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,
|
to: trailingScrollOffset,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final double targetEndScrollOffsetForPaint = constraints.scrollOffset + constraints.remainingPaintExtent;
|
||||||
|
final int targetLastIndexForPaint = targetEndScrollOffsetForPaint.isFinite ?
|
||||||
|
getMaxChildIndexForScrollOffset(targetEndScrollOffsetForPaint, itemExtent) : null;
|
||||||
geometry = new SliverGeometry(
|
geometry = new SliverGeometry(
|
||||||
scrollExtent: estimatedMaxScrollOffset,
|
scrollExtent: estimatedMaxScrollOffset,
|
||||||
paintExtent: paintExtent,
|
paintExtent: paintExtent,
|
||||||
cacheExtent: cacheExtent,
|
cacheExtent: cacheExtent,
|
||||||
maxPaintExtent: estimatedMaxScrollOffset,
|
maxPaintExtent: estimatedMaxScrollOffset,
|
||||||
// Conservative to avoid flickering away the clip during scroll.
|
// Conservative to avoid flickering away the clip during scroll.
|
||||||
hasVisualOverflow: (targetLastIndex != null && lastIndex >= targetLastIndex)
|
hasVisualOverflow: (targetLastIndexForPaint != null && lastIndex >= targetLastIndexForPaint)
|
||||||
|| constraints.scrollOffset > 0.0,
|
|| constraints.scrollOffset > 0.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -274,13 +274,14 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor {
|
|||||||
from: childScrollOffset(firstChild),
|
from: childScrollOffset(firstChild),
|
||||||
to: endScrollOffset,
|
to: endScrollOffset,
|
||||||
);
|
);
|
||||||
|
final double targetEndScrollOffsetForPaint = constraints.scrollOffset + constraints.remainingPaintExtent;
|
||||||
geometry = new SliverGeometry(
|
geometry = new SliverGeometry(
|
||||||
scrollExtent: estimatedMaxScrollOffset,
|
scrollExtent: estimatedMaxScrollOffset,
|
||||||
paintExtent: paintExtent,
|
paintExtent: paintExtent,
|
||||||
cacheExtent: cacheExtent,
|
cacheExtent: cacheExtent,
|
||||||
maxPaintExtent: estimatedMaxScrollOffset,
|
maxPaintExtent: estimatedMaxScrollOffset,
|
||||||
// Conservative to avoid flickering away the clip during scroll.
|
// 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
|
// 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_test/flutter_test.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import '../rendering/mock_canvas.dart';
|
||||||
|
|
||||||
class TestSliverChildListDelegate extends SliverChildListDelegate {
|
class TestSliverChildListDelegate extends SliverChildListDelegate {
|
||||||
TestSliverChildListDelegate(List<Widget> children) : super(children);
|
TestSliverChildListDelegate(List<Widget> children) : super(children);
|
||||||
|
|
||||||
@ -293,4 +295,114 @@ void main() {
|
|||||||
// Leave left/right padding as is for children.
|
// Leave left/right padding as is for children.
|
||||||
expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
|
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