mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This auto-formats all *.dart files in the repository outside of the `engine` subdirectory and enforces that these files stay formatted with a presubmit check. **Reviewers:** Please carefully review all the commits except for the one titled "formatted". The "formatted" commit was auto-generated by running `dev/tools/format.sh -a -f`. The other commits were hand-crafted to prepare the repo for the formatting change. I recommend reviewing the commits one-by-one via the "Commits" tab and avoiding Github's "Files changed" tab as it will likely slow down your browser because of the size of this PR. --------- Co-authored-by: Kate Lovett <katelovett@google.com> Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
1813 lines
60 KiB
Dart
1813 lines
60 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'rendering_tester.dart';
|
|
|
|
void main() {
|
|
TestRenderingFlutterBinding.ensureInitialized();
|
|
|
|
test(
|
|
'RenderViewport calculates correct constraints, RenderSliverToBoxAdapter calculates correct geometry',
|
|
() {
|
|
final List<RenderSliver> children = List<RenderSliver>.generate(30, (int index) {
|
|
return RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, 100.0)));
|
|
});
|
|
|
|
// Viewport is 800x600, can show 6 children at a time.
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: 250.0,
|
|
children: children,
|
|
);
|
|
layout(root);
|
|
|
|
RenderSliver firstVisible = children[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisible,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisible,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
RenderSliver lastVisible = children[5];
|
|
expectSliverConstraints(
|
|
sliver: lastVisible,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 100.0,
|
|
remainingCacheExtent: 350.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastVisible,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
RenderSliver firstInCache = children[6];
|
|
expectSliverConstraints(
|
|
sliver: firstInCache,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstInCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
RenderSliver lastInCache = children[8];
|
|
expectSliverConstraints(
|
|
sliver: lastInCache,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 50.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastInCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 50.0,
|
|
visible: false,
|
|
);
|
|
|
|
RenderSliver outsideCache = children[9];
|
|
expectSliverConstraints(
|
|
sliver: outsideCache,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 0.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: outsideCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 0.0,
|
|
visible: false,
|
|
);
|
|
|
|
// scroll down half a sliver
|
|
root.offset = ViewportOffset.fixed(50.0);
|
|
pumpFrame();
|
|
|
|
firstVisible = children[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisible,
|
|
cacheOrigin: -50.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 50.0 + 600.0 + 250.0,
|
|
scrollOffset: 50.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisible,
|
|
paintExtent: 50.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
lastVisible = children[6];
|
|
expectSliverConstraints(
|
|
sliver: lastVisible,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 50.0,
|
|
remainingCacheExtent: 300.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastVisible,
|
|
paintExtent: 50.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
firstInCache = children[7];
|
|
expectSliverConstraints(
|
|
sliver: firstInCache,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 200.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstInCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
lastInCache = children[8];
|
|
expectSliverConstraints(
|
|
sliver: lastInCache,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 100.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastInCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
outsideCache = children[9];
|
|
expectSliverConstraints(
|
|
sliver: outsideCache,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 0.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: outsideCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 0.0,
|
|
visible: false,
|
|
);
|
|
|
|
// scroll down 1.5 slivers
|
|
root.offset = ViewportOffset.fixed(150.0);
|
|
pumpFrame();
|
|
|
|
RenderSliver firstInPreCache = children[0];
|
|
expectSliverConstraints(
|
|
sliver: firstInPreCache,
|
|
cacheOrigin: -150.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 150.0 + 600.0 + 250.0,
|
|
scrollOffset: 150.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstInPreCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
firstVisible = children[1];
|
|
expectSliverConstraints(
|
|
sliver: firstVisible,
|
|
cacheOrigin: -50.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 50.0 + 600.0 + 250.0,
|
|
scrollOffset: 50.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisible,
|
|
paintExtent: 50.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
// scroll down 10 slivers
|
|
root.offset = ViewportOffset.fixed(1000.0);
|
|
pumpFrame();
|
|
|
|
final RenderSliver first = children[0];
|
|
expectSliverConstraints(
|
|
sliver: first,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 1000.0,
|
|
);
|
|
expectSliverGeometry(sliver: first, paintExtent: 0.0, cacheExtent: 0.0, visible: false);
|
|
|
|
firstInPreCache = children[7];
|
|
expectSliverConstraints(
|
|
sliver: firstInPreCache,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 300.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstInPreCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 50.0,
|
|
visible: false,
|
|
);
|
|
|
|
final RenderSliver lastInPreCache = children[9];
|
|
expectSliverConstraints(
|
|
sliver: lastInPreCache,
|
|
cacheOrigin: -100.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 100.0 + 600.0 + 250.0,
|
|
scrollOffset: 100.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastInPreCache,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
firstVisible = children[10];
|
|
expectSliverConstraints(
|
|
sliver: firstVisible,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisible,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
},
|
|
);
|
|
|
|
test('RenderSliverFixedExtentList calculates correct geometry', () {
|
|
// Viewport is 800x600, can show 6 full children at a time
|
|
final List<RenderBox> children = List<RenderBox>.generate(30, (int index) {
|
|
return RenderSizedBox(const Size(400.0, 100.0));
|
|
});
|
|
final TestRenderSliverBoxChildManager childManager = TestRenderSliverBoxChildManager(
|
|
children: children,
|
|
);
|
|
RenderSliverFixedExtentList inner;
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: 250.0,
|
|
children: <RenderSliver>[inner = childManager.createRenderSliverFixedExtentList()],
|
|
);
|
|
layout(root);
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 850.0, visible: true);
|
|
expect(children.sublist(0, 9).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(9, 30).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll half an item down
|
|
root.offset = ViewportOffset.fixed(50.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -50.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 50.0 + 600.0 + 250.0,
|
|
scrollOffset: 50.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 900.0, visible: true);
|
|
expect(children.sublist(0, 9).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(9, 30).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll to the middle
|
|
root.offset = ViewportOffset.fixed(1500.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 1500.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 1100.0, visible: true);
|
|
|
|
expect(children.sublist(0, 12).any((RenderBox r) => r.attached), false);
|
|
expect(children.sublist(12, 24).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(24, 30).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll to the end
|
|
root.offset = ViewportOffset.fixed(2400.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 2400.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 850.0, visible: true);
|
|
expect(children.sublist(0, 21).any((RenderBox r) => r.attached), false);
|
|
expect(children.sublist(21, 30).every((RenderBox r) => r.attached), true);
|
|
});
|
|
|
|
test('RenderSliverList calculates correct geometry', () {
|
|
// Viewport is 800x600, can show 6 full children at a time
|
|
final List<RenderBox> children = List<RenderBox>.generate(30, (int index) {
|
|
return RenderSizedBox(const Size(400.0, 100.0));
|
|
});
|
|
final TestRenderSliverBoxChildManager childManager = TestRenderSliverBoxChildManager(
|
|
children: children,
|
|
);
|
|
RenderSliverList inner;
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: 250.0,
|
|
children: <RenderSliver>[inner = childManager.createRenderSliverList()],
|
|
);
|
|
layout(root);
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 850.0, visible: true);
|
|
expect(children.sublist(0, 9).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(9, 30).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll half an item down
|
|
root.offset = ViewportOffset.fixed(50.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -50.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 50.0 + 600.0 + 250.0,
|
|
scrollOffset: 50.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 900.0, visible: true);
|
|
expect(children.sublist(0, 9).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(9, 30).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll to the middle
|
|
root.offset = ViewportOffset.fixed(1500.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 1500.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 1100.0, visible: true);
|
|
|
|
expect(children.sublist(0, 12).any((RenderBox r) => r.attached), false);
|
|
expect(children.sublist(12, 24).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(24, 30).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll to the end
|
|
root.offset = ViewportOffset.fixed(2400.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 2400.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 850.0, visible: true);
|
|
expect(children.sublist(0, 21).any((RenderBox r) => r.attached), false);
|
|
expect(children.sublist(21, 30).every((RenderBox r) => r.attached), true);
|
|
});
|
|
|
|
test('RenderSliverGrid calculates correct geometry', () {
|
|
// Viewport is 800x600, each grid element is 400x100, giving us space for 12 visible children
|
|
final List<RenderBox> children = List<RenderBox>.generate(60, (int index) {
|
|
return RenderSizedBox(const Size(400.0, 100.0));
|
|
});
|
|
final TestRenderSliverBoxChildManager childManager = TestRenderSliverBoxChildManager(
|
|
children: children,
|
|
);
|
|
RenderSliverGrid inner;
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: 250.0,
|
|
children: <RenderSliver>[inner = childManager.createRenderSliverGrid()],
|
|
);
|
|
layout(root);
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 850.0, visible: true);
|
|
expect(children.sublist(0, 18).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(18, 60).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll half an item down
|
|
root.offset = ViewportOffset.fixed(50.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -50.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 50.0 + 600.0 + 250.0,
|
|
scrollOffset: 50.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 900.0, visible: true);
|
|
expect(children.sublist(0, 18).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(18, 60).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll to the middle
|
|
root.offset = ViewportOffset.fixed(1500.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 1500.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 1100.0, visible: true);
|
|
|
|
expect(children.sublist(0, 24).any((RenderBox r) => r.attached), false);
|
|
expect(children.sublist(24, 48).every((RenderBox r) => r.attached), true);
|
|
expect(children.sublist(48, 60).any((RenderBox r) => r.attached), false);
|
|
|
|
// scroll to the end
|
|
root.offset = ViewportOffset.fixed(2400.0);
|
|
pumpFrame();
|
|
|
|
expectSliverConstraints(
|
|
sliver: inner,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 2400.0,
|
|
);
|
|
expectSliverGeometry(sliver: inner, paintExtent: 600.0, cacheExtent: 850.0, visible: true);
|
|
expect(children.sublist(0, 42).any((RenderBox r) => r.attached), false);
|
|
expect(children.sublist(42, 60).every((RenderBox r) => r.attached), true);
|
|
});
|
|
|
|
test('RenderSliverPadding calculates correct geometry', () {
|
|
// Viewport is 800x600, each item is 100px high with 50px before and after = 200px
|
|
|
|
final List<RenderSliverToBoxAdapter> adapters = <RenderSliverToBoxAdapter>[];
|
|
final List<RenderSliverPadding> paddings = List<RenderSliverPadding>.generate(30, (int index) {
|
|
RenderSliverToBoxAdapter adapter;
|
|
final RenderSliverPadding padding = RenderSliverPadding(
|
|
padding: const EdgeInsets.symmetric(vertical: 50.0),
|
|
child: adapter = RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, 100.0))),
|
|
);
|
|
adapters.add(adapter);
|
|
return padding;
|
|
});
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: 250.0,
|
|
children: paddings,
|
|
);
|
|
layout(root);
|
|
|
|
RenderSliverPadding firstVisiblePadding = paddings[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisiblePadding,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisiblePadding,
|
|
paintExtent: 200.0,
|
|
cacheExtent: 200.0,
|
|
visible: true,
|
|
);
|
|
RenderSliverToBoxAdapter firstVisiblePadded = adapters[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisiblePadded,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 550.0,
|
|
remainingCacheExtent: 600.0 + 250.0 - 50.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisiblePadded,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
RenderSliverPadding lastVisiblePadding = paddings[2];
|
|
expectSliverConstraints(
|
|
sliver: lastVisiblePadding,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 200.0,
|
|
remainingCacheExtent: 200.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastVisiblePadding,
|
|
paintExtent: 200.0,
|
|
cacheExtent: 200.0,
|
|
visible: true,
|
|
);
|
|
RenderSliverToBoxAdapter lastVisiblePadded = adapters[2];
|
|
expectSliverConstraints(
|
|
sliver: lastVisiblePadded,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 150.0,
|
|
remainingCacheExtent: 200.0 + 250.0 - 50.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastVisiblePadded,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
final RenderSliverPadding firstCachePadding = paddings[3];
|
|
expectSliverConstraints(
|
|
sliver: firstCachePadding,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstCachePadding,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 200.0,
|
|
visible: false,
|
|
);
|
|
final RenderSliverToBoxAdapter firstCachePadded = adapters[3];
|
|
expectSliverConstraints(
|
|
sliver: firstCachePadded,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 250.0 - 50.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstCachePadded,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
final RenderSliverPadding lastCachePadding = paddings[4];
|
|
expectSliverConstraints(
|
|
sliver: lastCachePadding,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 50.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastCachePadding,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 50.0,
|
|
visible: false,
|
|
);
|
|
final RenderSliverToBoxAdapter lastCachePadded = adapters[4];
|
|
expectSliverConstraints(
|
|
sliver: lastCachePadded,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 0.0,
|
|
remainingCacheExtent: 0.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastCachePadded,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 0.0,
|
|
visible: false,
|
|
);
|
|
|
|
// scroll first padding off screen
|
|
root.offset = ViewportOffset.fixed(50.0);
|
|
pumpFrame();
|
|
|
|
firstVisiblePadding = paddings[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisiblePadding,
|
|
cacheOrigin: -50.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 50.0 + 600.0 + 250.0,
|
|
scrollOffset: 50.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisiblePadding,
|
|
paintExtent: 150.0,
|
|
cacheExtent: 200.0,
|
|
visible: true,
|
|
);
|
|
firstVisiblePadded = adapters[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisiblePadded,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 600.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisiblePadded,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
|
|
// scroll to the end
|
|
root.offset = ViewportOffset.fixed(5400.0);
|
|
pumpFrame();
|
|
|
|
final RenderSliverPadding firstPadding = paddings[0];
|
|
expectSliverConstraints(
|
|
sliver: firstPadding,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 5400.0,
|
|
);
|
|
expectSliverGeometry(sliver: firstPadding, paintExtent: 0.0, cacheExtent: 0.0, visible: false);
|
|
final RenderSliverToBoxAdapter firstPadded = adapters[0];
|
|
expectSliverConstraints(
|
|
sliver: firstPadded,
|
|
cacheOrigin: -200.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 5350.0,
|
|
);
|
|
expectSliverGeometry(sliver: firstPadded, paintExtent: 0.0, cacheExtent: 0.0, visible: false);
|
|
|
|
final RenderSliverPadding firstPreCachePadding = paddings[25];
|
|
expectSliverConstraints(
|
|
sliver: firstPreCachePadding,
|
|
cacheOrigin: -250.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 400.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstPreCachePadding,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 50.0,
|
|
visible: false,
|
|
);
|
|
final RenderSliverToBoxAdapter firstPreCachePadded = adapters[25];
|
|
expectSliverConstraints(
|
|
sliver: firstPreCachePadded,
|
|
cacheOrigin: -200.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 250.0 + 600.0 + 250.0,
|
|
scrollOffset: 350.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstPreCachePadded,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 0.0,
|
|
visible: false,
|
|
);
|
|
|
|
final RenderSliverPadding lastPreCachePadding = paddings[26];
|
|
expectSliverConstraints(
|
|
sliver: lastPreCachePadding,
|
|
cacheOrigin: -200.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 200.0 + 600.0 + 250.0,
|
|
scrollOffset: 200.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastPreCachePadding,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 200.0,
|
|
visible: false,
|
|
);
|
|
final RenderSliverToBoxAdapter lastPreCachePadded = adapters[26];
|
|
expectSliverConstraints(
|
|
sliver: lastPreCachePadded,
|
|
cacheOrigin: -150.0,
|
|
remainingPaintExtent: 600.0,
|
|
remainingCacheExtent: 150.0 + 600.0 + 250.0,
|
|
scrollOffset: 150.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastPreCachePadded,
|
|
paintExtent: 0.0,
|
|
cacheExtent: 100.0,
|
|
visible: false,
|
|
);
|
|
|
|
lastVisiblePadding = paddings[29];
|
|
expectSliverConstraints(
|
|
sliver: lastVisiblePadding,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 200.0,
|
|
remainingCacheExtent: 200.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastVisiblePadding,
|
|
paintExtent: 200.0,
|
|
cacheExtent: 200.0,
|
|
visible: true,
|
|
);
|
|
lastVisiblePadded = adapters[29];
|
|
expectSliverConstraints(
|
|
sliver: lastVisiblePadded,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: 150.0,
|
|
remainingCacheExtent: 150.0 + 250.0,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: lastVisiblePadded,
|
|
paintExtent: 100.0,
|
|
cacheExtent: 100.0,
|
|
visible: true,
|
|
);
|
|
});
|
|
|
|
group('RenderSliverFillRemaining calculates correct geometry', () {
|
|
test('when initially in view', () {
|
|
// Viewport is 800x600
|
|
const double viewportHeight = 600;
|
|
const double viewportWidth = 800;
|
|
const double cacheExtent = 250.0;
|
|
const double beginningViewportCacheExtent = viewportHeight + cacheExtent;
|
|
const double firstSliverHeight = 400;
|
|
const double sliverFillRemainingChildHeight = 100.0;
|
|
|
|
final List<RenderSliver> slivers = <RenderSliver>[
|
|
RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, firstSliverHeight))),
|
|
RenderSliverFillRemaining(
|
|
child: RenderSizedBox(const Size(100.0, sliverFillRemainingChildHeight)),
|
|
),
|
|
];
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: cacheExtent,
|
|
children: slivers,
|
|
);
|
|
layout(root);
|
|
|
|
final RenderSliver firstVisibleSliver = slivers[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisibleSliver,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: viewportHeight,
|
|
remainingCacheExtent: beginningViewportCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisibleSliver,
|
|
paintExtent: firstSliverHeight,
|
|
cacheExtent: firstSliverHeight,
|
|
visible: true,
|
|
);
|
|
|
|
// With RenderSliverFillRemaining:
|
|
// * The child has a minExtent and maxExtent of the remaining space of the
|
|
// viewportMainAxisExtent or the height of the child - whichever is larger.
|
|
// * The sliver has a paintExtent of the child's minExtent/maxExtent or the
|
|
// remainingPaintExtent - whichever is smaller.
|
|
// * The sliver has a cacheExtent of the child's minExtent/maxExtent or the
|
|
// remainingCacheExtent - whichever is smaller.
|
|
final RenderSliverSingleBoxAdapter sliverFillRemaining =
|
|
slivers[1] as RenderSliverSingleBoxAdapter;
|
|
const double extentOfChild = viewportHeight - firstSliverHeight;
|
|
double remainingPaintExtent = viewportHeight - firstSliverHeight;
|
|
double remainingCacheExtent = beginningViewportCacheExtent - firstSliverHeight;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: extentOfChild,
|
|
cacheExtent: extentOfChild,
|
|
visible: true,
|
|
);
|
|
|
|
// Overscroll
|
|
const double scrollOffset = 50;
|
|
root.offset = ViewportOffset.fixed(scrollOffset);
|
|
pumpFrame();
|
|
remainingPaintExtent = viewportHeight - firstSliverHeight + scrollOffset;
|
|
remainingCacheExtent = beginningViewportCacheExtent - firstSliverHeight + scrollOffset;
|
|
|
|
// With RenderSliverFillRemaining, when you overscroll, the extent of the
|
|
// child does not change and therefore neither does paintExtent or cacheExtent.
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: extentOfChild,
|
|
cacheExtent: extentOfChild,
|
|
visible: true,
|
|
);
|
|
});
|
|
|
|
test('when scrolled into view', () {
|
|
// Viewport is 800x600
|
|
const double viewportHeight = 600;
|
|
const double viewportWidth = 800;
|
|
const double cacheExtent = 250.0;
|
|
const double beginningViewportCacheExtent = viewportHeight + cacheExtent;
|
|
const double firstSliverHeight = beginningViewportCacheExtent;
|
|
const double sliverFillRemainingChildHeight = 100.0;
|
|
|
|
final List<RenderSliver> slivers = <RenderSliver>[
|
|
RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, firstSliverHeight))),
|
|
RenderSliverFillRemaining(
|
|
child: RenderSizedBox(const Size(100.0, sliverFillRemainingChildHeight)),
|
|
),
|
|
];
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: cacheExtent,
|
|
children: slivers,
|
|
);
|
|
layout(root);
|
|
|
|
final RenderSliver firstVisibleSliver = slivers[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisibleSliver,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: viewportHeight,
|
|
remainingCacheExtent: beginningViewportCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisibleSliver,
|
|
paintExtent: viewportHeight,
|
|
cacheExtent: firstSliverHeight,
|
|
visible: true,
|
|
);
|
|
|
|
// With RenderSliverFillRemaining:
|
|
// * The child has a minExtent and maxExtent of the remaining space of the
|
|
// viewportMainAxisExtent or the height of the child - whichever is larger.
|
|
// * The sliver has a paintExtent of the child's minExtent/maxExtent or the
|
|
// remainingPaintExtent - whichever is smaller.
|
|
// * The sliver has a cacheExtent of the child's minExtent/maxExtent or the
|
|
// remainingCacheExtent - whichever is smaller.
|
|
final RenderSliverSingleBoxAdapter sliverFillRemaining =
|
|
slivers[1] as RenderSliverSingleBoxAdapter;
|
|
const double extentOfChild = sliverFillRemainingChildHeight;
|
|
double remainingPaintExtent = 0;
|
|
double remainingCacheExtent = 0;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: remainingPaintExtent,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: false,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemaining is not within viewport, but is
|
|
// within remainingCacheExtent.
|
|
root.offset = ViewportOffset.fixed(cacheExtent);
|
|
pumpFrame();
|
|
remainingPaintExtent = 0;
|
|
remainingCacheExtent = cacheExtent;
|
|
|
|
// When within the remainingCacheExtent, the sliver will have a cacheExtent
|
|
// of the child's extent.
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: remainingPaintExtent,
|
|
cacheExtent: extentOfChild,
|
|
visible: false,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemaining is partially within viewport.
|
|
root.offset = ViewportOffset.fixed(cacheExtent + 50);
|
|
pumpFrame();
|
|
remainingPaintExtent = 50;
|
|
remainingCacheExtent = cacheExtent + 50;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: remainingPaintExtent,
|
|
cacheExtent: extentOfChild,
|
|
visible: true,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemaining is completely within viewport.
|
|
root.offset = ViewportOffset.fixed(cacheExtent + sliverFillRemainingChildHeight);
|
|
pumpFrame();
|
|
remainingPaintExtent = sliverFillRemainingChildHeight;
|
|
remainingCacheExtent = cacheExtent + sliverFillRemainingChildHeight;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: extentOfChild,
|
|
cacheExtent: extentOfChild,
|
|
visible: true,
|
|
);
|
|
|
|
// Overscroll
|
|
root.offset = ViewportOffset.fixed(cacheExtent + sliverFillRemainingChildHeight + 50);
|
|
pumpFrame();
|
|
remainingPaintExtent = sliverFillRemainingChildHeight + 50;
|
|
remainingCacheExtent = cacheExtent + sliverFillRemainingChildHeight + 50;
|
|
|
|
// With RenderSliverFillRemaining, when you overscroll, the extent of the
|
|
// child does not change and therefore neither does paintExtent or cacheExtent.
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: extentOfChild,
|
|
minHeight: extentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: extentOfChild,
|
|
cacheExtent: extentOfChild,
|
|
visible: true,
|
|
);
|
|
});
|
|
});
|
|
|
|
group('RenderSliverFillRemainingAndOverscroll calculates correct geometry', () {
|
|
test('when initially in view', () {
|
|
// Viewport is 800x600
|
|
const double viewportHeight = 600;
|
|
const double viewportWidth = 800;
|
|
const double cacheExtent = 250.0;
|
|
const double beginningViewportCacheExtent = viewportHeight + cacheExtent;
|
|
const double firstSliverHeight = 400;
|
|
const double sliverFillRemainingChildHeight = 100.0;
|
|
|
|
final List<RenderSliver> slivers = <RenderSliver>[
|
|
RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, firstSliverHeight))),
|
|
RenderSliverFillRemainingAndOverscroll(
|
|
child: RenderSizedBox(const Size(100.0, sliverFillRemainingChildHeight)),
|
|
),
|
|
];
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: cacheExtent,
|
|
children: slivers,
|
|
);
|
|
layout(root);
|
|
|
|
final RenderSliver firstVisibleSliver = slivers[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisibleSliver,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: viewportHeight,
|
|
remainingCacheExtent: beginningViewportCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisibleSliver,
|
|
paintExtent: firstSliverHeight,
|
|
cacheExtent: firstSliverHeight,
|
|
visible: true,
|
|
);
|
|
|
|
// With RenderSliverFillRemainingAndOverscroll:
|
|
// * The child has a minExtent of the remaining space of the viewportMainAxisExtent
|
|
// or the height of the child - whichever is larger.
|
|
// * The child has a maxExtent of the remaining space of the viewportMainAxisExtent,
|
|
// the height of the child, or the remainingPaintExtent - whichever is larger.
|
|
// * The sliver has a paintExtent of the child's maxExtent or the
|
|
// remainingPaintExtent - whichever is smaller.
|
|
// * The sliver has a cacheExtent of the child's minExtent or the
|
|
// remainingCacheExtent - whichever is smaller.
|
|
final RenderSliverSingleBoxAdapter sliverFillRemaining =
|
|
slivers[1] as RenderSliverSingleBoxAdapter;
|
|
const double minExtentOfChild = viewportHeight - firstSliverHeight;
|
|
double maxExtentOfChild = viewportHeight - firstSliverHeight;
|
|
double remainingPaintExtent = viewportHeight - firstSliverHeight;
|
|
double remainingCacheExtent = beginningViewportCacheExtent - firstSliverHeight;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: maxExtentOfChild,
|
|
cacheExtent: minExtentOfChild,
|
|
visible: true,
|
|
);
|
|
|
|
// Overscroll
|
|
const double scrollOffset = 50;
|
|
root.offset = ViewportOffset.fixed(scrollOffset);
|
|
pumpFrame();
|
|
remainingPaintExtent = viewportHeight - firstSliverHeight + scrollOffset;
|
|
remainingCacheExtent = beginningViewportCacheExtent - firstSliverHeight + scrollOffset;
|
|
|
|
// When you overscroll, the child's maxExtent is the
|
|
// remainingPaintExtent, since it's the higher value.
|
|
maxExtentOfChild = remainingPaintExtent;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: maxExtentOfChild,
|
|
cacheExtent: minExtentOfChild,
|
|
visible: true,
|
|
);
|
|
});
|
|
|
|
test('when scrolled into view', () {
|
|
// Viewport is 800x600
|
|
const double viewportHeight = 600;
|
|
const double viewportWidth = 800;
|
|
const double cacheExtent = 250.0;
|
|
const double beginningViewportCacheExtent = viewportHeight + cacheExtent;
|
|
const double firstSliverHeight = beginningViewportCacheExtent;
|
|
const double sliverFillRemainingChildHeight = 100.0;
|
|
|
|
final List<RenderSliver> slivers = <RenderSliver>[
|
|
RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, firstSliverHeight))),
|
|
RenderSliverFillRemainingAndOverscroll(
|
|
child: RenderSizedBox(const Size(100.0, sliverFillRemainingChildHeight)),
|
|
),
|
|
];
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: cacheExtent,
|
|
children: slivers,
|
|
);
|
|
layout(root);
|
|
|
|
final RenderSliver firstVisibleSliver = slivers[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisibleSliver,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: viewportHeight,
|
|
remainingCacheExtent: beginningViewportCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisibleSliver,
|
|
paintExtent: viewportHeight,
|
|
cacheExtent: firstSliverHeight,
|
|
visible: true,
|
|
);
|
|
|
|
// With RenderSliverFillRemainingAndOverscroll:
|
|
// * The child has a minExtent of the remaining space of the viewportMainAxisExtent
|
|
// or the height of the child - whichever is larger.
|
|
// * The child has a maxExtent of the remaining space of the viewportMainAxisExtent,
|
|
// the height of the child, or the remainingPaintExtent - whichever is larger.
|
|
// * The sliver has a paintExtent of the child's maxExtent or the
|
|
// remainingPaintExtent - whichever is smaller.
|
|
// * The sliver has a cacheExtent of the child's minExtent or the
|
|
// remainingCacheExtent - whichever is smaller.
|
|
final RenderSliverSingleBoxAdapter sliverFillRemaining =
|
|
slivers[1] as RenderSliverSingleBoxAdapter;
|
|
const double minExtentOfChild = sliverFillRemainingChildHeight;
|
|
double maxExtentOfChild = sliverFillRemainingChildHeight;
|
|
double remainingPaintExtent = 0;
|
|
double remainingCacheExtent = 0;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: remainingPaintExtent,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: false,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemainingAndOverscroll is not within viewport,
|
|
// but is within remainingCacheExtent.
|
|
root.offset = ViewportOffset.fixed(cacheExtent);
|
|
pumpFrame();
|
|
remainingPaintExtent = 0;
|
|
remainingCacheExtent = cacheExtent;
|
|
|
|
// When within the remainingCacheExtent, the sliver will have a cacheExtent
|
|
// of the child's minExtent.
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: remainingPaintExtent,
|
|
cacheExtent: minExtentOfChild,
|
|
visible: false,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemainingAndOverscroll is partially within
|
|
// the viewport.
|
|
root.offset = ViewportOffset.fixed(cacheExtent + 50);
|
|
pumpFrame();
|
|
remainingPaintExtent = 50;
|
|
remainingCacheExtent = cacheExtent + 50;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: remainingPaintExtent,
|
|
cacheExtent: minExtentOfChild,
|
|
visible: true,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemainingAndOverscroll is completely within
|
|
// the viewport.
|
|
root.offset = ViewportOffset.fixed(cacheExtent + sliverFillRemainingChildHeight);
|
|
pumpFrame();
|
|
remainingPaintExtent = sliverFillRemainingChildHeight;
|
|
remainingCacheExtent = cacheExtent + sliverFillRemainingChildHeight;
|
|
|
|
// When completely in view, the slivers's paintExtent is the child's
|
|
// maxExtentOfChild, since it's the smaller value.
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: maxExtentOfChild,
|
|
cacheExtent: minExtentOfChild,
|
|
visible: true,
|
|
);
|
|
|
|
// Overscroll
|
|
root.offset = ViewportOffset.fixed(cacheExtent + sliverFillRemainingChildHeight + 50);
|
|
pumpFrame();
|
|
remainingPaintExtent = sliverFillRemainingChildHeight + 50;
|
|
remainingCacheExtent = cacheExtent + sliverFillRemainingChildHeight + 50;
|
|
|
|
// When you overscroll, the child's maxExtent is the remainingPaintExtent,
|
|
// since it's the higher value.
|
|
maxExtentOfChild = remainingPaintExtent;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: maxExtentOfChild,
|
|
cacheExtent: minExtentOfChild,
|
|
visible: true,
|
|
);
|
|
});
|
|
});
|
|
|
|
group('RenderSliverFillRemainingWithScrollable calculates correct geometry', () {
|
|
test('when initially in view', () {
|
|
// Viewport is 800x600
|
|
const double viewportHeight = 600;
|
|
const double viewportWidth = 800;
|
|
const double cacheExtent = 250.0;
|
|
const double beginningViewportCacheExtent = viewportHeight + cacheExtent;
|
|
const double firstSliverHeight = 400;
|
|
const double sliverFillRemainingChildHeight = 100.0;
|
|
|
|
final List<RenderSliver> slivers = <RenderSliver>[
|
|
RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, firstSliverHeight))),
|
|
RenderSliverFillRemainingWithScrollable(
|
|
child: RenderSizedBox(const Size(100.0, sliverFillRemainingChildHeight)),
|
|
),
|
|
];
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: cacheExtent,
|
|
children: slivers,
|
|
);
|
|
layout(root);
|
|
|
|
final RenderSliver firstVisibleSliver = slivers[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisibleSliver,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: viewportHeight,
|
|
remainingCacheExtent: beginningViewportCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisibleSliver,
|
|
paintExtent: firstSliverHeight,
|
|
cacheExtent: firstSliverHeight,
|
|
visible: true,
|
|
);
|
|
|
|
// With RenderSliverFillRemainingWithScrollable:
|
|
// * The child has a minExtent of the remainingPaintExtent.
|
|
// * If not within the viewport but within the cacheExtent, the child has
|
|
// a maxExtent of the sliver's cacheExtent. Otherwise, the child has a
|
|
// maxExtent of the remainingPaintExtent
|
|
// * The sliver has a paintExtent of the child's minExtent or the
|
|
// remainingPaintExtent - whichever is smaller.
|
|
// * The sliver has a cacheExtent of either the viewportMainAxisExtent or
|
|
// the remainingCacheExtent - whichever is smaller.
|
|
final RenderSliverSingleBoxAdapter sliverFillRemaining =
|
|
slivers[1] as RenderSliverSingleBoxAdapter;
|
|
double remainingPaintExtent = viewportHeight - firstSliverHeight;
|
|
double remainingCacheExtent = beginningViewportCacheExtent - firstSliverHeight;
|
|
double minExtentOfChild = remainingPaintExtent;
|
|
double maxExtentOfChild = remainingPaintExtent;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: true,
|
|
);
|
|
|
|
// Overscroll so first sliver is partially out of view.
|
|
root.offset = ViewportOffset.fixed(50);
|
|
pumpFrame();
|
|
remainingPaintExtent = viewportHeight - firstSliverHeight + 50;
|
|
remainingCacheExtent = beginningViewportCacheExtent - firstSliverHeight + 50;
|
|
minExtentOfChild = remainingPaintExtent;
|
|
maxExtentOfChild = remainingPaintExtent;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: true,
|
|
);
|
|
|
|
// Overscroll so only RenderSliverFillRemainingWithScrollable is visible.
|
|
root.offset = ViewportOffset.fixed(firstSliverHeight);
|
|
pumpFrame();
|
|
remainingPaintExtent = viewportHeight;
|
|
remainingCacheExtent = beginningViewportCacheExtent;
|
|
minExtentOfChild = remainingPaintExtent;
|
|
maxExtentOfChild = remainingPaintExtent;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: viewportHeight,
|
|
visible: true,
|
|
);
|
|
});
|
|
|
|
test('when scrolled into view', () {
|
|
// Viewport is 800x600
|
|
const double viewportHeight = 600;
|
|
const double viewportWidth = 800;
|
|
const double cacheExtent = 250.0;
|
|
const double beginningViewportCacheExtent = viewportHeight + cacheExtent;
|
|
const double firstSliverHeight = beginningViewportCacheExtent;
|
|
const double sliverFillRemainingChildHeight = 100.0;
|
|
|
|
final List<RenderSliver> slivers = <RenderSliver>[
|
|
RenderSliverToBoxAdapter(child: RenderSizedBox(const Size(400.0, firstSliverHeight))),
|
|
RenderSliverFillRemainingWithScrollable(
|
|
child: RenderSizedBox(const Size(100.0, sliverFillRemainingChildHeight)),
|
|
),
|
|
];
|
|
|
|
final RenderViewport root = RenderViewport(
|
|
crossAxisDirection: AxisDirection.right,
|
|
offset: ViewportOffset.zero(),
|
|
cacheExtent: cacheExtent,
|
|
children: slivers,
|
|
);
|
|
layout(root);
|
|
|
|
final RenderSliver firstVisibleSliver = slivers[0];
|
|
expectSliverConstraints(
|
|
sliver: firstVisibleSliver,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: viewportHeight,
|
|
remainingCacheExtent: beginningViewportCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: firstVisibleSliver,
|
|
paintExtent: viewportHeight,
|
|
cacheExtent: firstSliverHeight,
|
|
visible: true,
|
|
);
|
|
|
|
// With RenderSliverFillRemainingWithScrollable:
|
|
// * The child has a minExtent of the remainingPaintExtent.
|
|
// * If not within the viewport but within the cacheExtent, the child has
|
|
// a maxExtent of the sliver's cacheExtent. Otherwise, the child has a
|
|
// maxExtent of the remainingPaintExtent
|
|
// * The sliver has a paintExtent of the child's minExtent or the
|
|
// remainingPaintExtent - whichever is smaller.
|
|
// * The sliver has a cacheExtent of either the viewportMainAxisExtent or
|
|
// the remainingCacheExtent - whichever is smaller.
|
|
final RenderSliverSingleBoxAdapter sliverFillRemaining =
|
|
slivers[1] as RenderSliverSingleBoxAdapter;
|
|
double remainingPaintExtent = 0;
|
|
double remainingCacheExtent = 0;
|
|
double minExtentOfChild = remainingPaintExtent;
|
|
double maxExtentOfChild = remainingPaintExtent;
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: false,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemainingWithScrollable is not within
|
|
// viewport, but is within remainingCacheExtent.
|
|
root.offset = ViewportOffset.fixed(cacheExtent);
|
|
pumpFrame();
|
|
remainingPaintExtent = 0;
|
|
remainingCacheExtent = cacheExtent;
|
|
minExtentOfChild = remainingPaintExtent;
|
|
// When RenderSliverFillRemainingWithScrollable is completely outside the
|
|
// viewport, but is within the remainingCacheExtent, the child has a
|
|
// maxExtent of the slivers's cacheExtent.
|
|
maxExtentOfChild = remainingCacheExtent;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: false,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemainingWithScrollable is partially within
|
|
// viewport.
|
|
root.offset = ViewportOffset.fixed(cacheExtent + 50);
|
|
pumpFrame();
|
|
remainingPaintExtent = 50;
|
|
remainingCacheExtent = cacheExtent + 50;
|
|
minExtentOfChild = remainingPaintExtent;
|
|
maxExtentOfChild = remainingPaintExtent;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: remainingCacheExtent,
|
|
visible: true,
|
|
);
|
|
|
|
// Scroll so RenderSliverFillRemainingWithScrollable takes the entire
|
|
// viewport.
|
|
root.offset = ViewportOffset.fixed(firstSliverHeight);
|
|
pumpFrame();
|
|
remainingPaintExtent = viewportHeight;
|
|
remainingCacheExtent = beginningViewportCacheExtent;
|
|
minExtentOfChild = remainingPaintExtent;
|
|
maxExtentOfChild = remainingPaintExtent;
|
|
|
|
expectSliverConstraints(
|
|
sliver: sliverFillRemaining,
|
|
cacheOrigin: 0.0,
|
|
remainingPaintExtent: remainingPaintExtent,
|
|
remainingCacheExtent: remainingCacheExtent,
|
|
scrollOffset: 0.0,
|
|
);
|
|
expectSliverChildConstraints(
|
|
sliver: sliverFillRemaining,
|
|
maxHeight: maxExtentOfChild,
|
|
minHeight: minExtentOfChild,
|
|
maxWidth: viewportWidth,
|
|
minWidth: viewportWidth,
|
|
);
|
|
expectSliverGeometry(
|
|
sliver: sliverFillRemaining,
|
|
paintExtent: minExtentOfChild,
|
|
cacheExtent: viewportHeight,
|
|
visible: true,
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
void expectSliverConstraints({
|
|
required RenderSliver sliver,
|
|
required double cacheOrigin,
|
|
required double remainingPaintExtent,
|
|
required double remainingCacheExtent,
|
|
required double scrollOffset,
|
|
}) {
|
|
expect(sliver.constraints.cacheOrigin, cacheOrigin, reason: 'cacheOrigin');
|
|
expect(
|
|
sliver.constraints.remainingPaintExtent,
|
|
remainingPaintExtent,
|
|
reason: 'remainingPaintExtent',
|
|
);
|
|
expect(
|
|
sliver.constraints.remainingCacheExtent,
|
|
remainingCacheExtent,
|
|
reason: 'remainingCacheExtent',
|
|
);
|
|
expect(sliver.constraints.scrollOffset, scrollOffset, reason: 'scrollOffset');
|
|
}
|
|
|
|
void expectSliverGeometry({
|
|
required RenderSliver sliver,
|
|
required double paintExtent,
|
|
required double cacheExtent,
|
|
required bool visible,
|
|
}) {
|
|
expect(sliver.geometry!.paintExtent, paintExtent, reason: 'paintExtent');
|
|
expect(sliver.geometry!.cacheExtent, cacheExtent, reason: 'cacheExtent');
|
|
expect(sliver.geometry!.visible, visible, reason: 'visible');
|
|
}
|
|
|
|
void expectSliverChildConstraints({
|
|
required RenderSliverSingleBoxAdapter sliver,
|
|
required double maxWidth,
|
|
required double maxHeight,
|
|
required double minWidth,
|
|
required double minHeight,
|
|
}) {
|
|
expect(sliver.child!.constraints.maxWidth, maxWidth, reason: 'maxWidth');
|
|
expect(sliver.child!.constraints.maxHeight, maxHeight, reason: 'maxHeight');
|
|
expect(sliver.child!.constraints.minWidth, minWidth, reason: 'minWidth');
|
|
expect(sliver.child!.constraints.minHeight, minHeight, reason: 'minHeight');
|
|
}
|
|
|
|
class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager {
|
|
TestRenderSliverBoxChildManager({required this.children});
|
|
|
|
RenderSliverMultiBoxAdaptor? _renderObject;
|
|
List<RenderBox> children;
|
|
|
|
RenderSliverList createRenderSliverList() {
|
|
assert(_renderObject == null);
|
|
_renderObject = RenderSliverList(childManager: this);
|
|
return _renderObject! as RenderSliverList;
|
|
}
|
|
|
|
RenderSliverFixedExtentList createRenderSliverFixedExtentList() {
|
|
assert(_renderObject == null);
|
|
_renderObject = RenderSliverFixedExtentList(childManager: this, itemExtent: 100.0);
|
|
return _renderObject! as RenderSliverFixedExtentList;
|
|
}
|
|
|
|
RenderSliverGrid createRenderSliverGrid() {
|
|
assert(_renderObject == null);
|
|
_renderObject = RenderSliverGrid(
|
|
childManager: this,
|
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
crossAxisCount: 2,
|
|
childAspectRatio: 4.0,
|
|
),
|
|
);
|
|
return _renderObject! as RenderSliverGrid;
|
|
}
|
|
|
|
int? _currentlyUpdatingChildIndex;
|
|
|
|
@override
|
|
void createChild(int index, {required RenderBox? after}) {
|
|
if (index < 0 || index >= children.length) {
|
|
return;
|
|
}
|
|
try {
|
|
_currentlyUpdatingChildIndex = index;
|
|
_renderObject!.insert(children[index], after: after);
|
|
} finally {
|
|
_currentlyUpdatingChildIndex = null;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void removeChild(RenderBox child) {
|
|
_renderObject!.remove(child);
|
|
}
|
|
|
|
@override
|
|
double estimateMaxScrollOffset(
|
|
SliverConstraints constraints, {
|
|
int? firstIndex,
|
|
int? lastIndex,
|
|
double? leadingScrollOffset,
|
|
double? trailingScrollOffset,
|
|
}) {
|
|
assert(lastIndex! >= firstIndex!);
|
|
return children.length *
|
|
(trailingScrollOffset! - leadingScrollOffset!) /
|
|
(lastIndex! - firstIndex! + 1);
|
|
}
|
|
|
|
@override
|
|
int get childCount => children.length;
|
|
|
|
@override
|
|
void didAdoptChild(RenderBox child) {
|
|
assert(_currentlyUpdatingChildIndex != null);
|
|
final SliverMultiBoxAdaptorParentData childParentData =
|
|
child.parentData! as SliverMultiBoxAdaptorParentData;
|
|
childParentData.index = _currentlyUpdatingChildIndex;
|
|
}
|
|
|
|
@override
|
|
void setDidUnderflow(bool value) {}
|
|
}
|