adds properties to dismissible widget (#14162)
* adds crossAxisEndOffset and rollbackDuration properties to dismissible widget * re-added removed license comment * corrected license comments * Adds test for rollbackDuration and crossAxisEndOffset * added tests and comments * modified tests for dismissible widgets
This commit is contained in:
parent
c54fab0444
commit
47e52b827f
@ -12,7 +12,6 @@ import 'gesture_detector.dart';
|
||||
import 'ticker_provider.dart';
|
||||
import 'transitions.dart';
|
||||
|
||||
const Duration _kDismissDuration = const Duration(milliseconds: 200);
|
||||
const Curve _kResizeTimeCurve = const Interval(0.4, 1.0, curve: Curves.ease);
|
||||
const double _kMinFlingVelocity = 700.0;
|
||||
const double _kMinFlingVelocityDelta = 400.0;
|
||||
@ -83,6 +82,8 @@ class Dismissible extends StatefulWidget {
|
||||
this.direction: DismissDirection.horizontal,
|
||||
this.resizeDuration: const Duration(milliseconds: 300),
|
||||
this.dismissThresholds: const <DismissDirection, double>{},
|
||||
this.movementDuration: const Duration(milliseconds: 200),
|
||||
this.crossAxisEndOffset: 0.0,
|
||||
}) : assert(key != null),
|
||||
assert(secondaryBackground != null ? background != null : true),
|
||||
super(key: key);
|
||||
@ -134,6 +135,15 @@ class Dismissible extends StatefulWidget {
|
||||
/// [direction] property.
|
||||
final Map<DismissDirection, double> dismissThresholds;
|
||||
|
||||
/// Defines the duration for card to dismiss or to come back to original position if not dismissed.
|
||||
final Duration movementDuration;
|
||||
|
||||
/// Defines the end offset across the main axis after the card is dismissed.
|
||||
///
|
||||
/// If non-zero value is given then widget moves in cross direction depending on whether
|
||||
/// it is positive or negative.
|
||||
final double crossAxisEndOffset;
|
||||
|
||||
@override
|
||||
_DismissibleState createState() => new _DismissibleState();
|
||||
}
|
||||
@ -183,7 +193,7 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_moveController = new AnimationController(duration: _kDismissDuration, vsync: this)
|
||||
_moveController = new AnimationController(duration: widget.movementDuration, vsync: this)
|
||||
..addStatusListener(_handleDismissStatusChanged);
|
||||
_updateMoveAnimation();
|
||||
}
|
||||
@ -317,7 +327,9 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
|
||||
final double end = _dragExtent.sign;
|
||||
_moveAnimation = new Tween<Offset>(
|
||||
begin: Offset.zero,
|
||||
end: _directionIsXAxis ? new Offset(end, 0.0) : new Offset(0.0, end),
|
||||
end: _directionIsXAxis
|
||||
? new Offset(end, widget.crossAxisEndOffset)
|
||||
: new Offset(widget.crossAxisEndOffset, end),
|
||||
).animate(_moveController);
|
||||
}
|
||||
|
||||
@ -513,3 +525,4 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ DismissDirection dismissDirection = DismissDirection.horizontal;
|
||||
DismissDirection reportedDismissDirection;
|
||||
List<int> dismissedItems = <int>[];
|
||||
Widget background;
|
||||
const double crossAxisEndOffset = 0.5;
|
||||
|
||||
Widget buildTest({ double startToEndThreshold, TextDirection textDirection: TextDirection.ltr }) {
|
||||
return new Directionality(
|
||||
@ -37,6 +38,7 @@ Widget buildTest({ double startToEndThreshold, TextDirection textDirection: Text
|
||||
dismissThresholds: startToEndThreshold == null
|
||||
? <DismissDirection, double>{}
|
||||
: <DismissDirection, double>{DismissDirection.startToEnd: startToEndThreshold},
|
||||
crossAxisEndOffset: crossAxisEndOffset,
|
||||
child: new Container(
|
||||
width: itemExtent,
|
||||
height: itemExtent,
|
||||
@ -143,6 +145,53 @@ Future<Null> dismissItem(WidgetTester tester, int item, {
|
||||
await tester.pump(); // rebuild after the callback removes the entry
|
||||
}
|
||||
|
||||
Future<Null> checkFlingItemBeforeMovementEnd(WidgetTester tester, int item, {
|
||||
@required AxisDirection gestureDirection,
|
||||
DismissMethod mechanism: rollbackElement
|
||||
}) async {
|
||||
assert(gestureDirection != null);
|
||||
final Finder itemFinder = find.text(item.toString());
|
||||
expect(itemFinder, findsOneWidget);
|
||||
|
||||
await mechanism(tester, itemFinder, gestureDirection: gestureDirection);
|
||||
|
||||
await tester.pump(); // start the slide
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
}
|
||||
|
||||
Future<Null> checkFlingItemAfterMovement(WidgetTester tester, int item, {
|
||||
@required AxisDirection gestureDirection,
|
||||
DismissMethod mechanism: rollbackElement
|
||||
}) async {
|
||||
assert(gestureDirection != null);
|
||||
final Finder itemFinder = find.text(item.toString());
|
||||
expect(itemFinder, findsOneWidget);
|
||||
|
||||
await mechanism(tester, itemFinder, gestureDirection: gestureDirection);
|
||||
|
||||
await tester.pump(); // start the slide
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
}
|
||||
|
||||
Future<Null> rollbackElement(WidgetTester tester, Finder finder, { @required AxisDirection gestureDirection, double initialOffsetFactor: 0.0 }) async {
|
||||
Offset delta;
|
||||
switch (gestureDirection) {
|
||||
case AxisDirection.left:
|
||||
delta = const Offset(-30.0, 0.0);
|
||||
break;
|
||||
case AxisDirection.right:
|
||||
delta = const Offset(30.0, 0.0);
|
||||
break;
|
||||
case AxisDirection.up:
|
||||
delta = const Offset(0.0, -30.0);
|
||||
break;
|
||||
case AxisDirection.down:
|
||||
delta = const Offset(0.0, 30.0);
|
||||
break;
|
||||
}
|
||||
await tester.fling(finder, delta, 1000.0, initialOffset: delta * initialOffsetFactor);
|
||||
}
|
||||
|
||||
class Test1215DismissibleWidget extends StatelessWidget {
|
||||
const Test1215DismissibleWidget(this.text);
|
||||
|
||||
@ -558,4 +607,54 @@ void main() {
|
||||
final RenderBox backgroundBox = tester.firstRenderObject(find.text('background'));
|
||||
expect(backgroundBox.size.height, equals(100.0));
|
||||
});
|
||||
}
|
||||
|
||||
testWidgets('Checking fling item before movementDuration completes', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(buildTest());
|
||||
expect(dismissedItems, isEmpty);
|
||||
|
||||
await checkFlingItemBeforeMovementEnd(tester, 0, gestureDirection: AxisDirection.left, mechanism: flingElement);
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
|
||||
await checkFlingItemBeforeMovementEnd(tester, 1, gestureDirection: AxisDirection.right, mechanism: flingElement);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Checking fling item after movementDuration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(buildTest());
|
||||
expect(dismissedItems, isEmpty);
|
||||
|
||||
await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.left, mechanism: flingElement);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
await checkFlingItemAfterMovement(tester, 0, gestureDirection: AxisDirection.right, mechanism: flingElement);
|
||||
expect(find.text('0'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Horizontal fling less than threshold', (WidgetTester tester) async {
|
||||
scrollDirection = Axis.horizontal;
|
||||
await tester.pumpWidget(buildTest());
|
||||
expect(dismissedItems, isEmpty);
|
||||
|
||||
await checkFlingItemAfterMovement(tester, 0, gestureDirection: AxisDirection.left, mechanism: rollbackElement);
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(dismissedItems, isEmpty);
|
||||
|
||||
await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.right, mechanism: rollbackElement);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
expect(dismissedItems, isEmpty);
|
||||
});
|
||||
|
||||
testWidgets('Vertical fling less than threshold', (WidgetTester tester) async {
|
||||
scrollDirection = Axis.vertical;
|
||||
await tester.pumpWidget(buildTest());
|
||||
expect(dismissedItems, isEmpty);
|
||||
|
||||
await checkFlingItemAfterMovement(tester, 0, gestureDirection: AxisDirection.left, mechanism: rollbackElement);
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(dismissedItems, isEmpty);
|
||||
|
||||
await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.right, mechanism: rollbackElement);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
expect(dismissedItems, isEmpty);
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user