Fix clipping for SliverLists (#18410)
This commit is contained in:
parent
409007827b
commit
6ab3abfbc3
@ -248,13 +248,16 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
|
||||
to: trailingScrollOffset,
|
||||
);
|
||||
|
||||
final double targetEndScrollOffsetForPaint = constraints.scrollOffset + constraints.remainingPaintExtent;
|
||||
final int targetLastIndexForPaint = targetEndScrollOffsetForPaint.isFinite ?
|
||||
getMaxChildIndexForScrollOffset(targetEndScrollOffsetForPaint, itemExtent) : null;
|
||||
geometry = new SliverGeometry(
|
||||
scrollExtent: estimatedMaxScrollOffset,
|
||||
paintExtent: paintExtent,
|
||||
cacheExtent: cacheExtent,
|
||||
maxPaintExtent: estimatedMaxScrollOffset,
|
||||
// Conservative to avoid flickering away the clip during scroll.
|
||||
hasVisualOverflow: (targetLastIndex != null && lastIndex >= targetLastIndex)
|
||||
hasVisualOverflow: (targetLastIndexForPaint != null && lastIndex >= targetLastIndexForPaint)
|
||||
|| constraints.scrollOffset > 0.0,
|
||||
);
|
||||
|
||||
|
@ -274,13 +274,14 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor {
|
||||
from: childScrollOffset(firstChild),
|
||||
to: endScrollOffset,
|
||||
);
|
||||
final double targetEndScrollOffsetForPaint = constraints.scrollOffset + constraints.remainingPaintExtent;
|
||||
geometry = new SliverGeometry(
|
||||
scrollExtent: estimatedMaxScrollOffset,
|
||||
paintExtent: paintExtent,
|
||||
cacheExtent: cacheExtent,
|
||||
maxPaintExtent: estimatedMaxScrollOffset,
|
||||
// Conservative to avoid flickering away the clip during scroll.
|
||||
hasVisualOverflow: endScrollOffset > targetEndScrollOffset || constraints.scrollOffset > 0.0,
|
||||
hasVisualOverflow: endScrollOffset > targetEndScrollOffsetForPaint || constraints.scrollOffset > 0.0,
|
||||
);
|
||||
|
||||
// We may have started the layout while scrolled to the end, which would not
|
||||
|
@ -5,6 +5,8 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
|
||||
class TestSliverChildListDelegate extends SliverChildListDelegate {
|
||||
TestSliverChildListDelegate(List<Widget> children) : super(children);
|
||||
|
||||
@ -293,4 +295,114 @@ void main() {
|
||||
// Leave left/right padding as is for children.
|
||||
expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
|
||||
});
|
||||
|
||||
testWidgets('ListView clips if overflow is smaller than cacheExtent', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/17426.
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: new Center(
|
||||
child: new Container(
|
||||
height: 200.0,
|
||||
child: new ListView(
|
||||
cacheExtent: 500.0,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
height: 90.0,
|
||||
),
|
||||
new Container(
|
||||
height: 110.0,
|
||||
),
|
||||
new Container(
|
||||
height: 80.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(Viewport), paints..clipRect());
|
||||
});
|
||||
|
||||
testWidgets('ListView does not clips if no overflow', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
new Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: new Center(
|
||||
child: new Container(
|
||||
height: 200.0,
|
||||
child: new ListView(
|
||||
cacheExtent: 500.0,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
height: 100.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(Viewport), isNot(paints..clipRect()));
|
||||
});
|
||||
|
||||
testWidgets('ListView (fixed extent) clips if overflow is smaller than cacheExtent', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/17426.
|
||||
|
||||
await tester.pumpWidget(
|
||||
new Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: new Center(
|
||||
child: new Container(
|
||||
height: 200.0,
|
||||
child: new ListView(
|
||||
itemExtent: 100.0,
|
||||
cacheExtent: 500.0,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
height: 100.0,
|
||||
),
|
||||
new Container(
|
||||
height: 100.0,
|
||||
),
|
||||
new Container(
|
||||
height: 100.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(Viewport), paints..clipRect());
|
||||
});
|
||||
|
||||
testWidgets('ListView (fixed extent) does not clips if no overflow', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
new Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: new Center(
|
||||
child: new Container(
|
||||
height: 200.0,
|
||||
child: new ListView(
|
||||
itemExtent: 100.0,
|
||||
cacheExtent: 500.0,
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
height: 100.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(Viewport), isNot(paints..clipRect()));
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user