Unverified Commit a0862f1c authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[framework] use ImageFilter for stretch overscroll. (#133613)

Rather than changing the size of the child elements (relaying out text
and potentially changing glyph shape and position due to pixel
snapping), apply the stretch effect as a compositing effect - render the
children to a texture and stretch the texture. If we end up using an
image shader to apply an custom shader we'll need to do this anyway.

Fixes https://github.com/flutter/flutter/issues/129528

### Before


https://github.com/flutter/flutter/assets/8975114/16e9eb57-f864-4093-b4a4-461082b89b43

### After


https://github.com/flutter/flutter/assets/8975114/14cf0167-8922-4876-a325-e3bc154b084f
parent 5296f846
...@@ -786,10 +786,10 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi ...@@ -786,10 +786,10 @@ class _StretchingOverscrollIndicatorState extends State<StretchingOverscrollIndi
); );
final double viewportDimension = _lastOverscrollNotification?.metrics.viewportDimension ?? mainAxisSize; final double viewportDimension = _lastOverscrollNotification?.metrics.viewportDimension ?? mainAxisSize;
final Widget transform = Transform( final Widget transform = Transform(
alignment: alignment, alignment: alignment,
transform: Matrix4.diagonal3Values(x, y, 1.0), transform: Matrix4.diagonal3Values(x, y, 1.0),
filterQuality: stretch == 0 ? null : FilterQuality.low,
child: widget.child, child: widget.child,
); );
......
...@@ -1124,4 +1124,29 @@ void main() { ...@@ -1124,4 +1124,29 @@ void main() {
await gesture.up(); await gesture.up();
}); });
testWidgets('Stretch overscroll only uses image filter during stretch effect', (WidgetTester tester) async {
final GlobalKey box1Key = GlobalKey();
final GlobalKey box2Key = GlobalKey();
final GlobalKey box3Key = GlobalKey();
final ScrollController controller = ScrollController();
await tester.pumpWidget(
buildTest(
box1Key,
box2Key,
box3Key,
controller,
axis: Axis.horizontal,
)
);
expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CustomScrollView)));
// Overscroll
await gesture.moveBy(const Offset(200.0, 0.0));
await tester.pumpAndSettle();
expect(tester.layers, contains(isA<ImageFilterLayer>()));
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment