Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
37f9c541
Unverified
Commit
37f9c541
authored
Nov 27, 2019
by
LongCatIsLooong
Committed by
GitHub
Nov 27, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use RenderSliverPadding to inset SliverFillViewport (#45432)
parent
1374a413
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
378 additions
and
176 deletions
+378
-176
sliver_fill.dart
packages/flutter/lib/src/rendering/sliver_fill.dart
+0
-35
sliver_fixed_extent_list.dart
...s/flutter/lib/src/rendering/sliver_fixed_extent_list.dart
+1
-1
sliver_padding.dart
packages/flutter/lib/src/rendering/sliver_padding.dart
+110
-84
page_view.dart
packages/flutter/lib/src/widgets/page_view.dart
+19
-2
sliver.dart
packages/flutter/lib/src/widgets/sliver.dart
+103
-4
page_view_test.dart
packages/flutter/test/widgets/page_view_test.dart
+84
-2
sliver_fill_viewport_test.dart
packages/flutter/test/widgets/sliver_fill_viewport_test.dart
+61
-48
No files found.
packages/flutter/lib/src/rendering/sliver_fill.dart
View file @
37f9c541
...
...
@@ -57,41 +57,6 @@ class RenderSliverFillViewport extends RenderSliverFixedExtentBoxAdaptor {
_viewportFraction
=
value
;
markNeedsLayout
();
}
double
get
_padding
=>
(
1.0
-
viewportFraction
)
*
constraints
.
viewportMainAxisExtent
*
0.5
;
@override
double
indexToLayoutOffset
(
double
itemExtent
,
int
index
)
{
return
_padding
+
super
.
indexToLayoutOffset
(
itemExtent
,
index
);
}
@override
int
getMinChildIndexForScrollOffset
(
double
scrollOffset
,
double
itemExtent
)
{
return
super
.
getMinChildIndexForScrollOffset
(
math
.
max
(
scrollOffset
-
_padding
,
0.0
),
itemExtent
);
}
@override
int
getMaxChildIndexForScrollOffset
(
double
scrollOffset
,
double
itemExtent
)
{
return
super
.
getMaxChildIndexForScrollOffset
(
math
.
max
(
scrollOffset
-
_padding
,
0.0
),
itemExtent
);
}
@override
double
estimateMaxScrollOffset
(
SliverConstraints
constraints
,
{
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
double
trailingScrollOffset
,
})
{
final
double
padding
=
_padding
;
return
childManager
.
estimateMaxScrollOffset
(
constraints
,
firstIndex:
firstIndex
,
lastIndex:
lastIndex
,
leadingScrollOffset:
leadingScrollOffset
-
padding
,
trailingScrollOffset:
trailingScrollOffset
-
padding
,
)
+
padding
+
padding
;
}
}
/// A sliver that contains a single box child that fills the remaining space in
...
...
packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart
View file @
37f9c541
...
...
@@ -195,7 +195,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
if
(
firstChild
==
null
)
{
if
(!
addInitialChild
(
index:
firstIndex
,
layoutOffset:
indexToLayoutOffset
(
itemExtent
,
firstIndex
)))
{
// There are either no children, or we are past the end of all our children.
// If it is the later, we will need to find the first available child.
// If it is the lat
t
er, we will need to find the first available child.
double
max
;
if
(
childManager
.
childCount
!=
null
)
{
max
=
computeMaxScrollOffset
(
constraints
,
itemExtent
);
...
...
packages/flutter/lib/src/rendering/sliver_padding.dart
View file @
37f9c541
...
...
@@ -12,73 +12,27 @@ import 'debug.dart';
import
'object.dart'
;
import
'sliver.dart'
;
/// Inset
a [RenderSliver], applying padding
on each side.
/// Inset
s a [RenderSliver] by applying [resolvedPadding]
on each side.
///
/// A [RenderSliver
Padding] object wraps the [SliverGeometry.layoutExtent] of
/// its child. Any incoming [SliverConstraints.overlap] is ignored and not
/// A [RenderSliver
EdgeInsetsPadding] subclass wraps the [SliverGeometry.layoutExtent]
///
of
its child. Any incoming [SliverConstraints.overlap] is ignored and not
/// passed on to the child.
///
/// {@template flutter.rendering.sliverPadding.limitation}
/// Applying padding to anything but the most mundane sliver is likely to have
/// undesired effects. For example, wrapping a
/// [RenderSliverPinnedPersistentHeader] will cause the app bar to overlap
/// earlier slivers (contrary to the normal behavior of pinned app bars), and
/// while the app bar is pinned, the padding will scroll away.
class
RenderSliverPadding
extends
RenderSliver
with
RenderObjectWithChildMixin
<
RenderSliver
>
{
/// Creates a render object that insets its child in a viewport.
///
/// The [padding] argument must not be null and must have non-negative insets.
RenderSliverPadding
({
@required
EdgeInsetsGeometry
padding
,
TextDirection
textDirection
,
RenderSliver
child
,
})
:
assert
(
padding
!=
null
),
assert
(
padding
.
isNonNegative
),
_padding
=
padding
,
_textDirection
=
textDirection
{
this
.
child
=
child
;
}
EdgeInsets
_resolvedPadding
;
void
_resolve
()
{
if
(
_resolvedPadding
!=
null
)
return
;
_resolvedPadding
=
padding
.
resolve
(
textDirection
);
assert
(
_resolvedPadding
.
isNonNegative
);
}
void
_markNeedResolution
()
{
_resolvedPadding
=
null
;
markNeedsLayout
();
}
/// undesired effects. For example, wrapping a [RenderSliverPinnedPersistentHeader]
/// will cause the app bar to overlap earlier slivers (contrary to the normal
/// behavior of pinned app bars), and while the app bar is pinned, the padding
/// will scroll away.
/// {@endtemplate}
abstract
class
RenderSliverEdgeInsetsPadding
extends
RenderSliver
with
RenderObjectWithChildMixin
<
RenderSliver
>
{
/// The amount to pad the child in each dimension.
///
/// If this is set to an [EdgeInsetsDirectional] object, then [textDirection]
/// must not be null.
EdgeInsetsGeometry
get
padding
=>
_padding
;
EdgeInsetsGeometry
_padding
;
set
padding
(
EdgeInsetsGeometry
value
)
{
assert
(
value
!=
null
);
assert
(
padding
.
isNonNegative
);
if
(
_padding
==
value
)
return
;
_padding
=
value
;
_markNeedResolution
();
}
/// The text direction with which to resolve [padding].
/// The offsets are specified in terms of visual edges, left, top, right, and
/// bottom. These values are not affected by the [TextDirection].
///
/// This may be changed to null, but only after the [padding] has been changed
/// to a value that does not depend on the direction.
TextDirection
get
textDirection
=>
_textDirection
;
TextDirection
_textDirection
;
set
textDirection
(
TextDirection
value
)
{
if
(
_textDirection
==
value
)
return
;
_textDirection
=
value
;
_markNeedResolution
();
}
/// Must not be null or contain negative values when [performLayout] is called.
EdgeInsets
get
resolvedPadding
;
/// The padding in the scroll direction on the side nearest the 0.0 scroll direction.
///
...
...
@@ -88,16 +42,16 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert
(
constraints
!=
null
);
assert
(
constraints
.
axisDirection
!=
null
);
assert
(
constraints
.
growthDirection
!=
null
);
assert
(
_
resolvedPadding
!=
null
);
assert
(
resolvedPadding
!=
null
);
switch
(
applyGrowthDirectionToAxisDirection
(
constraints
.
axisDirection
,
constraints
.
growthDirection
))
{
case
AxisDirection
.
up
:
return
_
resolvedPadding
.
bottom
;
return
resolvedPadding
.
bottom
;
case
AxisDirection
.
right
:
return
_
resolvedPadding
.
left
;
return
resolvedPadding
.
left
;
case
AxisDirection
.
down
:
return
_
resolvedPadding
.
top
;
return
resolvedPadding
.
top
;
case
AxisDirection
.
left
:
return
_
resolvedPadding
.
right
;
return
resolvedPadding
.
right
;
}
return
null
;
}
...
...
@@ -110,16 +64,16 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert
(
constraints
!=
null
);
assert
(
constraints
.
axisDirection
!=
null
);
assert
(
constraints
.
growthDirection
!=
null
);
assert
(
_
resolvedPadding
!=
null
);
assert
(
resolvedPadding
!=
null
);
switch
(
applyGrowthDirectionToAxisDirection
(
constraints
.
axisDirection
,
constraints
.
growthDirection
))
{
case
AxisDirection
.
up
:
return
_
resolvedPadding
.
top
;
return
resolvedPadding
.
top
;
case
AxisDirection
.
right
:
return
_
resolvedPadding
.
right
;
return
resolvedPadding
.
right
;
case
AxisDirection
.
down
:
return
_
resolvedPadding
.
bottom
;
return
resolvedPadding
.
bottom
;
case
AxisDirection
.
left
:
return
_
resolvedPadding
.
left
;
return
resolvedPadding
.
left
;
}
return
null
;
}
...
...
@@ -133,8 +87,8 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
double
get
mainAxisPadding
{
assert
(
constraints
!=
null
);
assert
(
constraints
.
axis
!=
null
);
assert
(
_
resolvedPadding
!=
null
);
return
_
resolvedPadding
.
along
(
constraints
.
axis
);
assert
(
resolvedPadding
!=
null
);
return
resolvedPadding
.
along
(
constraints
.
axis
);
}
/// The total padding in the cross-axis direction. (In other words, for a
...
...
@@ -146,12 +100,12 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
double
get
crossAxisPadding
{
assert
(
constraints
!=
null
);
assert
(
constraints
.
axis
!=
null
);
assert
(
_
resolvedPadding
!=
null
);
assert
(
resolvedPadding
!=
null
);
switch
(
constraints
.
axis
)
{
case
Axis
.
horizontal
:
return
_
resolvedPadding
.
vertical
;
return
resolvedPadding
.
vertical
;
case
Axis
.
vertical
:
return
_
resolvedPadding
.
horizontal
;
return
resolvedPadding
.
horizontal
;
}
return
null
;
}
...
...
@@ -164,8 +118,7 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
@override
void
performLayout
()
{
_resolve
();
assert
(
_resolvedPadding
!=
null
);
assert
(
resolvedPadding
!=
null
);
final
double
beforePadding
=
this
.
beforePadding
;
final
double
afterPadding
=
this
.
afterPadding
;
final
double
mainAxisPadding
=
this
.
mainAxisPadding
;
...
...
@@ -240,16 +193,16 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert
(
constraints
.
growthDirection
!=
null
);
switch
(
applyGrowthDirectionToAxisDirection
(
constraints
.
axisDirection
,
constraints
.
growthDirection
))
{
case
AxisDirection
.
up
:
childParentData
.
paintOffset
=
Offset
(
_resolvedPadding
.
left
,
calculatePaintOffset
(
constraints
,
from:
_resolvedPadding
.
bottom
+
childLayoutGeometry
.
scrollExtent
,
to:
_resolvedPadding
.
bottom
+
childLayoutGeometry
.
scrollExtent
+
_
resolvedPadding
.
top
));
childParentData
.
paintOffset
=
Offset
(
resolvedPadding
.
left
,
calculatePaintOffset
(
constraints
,
from:
resolvedPadding
.
bottom
+
childLayoutGeometry
.
scrollExtent
,
to:
resolvedPadding
.
bottom
+
childLayoutGeometry
.
scrollExtent
+
resolvedPadding
.
top
));
break
;
case
AxisDirection
.
right
:
childParentData
.
paintOffset
=
Offset
(
calculatePaintOffset
(
constraints
,
from:
0.0
,
to:
_resolvedPadding
.
left
),
_
resolvedPadding
.
top
);
childParentData
.
paintOffset
=
Offset
(
calculatePaintOffset
(
constraints
,
from:
0.0
,
to:
resolvedPadding
.
left
),
resolvedPadding
.
top
);
break
;
case
AxisDirection
.
down
:
childParentData
.
paintOffset
=
Offset
(
_resolvedPadding
.
left
,
calculatePaintOffset
(
constraints
,
from:
0.0
,
to:
_
resolvedPadding
.
top
));
childParentData
.
paintOffset
=
Offset
(
resolvedPadding
.
left
,
calculatePaintOffset
(
constraints
,
from:
0.0
,
to:
resolvedPadding
.
top
));
break
;
case
AxisDirection
.
left
:
childParentData
.
paintOffset
=
Offset
(
calculatePaintOffset
(
constraints
,
from:
_resolvedPadding
.
right
+
childLayoutGeometry
.
scrollExtent
,
to:
_resolvedPadding
.
right
+
childLayoutGeometry
.
scrollExtent
+
_resolvedPadding
.
left
),
_
resolvedPadding
.
top
);
childParentData
.
paintOffset
=
Offset
(
calculatePaintOffset
(
constraints
,
from:
resolvedPadding
.
right
+
childLayoutGeometry
.
scrollExtent
,
to:
resolvedPadding
.
right
+
childLayoutGeometry
.
scrollExtent
+
resolvedPadding
.
left
),
resolvedPadding
.
top
);
break
;
}
assert
(
childParentData
.
paintOffset
!=
null
);
...
...
@@ -289,14 +242,14 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
assert
(
constraints
!=
null
);
assert
(
constraints
.
axisDirection
!=
null
);
assert
(
constraints
.
growthDirection
!=
null
);
assert
(
_
resolvedPadding
!=
null
);
assert
(
resolvedPadding
!=
null
);
switch
(
applyGrowthDirectionToAxisDirection
(
constraints
.
axisDirection
,
constraints
.
growthDirection
))
{
case
AxisDirection
.
up
:
case
AxisDirection
.
down
:
return
_
resolvedPadding
.
left
;
return
resolvedPadding
.
left
;
case
AxisDirection
.
left
:
case
AxisDirection
.
right
:
return
_
resolvedPadding
.
top
;
return
resolvedPadding
.
top
;
}
return
null
;
}
...
...
@@ -346,6 +299,79 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
return
true
;
}());
}
}
/// Insets a [RenderSliver], applying padding on each side.
///
/// A [RenderSliverPadding] object wraps the [SliverGeometry.layoutExtent] of
/// its child. Any incoming [SliverConstraints.overlap] is ignored and not
/// passed on to the child.
///
/// {@macro flutter.rendering.sliverPadding.limitation}
class
RenderSliverPadding
extends
RenderSliverEdgeInsetsPadding
{
/// Creates a render object that insets its child in a viewport.
///
/// The [padding] argument must not be null and must have non-negative insets.
RenderSliverPadding
({
@required
EdgeInsetsGeometry
padding
,
TextDirection
textDirection
,
RenderSliver
child
,
})
:
assert
(
padding
!=
null
),
assert
(
padding
.
isNonNegative
),
_padding
=
padding
,
_textDirection
=
textDirection
{
this
.
child
=
child
;
}
@override
EdgeInsets
get
resolvedPadding
=>
_resolvedPadding
;
EdgeInsets
_resolvedPadding
;
void
_resolve
()
{
if
(
resolvedPadding
!=
null
)
return
;
_resolvedPadding
=
padding
.
resolve
(
textDirection
);
assert
(
resolvedPadding
.
isNonNegative
);
}
void
_markNeedsResolution
()
{
_resolvedPadding
=
null
;
markNeedsLayout
();
}
/// The amount to pad the child in each dimension.
///
/// If this is set to an [EdgeInsetsDirectional] object, then [textDirection]
/// must not be null.
EdgeInsetsGeometry
get
padding
=>
_padding
;
EdgeInsetsGeometry
_padding
;
set
padding
(
EdgeInsetsGeometry
value
)
{
assert
(
value
!=
null
);
assert
(
padding
.
isNonNegative
);
if
(
_padding
==
value
)
return
;
_padding
=
value
;
_markNeedsResolution
();
}
/// The text direction with which to resolve [padding].
///
/// This may be changed to null, but only after the [padding] has been changed
/// to a value that does not depend on the direction.
TextDirection
get
textDirection
=>
_textDirection
;
TextDirection
_textDirection
;
set
textDirection
(
TextDirection
value
)
{
if
(
_textDirection
==
value
)
return
;
_textDirection
=
value
;
_markNeedsResolution
();
}
@override
void
performLayout
()
{
_resolve
();
super
.
performLayout
();
}
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
...
...
packages/flutter/lib/src/widgets/page_view.dart
View file @
37f9c541
...
...
@@ -345,8 +345,16 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
forcePixels
(
getPixelsFromPage
(
oldPage
));
}
// The amount of offset that will be added to [minScrollExtent] and subtracted
// from [maxScrollExtent], such that every page will properly snap to the center
// of the viewport when viewportFraction is greater than 1.
//
// The value is 0 if viewportFraction is less than or equal to 1, larger than 0
// otherwise.
double
get
_initialPageOffset
=>
math
.
max
(
0
,
viewportDimension
*
(
viewportFraction
-
1
)
/
2
);
double
getPageFromPixels
(
double
pixels
,
double
viewportDimension
)
{
final
double
actual
=
math
.
max
(
0.0
,
pixels
)
/
math
.
max
(
1.0
,
viewportDimension
*
viewportFraction
);
final
double
actual
=
math
.
max
(
0.0
,
pixels
-
_initialPageOffset
)
/
math
.
max
(
1.0
,
viewportDimension
*
viewportFraction
);
final
double
round
=
actual
.
roundToDouble
();
if
((
actual
-
round
).
abs
()
<
precisionErrorTolerance
)
{
return
round
;
...
...
@@ -355,7 +363,7 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
}
double
getPixelsFromPage
(
double
page
)
{
return
page
*
viewportDimension
*
viewportFraction
;
return
page
*
viewportDimension
*
viewportFraction
+
_initialPageOffset
;
}
@override
...
...
@@ -396,6 +404,15 @@ class _PagePosition extends ScrollPositionWithSingleContext implements PageMetri
return
result
;
}
@override
bool
applyContentDimensions
(
double
minScrollExtent
,
double
maxScrollExtent
)
{
final
double
newMinScrollExtent
=
minScrollExtent
+
_initialPageOffset
;
return
super
.
applyContentDimensions
(
newMinScrollExtent
,
math
.
max
(
newMinScrollExtent
,
maxScrollExtent
-
_initialPageOffset
),
);
}
@override
PageMetrics
copyWith
({
double
minScrollExtent
,
...
...
packages/flutter/lib/src/widgets/sliver.dart
View file @
37f9c541
...
...
@@ -725,6 +725,7 @@ abstract class SliverMultiBoxAdaptorWidget extends SliverWithKeepAliveWidget {
})
:
assert
(
delegate
!=
null
),
super
(
key:
key
);
/// {@template flutter.widgets.sliverMultiBoxAdaptor.delegate}
/// The delegate that provides the children for this widget.
///
/// The children are constructed lazily using this delegate to avoid creating
...
...
@@ -735,6 +736,7 @@ abstract class SliverMultiBoxAdaptorWidget extends SliverWithKeepAliveWidget {
/// * [SliverChildBuilderDelegate] and [SliverChildListDelegate], which are
/// commonly used subclasses of [SliverChildDelegate] that use a builder
/// callback and an explicit child list, respectively.
/// {@endtemplate}
final
SliverChildDelegate
delegate
;
@override
...
...
@@ -1023,7 +1025,7 @@ class SliverGrid extends SliverMultiBoxAdaptorWidget {
}
}
/// A sliver that contains
a multiple box children that each fill
the viewport.
/// A sliver that contains
multiple box children that each fills
the viewport.
///
/// [SliverFillViewport] places its children in a linear array along the main
/// axis. Each child is sized to fill the viewport, both in the main and cross
...
...
@@ -1038,15 +1040,15 @@ class SliverGrid extends SliverMultiBoxAdaptorWidget {
/// the main axis extent of each item.
/// * [SliverList], which does not require its children to have the same
/// extent in the main axis.
class
SliverFillViewport
extends
S
liverMultiBoxAdaptor
Widget
{
class
SliverFillViewport
extends
S
tateless
Widget
{
/// Creates a sliver whose box children that each fill the viewport.
const
SliverFillViewport
({
Key
key
,
@required
SliverChildDelegate
delegate
,
@required
this
.
delegate
,
this
.
viewportFraction
=
1.0
,
})
:
assert
(
viewportFraction
!=
null
),
assert
(
viewportFraction
>
0.0
),
super
(
key:
key
,
delegate:
delegate
);
super
(
key:
key
);
/// The fraction of the viewport that each child should fill in the main axis.
///
...
...
@@ -1055,6 +1057,32 @@ class SliverFillViewport extends SliverMultiBoxAdaptorWidget {
/// the viewport in the main axis.
final
double
viewportFraction
;
/// {@macro flutter.widgets.sliverMultiBoxAdaptor.delegate}
final
SliverChildDelegate
delegate
;
@override
Widget
build
(
BuildContext
context
)
{
return
_SliverFractionalPadding
(
viewportFraction:
(
1
-
viewportFraction
).
clamp
(
0
,
1
)
/
2
,
sliver:
_SliverFillViewportRenderObjectWidget
(
viewportFraction:
viewportFraction
,
delegate:
delegate
,
),
);
}
}
class
_SliverFillViewportRenderObjectWidget
extends
SliverMultiBoxAdaptorWidget
{
const
_SliverFillViewportRenderObjectWidget
({
Key
key
,
@required
SliverChildDelegate
delegate
,
this
.
viewportFraction
=
1.0
,
})
:
assert
(
viewportFraction
!=
null
),
assert
(
viewportFraction
>
0.0
),
super
(
key:
key
,
delegate:
delegate
);
final
double
viewportFraction
;
@override
RenderSliverFillViewport
createRenderObject
(
BuildContext
context
)
{
final
SliverMultiBoxAdaptorElement
element
=
context
;
...
...
@@ -1067,6 +1095,77 @@ class SliverFillViewport extends SliverMultiBoxAdaptorWidget {
}
}
class
_SliverFractionalPadding
extends
SingleChildRenderObjectWidget
{
const
_SliverFractionalPadding
({
this
.
viewportFraction
=
0
,
Widget
sliver
,
})
:
assert
(
viewportFraction
!=
null
),
assert
(
viewportFraction
>=
0
),
assert
(
viewportFraction
<=
0.5
),
super
(
child:
sliver
);
final
double
viewportFraction
;
@override
RenderObject
createRenderObject
(
BuildContext
context
)
=>
_RenderSliverFractionalPadding
(
viewportFraction:
viewportFraction
);
@override
void
updateRenderObject
(
BuildContext
context
,
_RenderSliverFractionalPadding
renderObject
)
{
renderObject
.
viewportFraction
=
viewportFraction
;
}
}
class
_RenderSliverFractionalPadding
extends
RenderSliverEdgeInsetsPadding
{
_RenderSliverFractionalPadding
({
double
viewportFraction
=
0
,
})
:
assert
(
viewportFraction
!=
null
),
assert
(
viewportFraction
<=
0.5
),
assert
(
viewportFraction
>=
0
),
_viewportFraction
=
viewportFraction
;
double
get
viewportFraction
=>
_viewportFraction
;
double
_viewportFraction
;
set
viewportFraction
(
double
newValue
)
{
assert
(
newValue
!=
null
);
if
(
_viewportFraction
==
newValue
)
return
;
_viewportFraction
=
newValue
;
_markNeedsResolution
();
}
@override
EdgeInsets
get
resolvedPadding
=>
_resolvedPadding
;
EdgeInsets
_resolvedPadding
;
void
_markNeedsResolution
()
{
_resolvedPadding
=
null
;
markNeedsLayout
();
}
void
_resolve
()
{
if
(
_resolvedPadding
!=
null
)
return
;
assert
(
constraints
.
axis
!=
null
);
final
double
paddingValue
=
constraints
.
viewportMainAxisExtent
*
viewportFraction
;
switch
(
constraints
.
axis
)
{
case
Axis
.
horizontal
:
_resolvedPadding
=
EdgeInsets
.
symmetric
(
horizontal:
paddingValue
);
break
;
case
Axis
.
vertical
:
_resolvedPadding
=
EdgeInsets
.
symmetric
(
vertical:
paddingValue
);
break
;
}
return
;
}
@override
void
performLayout
()
{
_resolve
();
super
.
performLayout
();
}
}
/// An element that lazily builds children for a [SliverMultiBoxAdaptorWidget].
///
/// Implements [RenderSliverBoxChildManager], which lets this element manage
...
...
packages/flutter/test/widgets/page_view_test.dart
View file @
37f9c541
...
...
@@ -532,8 +532,7 @@ void main() {
});
testWidgets
(
'PageView large viewportFraction'
,
(
WidgetTester
tester
)
async
{
final
PageController
controller
=
PageController
(
viewportFraction:
5
/
4
);
final
PageController
controller
=
PageController
(
viewportFraction:
5
/
4
);
Widget
build
(
PageController
controller
)
{
return
Directionality
(
...
...
@@ -601,6 +600,89 @@ void main() {
expect
(
tester
.
getTopLeft
(
find
.
text
(
'Hawaii'
)),
const
Offset
(-(
4
-
1
)
*
800
/
2
,
0
));
});
testWidgets
(
'PageView large viewportFraction can scroll to the last page and snap'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/45096.
final
PageController
controller
=
PageController
(
viewportFraction:
5
/
4
);
Widget
build
(
PageController
controller
)
{
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
PageView
.
builder
(
controller:
controller
,
itemCount:
3
,
itemBuilder:
(
BuildContext
context
,
int
index
)
{
return
Container
(
height:
200.0
,
color:
index
%
2
==
0
?
const
Color
(
0xFF0000FF
)
:
const
Color
(
0xFF00FF00
),
child:
Text
(
index
.
toString
()),
);
},
),
);
}
await
tester
.
pumpWidget
(
build
(
controller
));
expect
(
tester
.
getCenter
(
find
.
text
(
'0'
)),
const
Offset
(
400
,
300
));
controller
.
jumpToPage
(
2
);
await
tester
.
pump
();
await
tester
.
pumpAndSettle
();
expect
(
tester
.
getCenter
(
find
.
text
(
'2'
)),
const
Offset
(
400
,
300
));
});
testWidgets
(
'All visible pages are able to receive touch events'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/23873.
final
PageController
controller
=
PageController
(
viewportFraction:
1
/
4
,
initialPage:
0
);
int
tappedIndex
;
Widget
build
()
{
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
PageView
.
builder
(
controller:
controller
,
itemCount:
20
,
itemBuilder:
(
BuildContext
context
,
int
index
)
{
return
GestureDetector
(
onTap:
()
=>
tappedIndex
=
index
,
child:
SizedBox
.
expand
(
child:
Text
(
'
$index
'
)),
);
},
),
);
}
Iterable
<
int
>
visiblePages
=
const
<
int
>
[
0
,
1
,
2
];
await
tester
.
pumpWidget
(
build
());
// The first 3 items should be visible and tappable.
for
(
int
index
in
visiblePages
)
{
expect
(
find
.
text
(
index
.
toString
()),
findsOneWidget
);
// The center of page 2's x-coordinate is 800, so we have to manually
// offset it a bit to make sure the tap lands within the screen.
final
Offset
center
=
tester
.
getCenter
(
find
.
text
(
'
$index
'
))
-
const
Offset
(
3
,
0
);
await
tester
.
tapAt
(
center
);
expect
(
tappedIndex
,
index
);
}
controller
.
jumpToPage
(
19
);
await
tester
.
pump
();
// The last 3 items should be visible and tappable.
visiblePages
=
const
<
int
>
[
17
,
18
,
19
];
for
(
int
index
in
visiblePages
)
{
expect
(
find
.
text
(
'
$index
'
),
findsOneWidget
);
await
tester
.
tap
(
find
.
text
(
'
$index
'
));
expect
(
tappedIndex
,
index
);
}
});
testWidgets
(
'PageView does not report page changed on overscroll'
,
(
WidgetTester
tester
)
async
{
final
PageController
controller
=
PageController
(
initialPage:
kStates
.
length
-
1
,
...
...
packages/flutter/test/widgets/sliver_fill_viewport_test.dart
View file @
37f9c541
...
...
@@ -64,7 +64,20 @@ void main() {
expect
(
viewport
.
toStringDeep
(
minLevel:
DiagnosticLevel
.
info
),
equalsIgnoringHashCodes
(
'RenderSliverFillViewport#00000 relayoutBoundary=up1
\n
'
'_RenderSliverFractionalPadding#00000 relayoutBoundary=up1
\n
'
' │ needs compositing
\n
'
' │ parentData: paintOffset=Offset(0.0, 0.0) (can use size)
\n
'
' │ constraints: SliverConstraints(AxisDirection.down,
\n
'
' │ GrowthDirection.forward, ScrollDirection.idle, scrollOffset:
\n
'
' │ 0.0, remainingPaintExtent: 600.0, crossAxisExtent: 800.0,
\n
'
' │ crossAxisDirection: AxisDirection.right,
\n
'
' │ viewportMainAxisExtent: 600.0, remainingCacheExtent: 850.0
\n
'
' │ cacheOrigin: 0.0 )
\n
'
' │ geometry: SliverGeometry(scrollExtent: 12000.0, paintExtent:
\n
'
' │ 600.0, maxPaintExtent: 12000.0, hasVisualOverflow: true,
\n
'
' │ cacheExtent: 850.0)
\n
'
' │
\n
'
' └─child: RenderSliverFillViewport#00000 relayoutBoundary=up2
\n
'
' │ needs compositing
\n
'
' │ parentData: paintOffset=Offset(0.0, 0.0) (can use size)
\n
'
' │ constraints: SliverConstraints(AxisDirection.down,
\n
'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment