Report progress on Dismissible update callback (#95504)

This commit is contained in:
Daniel Cachapa 2022-02-05 21:30:04 +01:00 committed by GitHub
parent 283e48bde4
commit 9d2a294496
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 1 deletions

View file

@ -233,7 +233,8 @@ class DismissUpdateDetails {
DismissUpdateDetails({
this.direction = DismissDirection.horizontal,
this.reached = false,
this.previousReached = false
this.previousReached = false,
this.progress = 0.0,
});
/// The direction that the dismissible is being dragged.
@ -247,6 +248,15 @@ class DismissUpdateDetails {
/// This can be used in conjunction with [DismissUpdateDetails.reached] to catch the moment
/// that the [Dismissible] is dragged across the threshold.
final bool previousReached;
/// The offset ratio of the dismissible in its parent container.
///
/// A value of 0.0 represents the normal position and 1.0 means the child is
/// completely outside its parent.
///
/// This can be used to synchronize other elements to what the dismissible is doing on screen,
/// e.g. using this value to set the opacity thereby fading dismissible as it's dragged offscreen.
final double progress;
}
class _DismissibleClipper extends CustomClipper<Rect> {
@ -438,6 +448,7 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
direction: _dismissDirection,
reached: _dismissThresholdReached,
previousReached: oldDismissThresholdReached,
progress: _moveController!.value,
);
widget.onUpdate!(details);
}

View file

@ -12,6 +12,7 @@ const DismissDirection defaultDismissDirection = DismissDirection.horizontal;
const double crossAxisEndOffset = 0.5;
bool reportedDismissUpdateReached = false;
bool reportedDismissUpdatePreviousReached = false;
double reportedDismissUpdateProgress = 0.0;
late DismissDirection reportedDismissUpdateReachedDirection;
DismissDirection reportedDismissDirection = DismissDirection.horizontal;
@ -53,6 +54,7 @@ Widget buildTest({
reportedDismissUpdateReachedDirection = details.direction;
reportedDismissUpdateReached = details.reached;
reportedDismissUpdatePreviousReached = details.previousReached;
reportedDismissUpdateProgress = details.progress;
},
background: background,
dismissThresholds: startToEndThreshold == null
@ -120,6 +122,25 @@ Future<void> dismissElement(WidgetTester tester, Finder finder, { required AxisD
await gesture.up();
}
Future<void> dragElement(WidgetTester tester, Finder finder, { required AxisDirection gestureDirection, required double amount }) async {
Offset delta;
switch (gestureDirection) {
case AxisDirection.left:
delta = Offset(-amount, 0.0);
break;
case AxisDirection.right:
delta = Offset(amount, 0.0);
break;
case AxisDirection.up:
delta = Offset(0.0, -amount);
break;
case AxisDirection.down:
delta = Offset(0.0, amount);
break;
}
await tester.drag(finder, delta);
}
Future<void> flingElement(WidgetTester tester, Finder finder, { required AxisDirection gestureDirection, double initialOffsetFactor = 0.0 }) async {
Offset delta;
switch (gestureDirection) {
@ -161,6 +182,20 @@ Future<void> dismissItem(
await tester.pumpAndSettle();
}
Future<void> dragItem(
WidgetTester tester,
int item, {
required AxisDirection gestureDirection,
required double amount,
}) async {
assert(gestureDirection != null);
final Finder itemFinder = find.text(item.toString());
expect(itemFinder, findsOneWidget);
await dragElement(tester, itemFinder, gestureDirection: gestureDirection, amount: amount);
await tester.pump();
}
Future<void> checkFlingItemBeforeMovementEnd(
WidgetTester tester,
int item, {
@ -1068,6 +1103,10 @@ void main() {
));
expect(dismissedItems, isEmpty);
// Unsuccessful dismiss, fractional progress reported
await dragItem(tester, 0, gestureDirection: AxisDirection.right, amount: 20);
expect(reportedDismissUpdateProgress, 0.2);
// Successful dismiss therefore threshold has been reached
await dismissItem(tester, 0, mechanism: flingElement, gestureDirection: AxisDirection.left);
expect(find.text('0'), findsNothing);
@ -1075,6 +1114,7 @@ void main() {
expect(reportedDismissUpdateReachedDirection, DismissDirection.endToStart);
expect(reportedDismissUpdateReached, true);
expect(reportedDismissUpdatePreviousReached, true);
expect(reportedDismissUpdateProgress, 1.0);
// Unsuccessful dismiss, threshold has not been reached
await checkFlingItemAfterMovement(tester, 1, gestureDirection: AxisDirection.right);
@ -1083,6 +1123,7 @@ void main() {
expect(reportedDismissUpdateReachedDirection, DismissDirection.startToEnd);
expect(reportedDismissUpdateReached, false);
expect(reportedDismissUpdatePreviousReached, false);
expect(reportedDismissUpdateProgress, 0.0);
// Another successful dismiss from another direction
await dismissItem(tester, 1, mechanism: flingElement, gestureDirection: AxisDirection.right);
@ -1091,6 +1132,7 @@ void main() {
expect(reportedDismissUpdateReachedDirection, DismissDirection.startToEnd);
expect(reportedDismissUpdateReached, true);
expect(reportedDismissUpdatePreviousReached, true);
expect(reportedDismissUpdateProgress, 1.0);
await tester.pumpWidget(buildTest(
scrollDirection: Axis.horizontal,
@ -1106,5 +1148,6 @@ void main() {
expect(reportedDismissUpdateReachedDirection, DismissDirection.startToEnd);
expect(reportedDismissUpdateReached, false);
expect(reportedDismissUpdatePreviousReached, false);
expect(reportedDismissUpdateProgress, 0.0);
});
}