diff --git a/lib/core/motion/querya_cross_fade_stack.dart b/lib/core/motion/querya_cross_fade_stack.dart index e3e01724..4527cf85 100644 --- a/lib/core/motion/querya_cross_fade_stack.dart +++ b/lib/core/motion/querya_cross_fade_stack.dart @@ -35,7 +35,10 @@ class QueryaCrossFadeStack extends StatelessWidget { opacity: index == i ? 1 : 0, duration: duration, curve: curve, - child: children[i], + child: TickerMode( + enabled: index == i, + child: RepaintBoundary(child: children[i]), + ), ), ), ), diff --git a/lib/core/motion/querya_switching_body.dart b/lib/core/motion/querya_switching_body.dart index 025f1490..77a54f91 100644 --- a/lib/core/motion/querya_switching_body.dart +++ b/lib/core/motion/querya_switching_body.dart @@ -74,11 +74,16 @@ class _SwitchingLayer extends StatelessWidget { @override Widget build(BuildContext context) { final curve = active ? inCurve : outCurve; + // Isolate paint; pause child tickers when inactive (opacity anim still runs). + final content = TickerMode( + enabled: active, + child: RepaintBoundary(child: child), + ); Widget layer = AnimatedOpacity( opacity: active ? 1 : 0, duration: duration, curve: curve, - child: child, + child: content, ); if (slide != Offset.zero) { diff --git a/test/core/motion/querya_switching_body_test.dart b/test/core/motion/querya_switching_body_test.dart index 07e19353..ecab84c6 100644 --- a/test/core/motion/querya_switching_body_test.dart +++ b/test/core/motion/querya_switching_body_test.dart @@ -251,6 +251,41 @@ void main() { ); }); + testWidgets('inactive layer disables TickerMode and uses RepaintBoundary', + (tester) async { + await tester.pumpWidget( + wrap( + const QueryaSwitchingBody( + index: 0, + children: [ + Text('active'), + Text('inactive'), + ], + ), + ), + ); + + final tickers = tester + .widgetList( + find.descendant( + of: find.byType(QueryaSwitchingBody), + matching: find.byType(TickerMode), + ), + ) + .toList(); + expect(tickers.length, 2); + expect(tickers.first.enabled, isTrue); + expect(tickers.last.enabled, isFalse); + + expect( + find.descendant( + of: find.byType(QueryaSwitchingBody), + matching: find.byType(RepaintBoundary), + ), + findsNWidgets(2), + ); + }); + testWidgets('ExcludeSemantics excludes inactive child', (tester) async { await tester.pumpWidget( wrap(