perf(ui): retain marquee content while scrolling

This commit is contained in:
zarzet committed 2026-10-05 19:20:05 +07:00
1 parent 604a485cf1
commit 5b28db1375
2 files changed
+58 -11

No files matched your search

+6 -5
View File
@@ -151,11 +151,12 @@ class _OverflowMarqueeState extends State<OverflowMarquee>
}
return false;
},
child: RepaintBoundary(
child: SingleChildScrollView(
controller: _scroll,
scrollDirection: Axis.horizontal,
physics: const NeverScrollableScrollPhysics(),
child: SingleChildScrollView(
controller: _scroll,
scrollDirection: Axis.horizontal,
physics: const NeverScrollableScrollPhysics(),
// The viewport repaints as it scrolls; retain the unchanged content.
child: RepaintBoundary(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
+52 -6
View File
@@ -27,6 +27,7 @@ void main() {
bool disableAnimations = false,
bool tickersEnabled = true,
TextDirection direction = TextDirection.ltr,
CustomPainter? foregroundPainter,
}) async {
await tester.pumpWidget(
MaterialApp(
@@ -43,12 +44,15 @@ void main() {
width: width,
child: OverflowMarquee(
resetKey: title,
child: ExplicitTrackTitle(
title: title,
explicit: explicit,
style: const TextStyle(fontSize: 16),
maxLines: 1,
overflow: TextOverflow.ellipsis,
child: CustomPaint(
foregroundPainter: foregroundPainter,
child: ExplicitTrackTitle(
title: title,
explicit: explicit,
style: const TextStyle(fontSize: 16),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
),
@@ -133,6 +137,38 @@ void main() {
expect(tester.binding.transientCallbackCount, 0);
});
testWidgets('scrolling retains text painting and track changes refresh it', (
tester,
) async {
final counter = _PaintCounter();
await pumpTitle(tester, foregroundPainter: counter);
await startScrolling(tester);
final scroll = controller(tester);
final start = scroll.offset;
final paints = counter.paints;
expect(start, greaterThan(0));
for (var frame = 0; frame < 20; frame++) {
await tester.pump(const Duration(milliseconds: 16));
}
expect(scroll.offset, greaterThan(start));
expect(counter.paints, paints);
await pumpTitle(
tester,
title: '$longTitle updated',
foregroundPainter: counter,
);
expect(scroll.offset, 0);
expect(counter.paints, greaterThan(paints));
expect(find.text('$longTitle updated'), findsNWidgets(2));
await startScrolling(tester);
final updatedPaints = counter.paints;
await tester.pump(const Duration(milliseconds: 100));
expect(scroll.offset, greaterThan(28));
expect(counter.paints, updatedPaints);
await tester.pumpWidget(const SizedBox.shrink());
});
testWidgets('reduced motion and hidden routes stop the marquee', (
tester,
) async {
@@ -359,3 +395,13 @@ void main() {
}
}
}
class _PaintCounter extends CustomPainter {
int paints = 0;
@override
void paint(Canvas canvas, Size size) => paints++;
@override
bool shouldRepaint(_PaintCounter oldDelegate) => false;
}