| // 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/foundation.dart'; |
| import 'package:flutter/rendering.dart'; |
| import '../flutter_test_alternative.dart'; |
| |
| import 'rendering_tester.dart'; |
| |
| void main() { |
| 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( |
| axisDirection: AxisDirection.down, |
| 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( |
| axisDirection: AxisDirection.down, |
| 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( |
| axisDirection: AxisDirection.down, |
| 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); |
| }, skip: isBrowser); |
| |
| 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( |
| axisDirection: AxisDirection.down, |
| 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( |
| axisDirection: AxisDirection.down, |
| 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, |
| ); |
| }); |
| } |
| |
| void expectSliverConstraints({ RenderSliver sliver, double cacheOrigin, double remainingPaintExtent, double remainingCacheExtent, 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({ RenderSliver sliver, double paintExtent, double cacheExtent, bool visible }) { |
| expect(sliver.geometry.paintExtent, paintExtent, reason: 'paintExtent'); |
| expect(sliver.geometry.cacheExtent, cacheExtent, reason: 'cacheExtent'); |
| expect(sliver.geometry.visible, visible, reason: 'visible'); |
| } |
| |
| class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager { |
| TestRenderSliverBoxChildManager({ |
| 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) { } |
| } |