Use AnimatedSwitcher's _childNumber as Key in layoutBuilder's Stack (#121408)
Use AnimatedSwitcher's _childNumber as Key in layoutBuilder's Stack
This commit is contained in:
parent
61a03f7907
commit
0a1af28a8b
@ -216,7 +216,6 @@ class AnimatedSwitcher extends StatefulWidget {
|
|||||||
/// This is an [AnimatedSwitcherTransitionBuilder] function.
|
/// This is an [AnimatedSwitcherTransitionBuilder] function.
|
||||||
static Widget defaultTransitionBuilder(Widget child, Animation<double> animation) {
|
static Widget defaultTransitionBuilder(Widget child, Animation<double> animation) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
key: ValueKey<Key?>(child.key),
|
|
||||||
opacity: animation,
|
opacity: animation,
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
@ -338,7 +337,10 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
|
|||||||
}) {
|
}) {
|
||||||
final _ChildEntry entry = _ChildEntry(
|
final _ChildEntry entry = _ChildEntry(
|
||||||
widgetChild: child,
|
widgetChild: child,
|
||||||
transition: KeyedSubtree.wrap(builder(child, animation), _childNumber),
|
transition: KeyedSubtree(
|
||||||
|
key: ValueKey<int>(_childNumber),
|
||||||
|
child: builder(child, animation),
|
||||||
|
),
|
||||||
animation: animation,
|
animation: animation,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
);
|
);
|
||||||
@ -389,6 +391,6 @@ class _AnimatedSwitcherState extends State<AnimatedSwitcher> with TickerProvider
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_rebuildOutgoingWidgetsIfNeeded();
|
_rebuildOutgoingWidgetsIfNeeded();
|
||||||
return widget.layoutBuilder(_currentEntry?.transition, _outgoingWidgets!.where((Widget outgoing) => outgoing.key != _currentEntry?.transition.key).toSet().toList());
|
return widget.layoutBuilder(_currentEntry?.transition, _outgoingWidgets!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,23 +416,44 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('AnimatedSwitcher does not duplicate animations if the same child is entered twice.', (WidgetTester tester) async {
|
testWidgets('AnimatedSwitcher can handle multiple children with the same key.', (WidgetTester tester) async {
|
||||||
Future<void> pumpChild(Widget child) async {
|
final UniqueKey containerA = UniqueKey();
|
||||||
|
final UniqueKey containerB = UniqueKey();
|
||||||
|
|
||||||
|
// Pump an AnimatedSwitcher with a child container with the given key.
|
||||||
|
Future<void> pump(Key key) async {
|
||||||
return tester.pumpWidget(
|
return tester.pumpWidget(
|
||||||
Directionality(
|
AnimatedSwitcher(
|
||||||
textDirection: TextDirection.ltr,
|
duration: const Duration(milliseconds: 1000),
|
||||||
child: AnimatedSwitcher(
|
child: Container(key: key),
|
||||||
duration: const Duration(milliseconds: 1000),
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await pumpChild(const Text('1', key: Key('1')));
|
|
||||||
await pumpChild(const Text('2', key: Key('2')));
|
// Pump four widgets with the two keys A and B in alternating order.
|
||||||
await pumpChild(const Text('1', key: Key('1')));
|
await pump(containerA);
|
||||||
await tester.pump(const Duration(milliseconds: 1000));
|
await tester.pump(const Duration(milliseconds: 1000));
|
||||||
expect(find.text('1'), findsOneWidget);
|
await pump(containerB);
|
||||||
|
await tester.pump(const Duration(milliseconds: 500));
|
||||||
|
await pump(containerA);
|
||||||
|
await tester.pump(const Duration(milliseconds: 250));
|
||||||
|
await pump(containerB);
|
||||||
|
await tester.pump(const Duration(milliseconds: 125));
|
||||||
|
|
||||||
|
// All four widgets should still be animating in (the one pumped last) or
|
||||||
|
// out (the other ones), and thus have an associated FadeTransition each.
|
||||||
|
expect(find.byType(FadeTransition), findsNWidgets(4));
|
||||||
|
final Iterable<FadeTransition> transitions = tester.widgetList(
|
||||||
|
find.byType(FadeTransition),
|
||||||
|
);
|
||||||
|
|
||||||
|
// The exponentially decaying timing used in pumping the widgets should have
|
||||||
|
// lined up all of the FadeTransitions' values to be the same.
|
||||||
|
for (final FadeTransition transition in transitions) {
|
||||||
|
expect(transition.opacity.value, moreOrLessEquals(0.125, epsilon: 0.001));
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpAndSettle();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user