@@ -18,13 +18,41 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
18
18
/// The main-axis extent of each item.
19
19
double get itemExtent;
20
20
21
+ @protected
22
+ double indexToScrollOffset (double itemExtent, int index) => itemExtent * index;
23
+
24
+ @protected
25
+ int getMinChildIndexForScrollOffset (double scrollOffset, double itemExtent) {
26
+ return itemExtent > 0.0 ? math.max (0 , scrollOffset ~ / itemExtent) : 0 ;
27
+ }
28
+
29
+ @protected
30
+ int getMaxChildIndexForScrollOffset (double scrollOffset, double itemExtent) {
31
+ return itemExtent > 0.0 ? math.max (0 , (scrollOffset / itemExtent).ceil () - 1 ) : 0 ;
32
+ }
33
+
34
+ @protected
35
+ double estimateMaxScrollOffset (SliverConstraints constraints, {
36
+ int firstIndex,
37
+ int lastIndex,
38
+ double leadingScrollOffset,
39
+ double trailingScrollOffset,
40
+ }) {
41
+ return childManager.estimateMaxScrollOffset (
42
+ constraints,
43
+ firstIndex: firstIndex,
44
+ lastIndex: lastIndex,
45
+ leadingScrollOffset: leadingScrollOffset,
46
+ trailingScrollOffset: trailingScrollOffset,
47
+ );
48
+ }
49
+
21
50
@override
22
51
void performLayout () {
23
52
assert (childManager.debugAssertChildListLocked ());
24
53
childManager.setDidUnderflow (false );
25
54
26
55
final double itemExtent = this .itemExtent;
27
- double indexToScrollOffset (int index) => itemExtent * index;
28
56
29
57
final double scrollOffset = constraints.scrollOffset;
30
58
assert (scrollOffset >= 0.0 );
@@ -37,8 +65,8 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
37
65
maxExtent: itemExtent,
38
66
);
39
67
40
- final int firstIndex = itemExtent > 0.0 ? math. max ( 0 , scrollOffset ~ / itemExtent) : 0 ;
41
- final int targetLastIndex = itemExtent > 0.0 ? math. max ( 0 , (targetEndScrollOffset / itemExtent). ceil () - 1 ) : 0 ;
68
+ final int firstIndex = getMinChildIndexForScrollOffset (scrollOffset, itemExtent);
69
+ final int targetLastIndex = getMaxChildIndexForScrollOffset (targetEndScrollOffset, itemExtent);
42
70
43
71
if (firstChild != null ) {
44
72
final int oldFirstIndex = indexOf (firstChild);
@@ -50,7 +78,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
50
78
}
51
79
52
80
if (firstChild == null ) {
53
- if (! addInitialChild (index: firstIndex, scrollOffset: indexToScrollOffset (firstIndex))) {
81
+ if (! addInitialChild (index: firstIndex, scrollOffset: indexToScrollOffset (itemExtent, firstIndex))) {
54
82
// There are no children.
55
83
geometry = SliverGeometry .zero;
56
84
return ;
@@ -62,15 +90,15 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
62
90
for (int index = indexOf (firstChild) - 1 ; index >= firstIndex; -- index) {
63
91
final RenderBox child = insertAndLayoutLeadingChild (childConstraints);
64
92
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
65
- childParentData.layoutOffset = indexToScrollOffset (index);
93
+ childParentData.layoutOffset = indexToScrollOffset (itemExtent, index);
66
94
assert (childParentData.index == index);
67
95
trailingChildWithLayout ?? = child;
68
96
}
69
97
70
98
if (trailingChildWithLayout == null ) {
71
99
firstChild.layout (childConstraints);
72
100
final SliverMultiBoxAdaptorParentData childParentData = firstChild.parentData;
73
- childParentData.layoutOffset = indexToScrollOffset (firstIndex);
101
+ childParentData.layoutOffset = indexToScrollOffset (itemExtent, firstIndex);
74
102
trailingChildWithLayout = firstChild;
75
103
}
76
104
@@ -88,19 +116,19 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
88
116
trailingChildWithLayout = child;
89
117
assert (child != null );
90
118
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
91
- childParentData.layoutOffset = indexToScrollOffset (childParentData.index);
119
+ childParentData.layoutOffset = indexToScrollOffset (itemExtent, childParentData.index);
92
120
}
93
121
94
122
final int lastIndex = indexOf (lastChild);
95
- final double leadingScrollOffset = indexToScrollOffset (firstIndex);
96
- final double trailingScrollOffset = indexToScrollOffset (lastIndex + 1 );
123
+ final double leadingScrollOffset = indexToScrollOffset (itemExtent, firstIndex);
124
+ final double trailingScrollOffset = indexToScrollOffset (itemExtent, lastIndex + 1 );
97
125
98
- assert (childScrollOffset (firstChild) <= scrollOffset);
126
+ assert (firstIndex == 0 || childScrollOffset (firstChild) <= scrollOffset);
99
127
assert (debugAssertChildListIsNonEmptyAndContiguous ());
100
128
assert (indexOf (firstChild) == firstIndex);
101
129
assert (lastIndex <= targetLastIndex);
102
130
103
- final double estimatedMaxScrollOffset = childManager. estimateMaxScrollOffset (
131
+ final double estimatedMaxScrollOffset = estimateMaxScrollOffset (
104
132
constraints,
105
133
firstIndex: firstIndex,
106
134
lastIndex: lastIndex,
@@ -147,8 +175,56 @@ class RenderSliverFixedExtentList extends RenderSliverFixedExtentBoxAdaptor {
147
175
class RenderSliverFill extends RenderSliverFixedExtentBoxAdaptor {
148
176
RenderSliverFill ({
149
177
@required RenderSliverBoxChildManager childManager,
150
- }) : super (childManager: childManager);
178
+ double viewportFraction: 1.0 ,
179
+ }) : _viewportFraction = viewportFraction, super (childManager: childManager) {
180
+ assert (viewportFraction != null );
181
+ assert (viewportFraction > 0.0 );
182
+ }
183
+
184
+ @override
185
+ double get itemExtent => constraints.viewportMainAxisExtent * viewportFraction;
186
+
187
+ double get viewportFraction => _viewportFraction;
188
+ double _viewportFraction;
189
+ set viewportFraction (double newValue) {
190
+ assert (newValue != null );
191
+ if (_viewportFraction == newValue)
192
+ return ;
193
+ _viewportFraction = newValue;
194
+ markNeedsLayout ();
195
+ }
196
+
197
+ double get _padding => (1.0 - viewportFraction) * constraints.viewportMainAxisExtent * 0.5 ;
198
+
199
+ @override
200
+ double indexToScrollOffset (double itemExtent, int index) {
201
+ return _padding + super .indexToScrollOffset (itemExtent, index);
202
+ }
203
+
204
+ @override
205
+ int getMinChildIndexForScrollOffset (double scrollOffset, double itemExtent) {
206
+ return super .getMinChildIndexForScrollOffset (math.max (scrollOffset - _padding, 0.0 ), itemExtent);
207
+ }
208
+
209
+ @override
210
+ int getMaxChildIndexForScrollOffset (double scrollOffset, double itemExtent) {
211
+ return super .getMaxChildIndexForScrollOffset (math.max (scrollOffset - _padding, 0.0 ), itemExtent);
212
+ }
151
213
152
214
@override
153
- double get itemExtent => constraints.viewportMainAxisExtent;
215
+ double estimateMaxScrollOffset (SliverConstraints constraints, {
216
+ int firstIndex,
217
+ int lastIndex,
218
+ double leadingScrollOffset,
219
+ double trailingScrollOffset,
220
+ }) {
221
+ final double padding = _padding;
222
+ return childManager.estimateMaxScrollOffset (
223
+ constraints,
224
+ firstIndex: firstIndex,
225
+ lastIndex: lastIndex,
226
+ leadingScrollOffset: leadingScrollOffset - padding,
227
+ trailingScrollOffset: trailingScrollOffset - padding,
228
+ ) + padding + padding;
229
+ }
154
230
}
0 commit comments