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
32784d35
Commit
32784d35
authored
Feb 01, 2017
by
Ian Hickson
Committed by
GitHub
Feb 01, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Add SliverGrid and ScrollGrid" (#7769)
parent
a0f0c42f
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
185 additions
and
1116 deletions
+185
-1116
grid_list_demo.dart
examples/flutter_gallery/lib/demo/grid_list_demo.dart
+39
-37
rendering.dart
packages/flutter/lib/rendering.dart
+0
-1
sliver.dart
packages/flutter/lib/src/rendering/sliver.dart
+11
-19
sliver_app_bar.dart
packages/flutter/lib/src/rendering/sliver_app_bar.dart
+9
-9
sliver_block.dart
packages/flutter/lib/src/rendering/sliver_block.dart
+6
-7
sliver_grid.dart
packages/flutter/lib/src/rendering/sliver_grid.dart
+0
-426
sliver_list.dart
packages/flutter/lib/src/rendering/sliver_list.dart
+4
-7
sliver_multi_box_adaptor.dart
...s/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
+10
-19
sliver_padding.dart
packages/flutter/lib/src/rendering/sliver_padding.dart
+2
-9
scroll_view.dart
packages/flutter/lib/src/widgets/scroll_view.dart
+27
-96
sliver.dart
packages/flutter/lib/src/widgets/sliver.dart
+20
-100
slivers_block_test.dart
packages/flutter/test/rendering/slivers_block_test.dart
+1
-1
block_test.dart
packages/flutter/test/widgets/block_test.dart
+2
-20
scroll_grid_test.dart
packages/flutter/test/widgets/scroll_grid_test.dart
+0
-306
scroll_view_test.dart
packages/flutter/test/widgets/scroll_view_test.dart
+54
-3
states.dart
packages/flutter/test/widgets/states.dart
+0
-56
No files found.
examples/flutter_gallery/lib/demo/grid_list_demo.dart
View file @
32784d35
...
...
@@ -131,9 +131,9 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
..
translate
(
_offset
.
dx
,
_offset
.
dy
)
..
scale
(
_scale
),
child:
new
ClipRect
(
child:
new
Image
.
asset
(
config
.
photo
.
assetName
,
fit:
ImageFit
.
cover
)
,
)
,
)
,
child:
new
Image
.
asset
(
config
.
photo
.
assetName
,
fit:
ImageFit
.
cover
)
)
)
);
}
);
...
...
@@ -200,11 +200,11 @@ class GridDemoPhotoItem extends StatelessWidget {
backgroundColor:
Colors
.
black45
,
leading:
new
Icon
(
icon
,
color:
Colors
.
white
,
)
,
)
,
color:
Colors
.
white
)
)
),
child:
image
,
child:
image
);
case
GridDemoTileStyle
.
twoLine
:
...
...
@@ -217,11 +217,11 @@ class GridDemoPhotoItem extends StatelessWidget {
subtitle:
new
_GridTitleText
(
photo
.
caption
),
trailing:
new
Icon
(
icon
,
color:
Colors
.
white
,
)
,
)
,
color:
Colors
.
white
)
)
),
child:
image
,
child:
image
);
}
assert
(
tileStyle
!=
null
);
...
...
@@ -245,62 +245,62 @@ class GridListDemoState extends State<GridListDemo> {
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_0.jpg'
,
title:
'Philippines'
,
caption:
'Batad rice terraces'
,
caption:
'Batad rice terraces'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_1.jpg'
,
title:
'Italy'
,
caption:
'Ceresole Reale'
,
caption:
'Ceresole Reale'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_2.jpg'
,
title:
'Somewhere'
,
caption:
'Beautiful mountains'
,
caption:
'Beautiful mountains'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_3.jpg'
,
title:
'A place'
,
caption:
'Beautiful hills'
,
caption:
'Beautiful hills'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_4.jpg'
,
title:
'New Zealand'
,
caption:
'View from the van'
,
caption:
'View from the van'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_5.jpg'
,
title:
'Autumn'
,
caption:
'The golden season'
,
caption:
'The golden season'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_6.jpg'
,
title:
'Germany'
,
caption:
'Englischer Garten'
,
caption:
'Englischer Garten'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_7.jpg'
,
title:
'A country'
,
caption:
'Grass fields'
,
caption:
'Grass fields'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_8.jpg'
,
title:
'Mountain country'
,
caption:
'River forest'
,
caption:
'River forest'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_9.jpg'
,
title:
'Alpine place'
,
caption:
'Green hills'
,
caption:
'Green hills'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_10.jpg'
,
title:
'Desert land'
,
caption:
'Blue skies'
,
caption:
'Blue skies'
),
new
Photo
(
assetName:
'packages/flutter_gallery_assets/landscape_11.jpg'
,
title:
'Narnia'
,
caption:
'Rocks and rivers'
,
caption:
'Rocks and rivers'
),
];
...
...
@@ -325,29 +325,31 @@ class GridListDemoState extends State<GridListDemo> {
itemBuilder:
(
BuildContext
context
)
=>
<
PopupMenuItem
<
GridDemoTileStyle
>>[
new
PopupMenuItem
<
GridDemoTileStyle
>(
value:
GridDemoTileStyle
.
imageOnly
,
child:
new
Text
(
'Image only'
)
,
child:
new
Text
(
'Image only'
)
),
new
PopupMenuItem
<
GridDemoTileStyle
>(
value:
GridDemoTileStyle
.
oneLine
,
child:
new
Text
(
'One line'
)
,
child:
new
Text
(
'One line'
)
),
new
PopupMenuItem
<
GridDemoTileStyle
>(
value:
GridDemoTileStyle
.
twoLine
,
child:
new
Text
(
'Two line'
)
,
)
,
]
,
)
,
]
,
child:
new
Text
(
'Two line'
)
)
]
)
]
),
body:
new
Column
(
children:
<
Widget
>[
new
Expanded
(
child:
new
ScrollGrid
.
count
(
crossAxisCount:
(
orientation
==
Orientation
.
portrait
)
?
2
:
3
,
mainAxisSpacing:
4.0
,
crossAxisSpacing:
4.0
,
child:
new
ScrollableGrid
(
delegate:
new
FixedColumnCountGridDelegate
(
columnCount:
(
orientation
==
Orientation
.
portrait
)
?
2
:
3
,
rowSpacing:
4.0
,
columnSpacing:
4.0
,
padding:
const
EdgeInsets
.
all
(
4.0
),
childAspectRatio:
(
orientation
==
Orientation
.
portrait
)
?
1.0
:
1.3
,
tileAspectRatio:
(
orientation
==
Orientation
.
portrait
)
?
1.0
:
1.3
),
children:
photos
.
map
((
Photo
photo
)
{
return
new
GridDemoPhotoItem
(
photo:
photo
,
...
...
@@ -358,7 +360,7 @@ class GridListDemoState extends State<GridListDemo> {
});
}
);
})
.
toList
(),
})
)
)
]
...
...
packages/flutter/lib/rendering.dart
View file @
32784d35
...
...
@@ -47,7 +47,6 @@ export 'src/rendering/shifted_box.dart';
export
'src/rendering/sliver.dart'
;
export
'src/rendering/sliver_app_bar.dart'
;
export
'src/rendering/sliver_block.dart'
;
export
'src/rendering/sliver_grid.dart'
;
export
'src/rendering/sliver_list.dart'
;
export
'src/rendering/sliver_multi_box_adaptor.dart'
;
export
'src/rendering/sliver_padding.dart'
;
...
...
packages/flutter/lib/src/rendering/sliver.dart
View file @
32784d35
...
...
@@ -282,9 +282,7 @@ class SliverConstraints extends Constraints {
BoxConstraints
asBoxConstraints
({
double
minExtent:
0.0
,
double
maxExtent:
double
.
INFINITY
,
double
crossAxisExtent
,
})
{
crossAxisExtent
??=
this
.
crossAxisExtent
;
switch
(
axis
)
{
case
Axis
.
horizontal
:
return
new
BoxConstraints
(
...
...
@@ -817,16 +815,13 @@ abstract class RenderSliver extends RenderObject {
/// the [RenderSliverHelpers] mixin and do not call this method yourself, you
/// do not need to implement this method.
@protected
double
child
MainAxis
Position
(
@checked
RenderObject
child
)
{
double
childPosition
(
@checked
RenderObject
child
)
{
assert
(()
{
throw
new
FlutterError
(
'
$runtimeType
does not implement childPosition.'
);
});
return
0.0
;
}
@protected
double
childCrossAxisPosition
(
@checked
RenderObject
child
)
=>
0.0
;
@override
void
applyPaintTransform
(
RenderObject
child
,
Matrix4
transform
)
{
assert
(()
{
...
...
@@ -1003,25 +998,24 @@ abstract class RenderSliverHelpers implements RenderSliver {
/// This function takes care of converting the position from the sliver
/// coordinate system to the cartesian coordinate system used by [RenderBox].
///
/// This function relies on [child
MainAxis
Position] to determine the position of
/// This function relies on [childPosition] to determine the position of
/// child in question.
///
/// Calling this for a child that is not visible is not valid.
@protected
bool
hitTestBoxChild
(
HitTestResult
result
,
RenderBox
child
,
{
@required
double
mainAxisPosition
,
@required
double
crossAxisPosition
})
{
final
bool
rightWayUp
=
_getRightWayUp
(
constraints
);
double
absolutePosition
=
mainAxisPosition
-
childMainAxisPosition
(
child
);
final
double
absoluteCrossAxisPosition
=
crossAxisPosition
-
childCrossAxisPosition
(
child
);
double
absolutePosition
=
mainAxisPosition
-
childPosition
(
child
);
assert
(
constraints
.
axis
!=
null
);
switch
(
constraints
.
axis
)
{
case
Axis
.
horizontal
:
if
(!
rightWayUp
)
absolutePosition
=
child
.
size
.
width
-
absolutePosition
;
return
child
.
hitTest
(
result
,
position:
new
Point
(
absolutePosition
,
absoluteC
rossAxisPosition
));
return
child
.
hitTest
(
result
,
position:
new
Point
(
absolutePosition
,
c
rossAxisPosition
));
case
Axis
.
vertical
:
if
(!
rightWayUp
)
absolutePosition
=
child
.
size
.
height
-
absolutePosition
;
return
child
.
hitTest
(
result
,
position:
new
Point
(
absoluteC
rossAxisPosition
,
absolutePosition
));
return
child
.
hitTest
(
result
,
position:
new
Point
(
c
rossAxisPosition
,
absolutePosition
));
}
return
false
;
}
...
...
@@ -1029,27 +1023,25 @@ abstract class RenderSliverHelpers implements RenderSliver {
/// Utility function for [applyPaintTransform] for use when the children are
/// [RenderBox] widgets.
///
/// This function turns the value returned by [childMainAxisPosition] and
/// [childCrossAxisPosition]for the child in question into a translation that
/// it then applies to the given matrix.
/// This function turns the value returned by [childPosition] for the child in
/// question into a translation that it then applies to the given matrix.
///
/// Calling this for a child that is not visible is not valid.
@protected
void
applyPaintTransformForBoxChild
(
RenderBox
child
,
Matrix4
transform
)
{
final
bool
rightWayUp
=
_getRightWayUp
(
constraints
);
double
delta
=
childMainAxisPosition
(
child
);
final
double
crossAxisDelta
=
childCrossAxisPosition
(
child
);
double
delta
=
childPosition
(
child
);
assert
(
constraints
.
axis
!=
null
);
switch
(
constraints
.
axis
)
{
case
Axis
.
horizontal
:
if
(!
rightWayUp
)
delta
=
geometry
.
paintExtent
-
child
.
size
.
width
-
delta
;
transform
.
translate
(
delta
,
crossAxisDelta
);
transform
.
translate
(
delta
,
0.0
);
break
;
case
Axis
.
vertical
:
if
(!
rightWayUp
)
delta
=
geometry
.
paintExtent
-
child
.
size
.
height
-
delta
;
transform
.
translate
(
crossAxisDelta
,
delta
);
transform
.
translate
(
0.0
,
delta
);
break
;
}
}
...
...
@@ -1846,7 +1838,7 @@ class RenderSliverToBoxAdapter extends RenderSliver with RenderObjectWithChildMi
}
@override
double
child
MainAxis
Position
(
RenderBox
child
)
{
double
childPosition
(
RenderBox
child
)
{
return
-
constraints
.
scrollOffset
;
}
...
...
packages/flutter/lib/src/rendering/sliver_app_bar.dart
View file @
32784d35
...
...
@@ -132,7 +132,7 @@ abstract class RenderSliverAppBar extends RenderSliver with RenderObjectWithChil
///
/// If there is no child, this should return 0.0.
@override
double
child
MainAxisPosition
(
@checked
RenderObject
child
)
=>
super
.
childMainAxis
Position
(
child
);
double
child
Position
(
@checked
RenderObject
child
)
=>
super
.
child
Position
(
child
);
@override
bool
hitTestChildren
(
HitTestResult
result
,
{
@required
double
mainAxisPosition
,
@required
double
crossAxisPosition
})
{
...
...
@@ -155,16 +155,16 @@ abstract class RenderSliverAppBar extends RenderSliver with RenderObjectWithChil
assert
(
constraints
.
axisDirection
!=
null
);
switch
(
applyGrowthDirectionToAxisDirection
(
constraints
.
axisDirection
,
constraints
.
growthDirection
))
{
case
AxisDirection
.
up
:
offset
+=
new
Offset
(
0.0
,
geometry
.
paintExtent
-
child
MainAxis
Position
(
child
)
-
childExtent
);
offset
+=
new
Offset
(
0.0
,
geometry
.
paintExtent
-
childPosition
(
child
)
-
childExtent
);
break
;
case
AxisDirection
.
down
:
offset
+=
new
Offset
(
0.0
,
child
MainAxis
Position
(
child
));
offset
+=
new
Offset
(
0.0
,
childPosition
(
child
));
break
;
case
AxisDirection
.
left
:
offset
+=
new
Offset
(
geometry
.
paintExtent
-
child
MainAxis
Position
(
child
)
-
childExtent
,
0.0
);
offset
+=
new
Offset
(
geometry
.
paintExtent
-
childPosition
(
child
)
-
childExtent
,
0.0
);
break
;
case
AxisDirection
.
right
:
offset
+=
new
Offset
(
child
MainAxis
Position
(
child
),
0.0
);
offset
+=
new
Offset
(
childPosition
(
child
),
0.0
);
break
;
}
context
.
paintChild
(
child
,
offset
);
...
...
@@ -180,7 +180,7 @@ abstract class RenderSliverAppBar extends RenderSliver with RenderObjectWithChil
description
.
add
(
'maxExtent: EXCEPTION (
${e.runtimeType}
) WHILE COMPUTING MAX EXTENT'
);
}
try
{
description
.
add
(
'child position:
${child
MainAxis
Position(child).toStringAsFixed(1)}
'
);
description
.
add
(
'child position:
${childPosition(child).toStringAsFixed(1)}
'
);
}
catch
(
e
)
{
description
.
add
(
'child position: EXCEPTION (
${e.runtimeType}
) WHILE COMPUTING CHILD POSITION'
);
}
...
...
@@ -216,7 +216,7 @@ abstract class RenderSliverScrollingAppBar extends RenderSliverAppBar {
}
@override
double
child
MainAxis
Position
(
RenderBox
child
)
{
double
childPosition
(
RenderBox
child
)
{
assert
(
child
==
this
.
child
);
return
_childPosition
;
}
...
...
@@ -246,7 +246,7 @@ abstract class RenderSliverPinnedAppBar extends RenderSliverAppBar {
}
@override
double
child
MainAxis
Position
(
RenderBox
child
)
{
double
childPosition
(
RenderBox
child
)
{
assert
(
child
==
this
.
child
);
return
constraints
?.
overlap
;
}
...
...
@@ -298,7 +298,7 @@ abstract class RenderSliverFloatingAppBar extends RenderSliverAppBar {
}
@override
double
child
MainAxis
Position
(
RenderBox
child
)
{
double
childPosition
(
RenderBox
child
)
{
assert
(
child
==
this
.
child
);
return
_childPosition
;
}
...
...
packages/flutter/lib/src/rendering/sliver_block.dart
View file @
32784d35
...
...
@@ -184,18 +184,17 @@ class RenderSliverBlock extends RenderSliverMultiBoxAdaptor {
collectGarbage
(
leadingGarbage
,
trailingGarbage
);
assert
(
debugAssertChildListIsNonEmptyAndContiguous
());
double
estimated
MaxScrollOffse
t
;
double
estimated
TotalExten
t
;
if
(
reachedEnd
)
{
estimated
MaxScrollOffse
t
=
endScrollOffset
;
estimated
TotalExten
t
=
endScrollOffset
;
}
else
{
estimatedMaxScrollOffset
=
childManager
.
estimateMaxScrollOffset
(
constraints
,
estimatedTotalExtent
=
childManager
.
estimateScrollOffsetExtent
(
firstIndex:
indexOf
(
firstChild
),
lastIndex:
indexOf
(
lastChild
),
leadingScrollOffset:
offsetOf
(
firstChild
),
trailingScrollOffset:
endScrollOffset
,
);
assert
(
estimated
MaxScrollOffse
t
>=
endScrollOffset
-
offsetOf
(
firstChild
));
assert
(
estimated
TotalExten
t
>=
endScrollOffset
-
offsetOf
(
firstChild
));
}
final
double
paintedExtent
=
calculatePaintOffset
(
constraints
,
...
...
@@ -203,9 +202,9 @@ class RenderSliverBlock extends RenderSliverMultiBoxAdaptor {
to:
endScrollOffset
,
);
geometry
=
new
SliverGeometry
(
scrollExtent:
estimated
MaxScrollOffse
t
,
scrollExtent:
estimated
TotalExten
t
,
paintExtent:
paintedExtent
,
maxPaintExtent:
estimated
MaxScrollOffse
t
,
maxPaintExtent:
estimated
TotalExten
t
,
// Conservative to avoid flickering away the clip during scroll.
hasVisualOverflow:
endScrollOffset
>
targetEndScrollOffset
||
constraints
.
scrollOffset
>
0.0
,
);
...
...
packages/flutter/lib/src/rendering/sliver_grid.dart
deleted
100644 → 0
View file @
a0f0c42f
// Copyright 2017 The Chromium 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
'dart:math'
as
math
;
import
'package:meta/meta.dart'
;
import
'box.dart'
;
import
'object.dart'
;
import
'sliver.dart'
;
import
'sliver_multi_box_adaptor.dart'
;
/// Describes the placement of a child in a [RenderSliverGrid].
///
/// See also:
///
/// * [SliverGridDelegate.getGeometryForChildIndex], which returns this object
/// to describe the child's placement.
/// * [RenderSliverGrid], which uses this class during its
/// [RenderSliverGrid.performLayout] method.
class
SliverGridGeometry
{
/// Creates an object that describes the placement of a child in a [RenderSliverGrid].
const
SliverGridGeometry
({
this
.
scrollOffset
,
this
.
crossAxisOffset
,
this
.
mainAxisExtent
,
this
.
crossAxisExtent
,
});
/// The scroll offset of the leading edge of the child relative to the leading
/// edge of the parent.
final
double
scrollOffset
;
/// The offset of the child in the non-scrolling axis.
///
/// If the scroll axis is vertical, this offset is from the left-most edge of
/// the parent to the left-most edge of the child. If the scroll axis is
/// horizontal, this offset is from the top-most edge of the parent to the
/// top-most edge of the child.
final
double
crossAxisOffset
;
/// The extent of the child in the scrolling axis.
///
/// If the scroll axis is vertical, this extent is the child's height. If the
/// scroll axis is horizontal, this extent is the child's width.
final
double
mainAxisExtent
;
/// The extent of the child in the non-scrolling axis.
///
/// If the scroll axis is vertical, this extent is the child's width. If the
/// scroll axis is horizontal, this extent is the child's height.
final
double
crossAxisExtent
;
/// Returns a tight [BoxConstraints] that forces the child to have the
/// required size.
BoxConstraints
getBoxConstraints
(
SliverConstraints
constraints
)
{
return
constraints
.
asBoxConstraints
(
minExtent:
mainAxisExtent
,
maxExtent:
mainAxisExtent
,
crossAxisExtent:
crossAxisExtent
,
);
}
}
class
SliverGridParentData
extends
SliverMultiBoxAdaptorParentData
{
double
crossAxisOffset
;
@override
String
toString
()
=>
'crossAxisOffset=
$crossAxisOffset
;
${super.toString()}
'
;
}
abstract
class
SliverGridDelegate
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const
SliverGridDelegate
();
int
getMinChildIndexForScrollOffset
(
SliverConstraints
constraints
,
double
scrollOffset
);
int
getMaxChildIndexForScrollOffset
(
SliverConstraints
constraints
,
double
scrollOffset
);
SliverGridGeometry
getGeometryForChildIndex
(
SliverConstraints
constraints
,
int
index
);
double
estimateMaxScrollOffset
(
SliverConstraints
constraints
,
int
childCount
);
bool
shouldRelayout
(
@checked
SliverGridDelegate
oldDelegate
);
}
class
SliverGridDelegateWithFixedCrossAxisCount
extends
SliverGridDelegate
{
const
SliverGridDelegateWithFixedCrossAxisCount
({
@required
this
.
crossAxisCount
,
this
.
mainAxisSpacing
:
0.0
,
this
.
crossAxisSpacing
:
0.0
,
this
.
childAspectRatio
:
1.0
,
});
/// The number of children in the cross axis.
final
int
crossAxisCount
;
/// The number of logical pixels between each child along the main axis.
final
double
mainAxisSpacing
;
/// The number of logical pixels between each child along the cross axis.
final
double
crossAxisSpacing
;
/// The ratio of the cross-axis to the main-axis extent of each child.
final
double
childAspectRatio
;
bool
_debugAssertIsValid
()
{
assert
(
crossAxisCount
>
0
);
assert
(
mainAxisSpacing
>=
0.0
);
assert
(
crossAxisSpacing
>=
0.0
);
assert
(
childAspectRatio
>
0.0
);
return
true
;
}
double
_getMainAxisStride
(
double
crossAxisExtent
)
{
final
double
usableCrossAxisExtent
=
crossAxisExtent
-
crossAxisSpacing
*
(
crossAxisCount
-
1
);
final
double
childCrossAxisExtent
=
usableCrossAxisExtent
/
crossAxisCount
;
final
double
childMainAxisExtent
=
childCrossAxisExtent
/
childAspectRatio
;
return
childMainAxisExtent
+
mainAxisSpacing
;
}
@override
int
getMinChildIndexForScrollOffset
(
SliverConstraints
constraints
,
double
scrollOffset
)
{
assert
(
_debugAssertIsValid
());
return
crossAxisCount
*
(
scrollOffset
~/
_getMainAxisStride
(
constraints
.
crossAxisExtent
));
}
@override
int
getMaxChildIndexForScrollOffset
(
SliverConstraints
constraints
,
double
scrollOffset
)
{
assert
(
_debugAssertIsValid
());
final
int
mainAxisCount
=
(
scrollOffset
/
_getMainAxisStride
(
constraints
.
crossAxisExtent
)).
ceil
();
return
math
.
max
(
0
,
crossAxisCount
*
mainAxisCount
-
1
);
}
@override
SliverGridGeometry
getGeometryForChildIndex
(
SliverConstraints
constraints
,
int
index
)
{
final
double
usableCrossAxisExtent
=
constraints
.
crossAxisExtent
-
crossAxisSpacing
*
(
crossAxisCount
-
1
);
final
double
childCrossAxisExtent
=
usableCrossAxisExtent
/
crossAxisCount
;
final
double
childMainAxisExtent
=
childCrossAxisExtent
/
childAspectRatio
;
final
double
mainAxisStride
=
childMainAxisExtent
+
mainAxisSpacing
;
final
double
crossAxisStrid
=
childCrossAxisExtent
+
crossAxisSpacing
;
assert
(
mainAxisStride
==
_getMainAxisStride
(
constraints
.
crossAxisExtent
));
return
new
SliverGridGeometry
(
scrollOffset:
(
index
~/
crossAxisCount
)
*
mainAxisStride
,
crossAxisOffset:
(
index
%
crossAxisCount
)
*
crossAxisStrid
,
mainAxisExtent:
childMainAxisExtent
,
crossAxisExtent:
childCrossAxisExtent
,
);
}
@override
double
estimateMaxScrollOffset
(
SliverConstraints
constraints
,
int
childCount
)
{
if
(
childCount
==
null
)
return
null
;
final
int
mainAxisCount
=
((
childCount
-
1
)
/
crossAxisCount
).
floor
()
+
1
;
return
_getMainAxisStride
(
constraints
.
crossAxisExtent
)
*
mainAxisCount
-
mainAxisSpacing
;
}
@override
bool
shouldRelayout
(
SliverGridDelegateWithFixedCrossAxisCount
oldDelegate
)
{
return
oldDelegate
.
crossAxisCount
!=
crossAxisCount
||
oldDelegate
.
mainAxisSpacing
!=
mainAxisSpacing
||
oldDelegate
.
crossAxisSpacing
!=
crossAxisSpacing
||
oldDelegate
.
childAspectRatio
!=
childAspectRatio
;
}
}
/// A [GridDelegate] that fills the width with a variable number of tiles.
///
/// This delegate will select a tile width that is as large as possible subject
/// to the following conditions:
///
/// - The tile width evenly divides the width of the grid.
/// - The tile width is at most [maxTileWidth].
class
SliverGridDelegateWithMaxCrossAxisExtent
extends
SliverGridDelegate
{
/// Creates a grid delegate that uses a max tile width.
///
/// The [maxTileWidth] argument must not be null.
const
SliverGridDelegateWithMaxCrossAxisExtent
({
@required
this
.
maxCrossAxisExtent
,
this
.
mainAxisSpacing
:
0.0
,
this
.
crossAxisSpacing
:
0.0
,
this
.
childAspectRatio
:
1.0
,
});
/// The number of children in the cross axis.
final
double
maxCrossAxisExtent
;
/// The number of logical pixels between each child along the main axis.
final
double
mainAxisSpacing
;
/// The number of logical pixels between each child along the cross axis.
final
double
crossAxisSpacing
;
/// The ratio of the cross-axis to the main-axis extent of each child.
final
double
childAspectRatio
;
bool
_debugAssertIsValid
()
{
assert
(
maxCrossAxisExtent
>
0.0
);
assert
(
mainAxisSpacing
>=
0.0
);
assert
(
crossAxisSpacing
>=
0.0
);
assert
(
childAspectRatio
>
0.0
);
return
true
;
}
int
_getCrossAxisCount
(
double
crossAxisExtent
)
{
return
(
crossAxisExtent
/
(
maxCrossAxisExtent
+
crossAxisSpacing
)).
ceil
();
}
double
_getMainAxisStride
(
double
crossAxisExtent
,
int
crossAxisCount
)
{
final
double
usableCrossAxisExtent
=
crossAxisExtent
-
crossAxisSpacing
*
(
crossAxisCount
-
1
);
final
double
childCrossAxisExtent
=
usableCrossAxisExtent
/
crossAxisCount
;
final
double
childMainAxisExtent
=
childCrossAxisExtent
/
childAspectRatio
;
return
childMainAxisExtent
+
mainAxisSpacing
;
}
@override
int
getMinChildIndexForScrollOffset
(
SliverConstraints
constraints
,
double
scrollOffset
)
{
assert
(
_debugAssertIsValid
());
final
double
crossAxisExtent
=
constraints
.
crossAxisExtent
;
final
int
crossAxisCount
=
_getCrossAxisCount
(
crossAxisExtent
);
return
crossAxisCount
*
(
scrollOffset
~/
_getMainAxisStride
(
crossAxisExtent
,
crossAxisCount
));
}
@override
int
getMaxChildIndexForScrollOffset
(
SliverConstraints
constraints
,
double
scrollOffset
)
{
assert
(
_debugAssertIsValid
());
final
double
crossAxisExtent
=
constraints
.
crossAxisExtent
;
final
int
crossAxisCount
=
_getCrossAxisCount
(
crossAxisExtent
);
final
int
mainAxisCount
=
(
scrollOffset
/
_getMainAxisStride
(
crossAxisExtent
,
crossAxisCount
)).
ceil
();
return
math
.
max
(
0
,
crossAxisCount
*
mainAxisCount
-
1
);
}
@override
SliverGridGeometry
getGeometryForChildIndex
(
SliverConstraints
constraints
,
int
index
)
{
final
int
crossAxisCount
=
_getCrossAxisCount
(
constraints
.
crossAxisExtent
);
final
double
usableCrossAxisExtent
=
constraints
.
crossAxisExtent
-
crossAxisSpacing
*
(
crossAxisCount
-
1
);
final
double
childCrossAxisExtent
=
usableCrossAxisExtent
/
crossAxisCount
;
final
double
childMainAxisExtent
=
childCrossAxisExtent
/
childAspectRatio
;
final
double
mainAxisStride
=
childMainAxisExtent
+
mainAxisSpacing
;
final
double
crossAxisStrid
=
childCrossAxisExtent
+
crossAxisSpacing
;
assert
(
mainAxisStride
==
_getMainAxisStride
(
constraints
.
crossAxisExtent
,
crossAxisCount
));
return
new
SliverGridGeometry
(
scrollOffset:
(
index
~/
crossAxisCount
)
*
mainAxisStride
,
crossAxisOffset:
(
index
%
crossAxisCount
)
*
crossAxisStrid
,
mainAxisExtent:
childMainAxisExtent
,
crossAxisExtent:
childCrossAxisExtent
,
);
}
@override
double
estimateMaxScrollOffset
(
SliverConstraints
constraints
,
int
childCount
)
{
if
(
childCount
==
null
)
return
null
;
final
double
crossAxisExtent
=
constraints
.
crossAxisExtent
;
final
int
crossAxisCount
=
_getCrossAxisCount
(
crossAxisExtent
);
final
int
mainAxisCount
=
((
childCount
-
1
)
/
crossAxisCount
).
floor
()
+
1
;
return
_getMainAxisStride
(
crossAxisExtent
,
crossAxisCount
)
*
mainAxisCount
-
mainAxisSpacing
;
}
@override
bool
shouldRelayout
(
SliverGridDelegateWithMaxCrossAxisExtent
oldDelegate
)
{
return
oldDelegate
.
maxCrossAxisExtent
!=
maxCrossAxisExtent
||
oldDelegate
.
mainAxisSpacing
!=
mainAxisSpacing
||
oldDelegate
.
crossAxisSpacing
!=
crossAxisSpacing
||
oldDelegate
.
childAspectRatio
!=
childAspectRatio
;
}
}
class
RenderSliverGrid
extends
RenderSliverMultiBoxAdaptor
{
RenderSliverGrid
({
@required
RenderSliverBoxChildManager
childManager
,
@required
SliverGridDelegate
gridDelegate
,
})
:
_gridDelegate
=
gridDelegate
,
super
(
childManager:
childManager
)
{
gridDelegate
!=
null
;
}
@override
void
setupParentData
(
RenderObject
child
)
{
if
(
child
.
parentData
is
!
SliverGridParentData
)
child
.
parentData
=
new
SliverGridParentData
();
}
SliverGridDelegate
get
gridDelegate
=>
_gridDelegate
;
SliverGridDelegate
_gridDelegate
;
set
gridDelegate
(
SliverGridDelegate
newDelegate
)
{
assert
(
newDelegate
!=
null
);
if
(
_gridDelegate
==
newDelegate
)
return
;
if
(
newDelegate
.
runtimeType
!=
_gridDelegate
.
runtimeType
||
newDelegate
.
shouldRelayout
(
_gridDelegate
))
markNeedsLayout
();
_gridDelegate
=
newDelegate
;
}
@override
double
childCrossAxisPosition
(
RenderBox
child
)
{
final
SliverGridParentData
childParentData
=
child
.
parentData
;
return
childParentData
.
crossAxisOffset
;
}
@override
void
performLayout
()
{
assert
(
childManager
.
debugAssertChildListLocked
());
final
double
scrollOffset
=
constraints
.
scrollOffset
;
assert
(
scrollOffset
>=
0.0
);
final
double
remainingPaintExtent
=
constraints
.
remainingPaintExtent
;
assert
(
remainingPaintExtent
>=
0.0
);
final
double
targetEndScrollOffset
=
scrollOffset
+
remainingPaintExtent
;
final
int
firstIndex
=
_gridDelegate
.
getMinChildIndexForScrollOffset
(
constraints
,
scrollOffset
);
final
int
targetLastIndex
=
_gridDelegate
.
getMaxChildIndexForScrollOffset
(
constraints
,
targetEndScrollOffset
);
if
(
firstChild
!=
null
)
{
final
int
oldFirstIndex
=
indexOf
(
firstChild
);
final
int
oldLastIndex
=
indexOf
(
lastChild
);
final
int
leadingGarbage
=
(
firstIndex
-
oldFirstIndex
).
clamp
(
0
,
childCount
);
final
int
trailingGarbage
=
(
oldLastIndex
-
targetLastIndex
).
clamp
(
0
,
childCount
);
if
(
leadingGarbage
+
trailingGarbage
>
0
)
collectGarbage
(
leadingGarbage
,
trailingGarbage
);
}
final
SliverGridGeometry
firstChildGridGeometry
=
_gridDelegate
.
getGeometryForChildIndex
(
constraints
,
firstIndex
);
double
leadingScrollOffset
=
firstChildGridGeometry
.
scrollOffset
;
double
trailingScrollOffset
=
firstChildGridGeometry
.
scrollOffset
;
if
(
firstChild
==
null
)
{
if
(!
addInitialChild
(
index:
firstIndex
,
scrollOffset:
firstChildGridGeometry
.
scrollOffset
))
{
// There are no children.
geometry
=
SliverGeometry
.
zero
;
return
;
}
}
RenderBox
trailingChildWithLayout
;
for
(
int
index
=
indexOf
(
firstChild
)
-
1
;
index
>=
firstIndex
;
--
index
)
{
final
SliverGridGeometry
gridGeometry
=
_gridDelegate
.
getGeometryForChildIndex
(
constraints
,
index
);
final
RenderBox
child
=
insertAndLayoutLeadingChild
(
gridGeometry
.
getBoxConstraints
(
constraints
));
final
SliverGridParentData
childParentData
=
child
.
parentData
;
childParentData
.
scrollOffset
=
gridGeometry
.
scrollOffset
;
childParentData
.
crossAxisOffset
=
gridGeometry
.
crossAxisOffset
;
assert
(
childParentData
.
index
==
index
);
trailingChildWithLayout
??=
child
;
if
(
gridGeometry
.
scrollOffset
>
trailingScrollOffset
)
trailingScrollOffset
=
gridGeometry
.
scrollOffset
;
}
assert
(
offsetOf
(
firstChild
)
<=
scrollOffset
);
if
(
trailingChildWithLayout
==
null
)
{
firstChild
.
layout
(
firstChildGridGeometry
.
getBoxConstraints
(
constraints
));
final
SliverGridParentData
childParentData
=
firstChild
.
parentData
;
childParentData
.
crossAxisOffset
=
firstChildGridGeometry
.
crossAxisOffset
;
assert
(
childParentData
.
scrollOffset
==
firstChildGridGeometry
.
scrollOffset
);
trailingChildWithLayout
=
firstChild
;
}
for
(
int
index
=
indexOf
(
trailingChildWithLayout
)
+
1
;
index
<=
targetLastIndex
;
++
index
)
{
final
SliverGridGeometry
gridGeometry
=
_gridDelegate
.
getGeometryForChildIndex
(
constraints
,
index
);
final
BoxConstraints
childConstraints
=
gridGeometry
.
getBoxConstraints
(
constraints
);
RenderBox
child
=
childAfter
(
trailingChildWithLayout
);
if
(
child
==
null
)
{
child
=
insertAndLayoutChild
(
childConstraints
,
after:
trailingChildWithLayout
);
if
(
child
==
null
)
{
// We have run out of children.
break
;
}
}
else
{
child
.
layout
(
childConstraints
);
}
trailingChildWithLayout
=
child
;
assert
(
child
!=
null
);
final
SliverGridParentData
childParentData
=
child
.
parentData
;
childParentData
.
scrollOffset
=
gridGeometry
.
scrollOffset
;
childParentData
.
crossAxisOffset
=
gridGeometry
.
crossAxisOffset
;
assert
(
childParentData
.
index
==
index
);
if
(
gridGeometry
.
scrollOffset
>
trailingScrollOffset
)
trailingScrollOffset
=
gridGeometry
.
scrollOffset
;
}
final
int
lastIndex
=
indexOf
(
lastChild
);
assert
(
debugAssertChildListIsNonEmptyAndContiguous
());
assert
(
indexOf
(
firstChild
)
==
firstIndex
);
assert
(
lastIndex
<=
targetLastIndex
);
final
double
estimatedTotalExtent
=
childManager
.
estimateMaxScrollOffset
(
constraints
,
firstIndex:
firstIndex
,
lastIndex:
lastIndex
,
leadingScrollOffset:
leadingScrollOffset
,
trailingScrollOffset:
trailingScrollOffset
,
);
final
double
paintedExtent
=
calculatePaintOffset
(
constraints
,
from:
leadingScrollOffset
,
to:
trailingScrollOffset
,
);
geometry
=
new
SliverGeometry
(
scrollExtent:
estimatedTotalExtent
,
paintExtent:
paintedExtent
,
maxPaintExtent:
estimatedTotalExtent
,
// Conservative to avoid complexity.
hasVisualOverflow:
true
,
);
assert
(
childManager
.
debugAssertChildListLocked
());
}
}
packages/flutter/lib/src/rendering/sliver_list.dart
View file @
32784d35
...
...
@@ -14,9 +14,7 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor {
RenderSliverList
({
@required
RenderSliverBoxChildManager
childManager
,
double
itemExtent
,
})
:
_itemExtent
=
itemExtent
,
super
(
childManager:
childManager
)
{
assert
(
itemExtent
!=
null
);
}
})
:
_itemExtent
=
itemExtent
,
super
(
childManager:
childManager
);
/// The main-axis extent of each item in the list.
double
get
itemExtent
=>
_itemExtent
;
...
...
@@ -107,8 +105,7 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor {
assert
(
indexOf
(
firstChild
)
==
firstIndex
);
assert
(
lastIndex
<=
targetLastIndex
);
final
double
estimatedMaxScrollOffset
=
childManager
.
estimateMaxScrollOffset
(
constraints
,
final
double
estimatedTotalExtent
=
childManager
.
estimateScrollOffsetExtent
(
firstIndex:
firstIndex
,
lastIndex:
lastIndex
,
leadingScrollOffset:
leadingScrollOffset
,
...
...
@@ -122,9 +119,9 @@ class RenderSliverList extends RenderSliverMultiBoxAdaptor {
);
geometry
=
new
SliverGeometry
(
scrollExtent:
estimated
MaxScrollOffse
t
,
scrollExtent:
estimated
TotalExten
t
,
paintExtent:
paintedExtent
,
maxPaintExtent:
estimated
MaxScrollOffse
t
,
maxPaintExtent:
estimated
TotalExten
t
,
// Conservative to avoid flickering away the clip during scroll.
hasVisualOverflow:
lastIndex
>=
targetLastIndex
||
constraints
.
scrollOffset
>
0.0
,
);
...
...
packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart
View file @
32784d35
...
...
@@ -61,7 +61,7 @@ abstract class RenderSliverBoxChildManager {
/// Must return the total distance from the start of the child with the
/// earliest possible index to the end of the child with the last possible
/// index.
double
estimate
MaxScrollOffset
(
SliverConstraints
constraints
,
{
double
estimate
ScrollOffsetExtent
(
{
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
...
...
@@ -304,7 +304,7 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
}
@override
double
child
MainAxis
Position
(
RenderBox
child
)
{
double
childPosition
(
RenderBox
child
)
{
return
offsetOf
(
child
)
-
constraints
.
scrollOffset
;
}
...
...
@@ -319,46 +319,37 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
return
;
// offset is to the top-left corner, regardless of our axis direction.
// originOffset gives us the delta from the real origin to the origin in the axis direction.
Offset
mainAxisUnit
,
crossAxisUni
t
,
originOffset
;
Offset
unitOffse
t
,
originOffset
;
bool
addExtent
;
switch
(
applyGrowthDirectionToAxisDirection
(
constraints
.
axisDirection
,
constraints
.
growthDirection
))
{
case
AxisDirection
.
up
:
mainAxisUnit
=
const
Offset
(
0.0
,
-
1.0
);
crossAxisUnit
=
const
Offset
(
1.0
,
0.0
);
unitOffset
=
const
Offset
(
0.0
,
-
1.0
);
originOffset
=
offset
+
new
Offset
(
0.0
,
geometry
.
paintExtent
);
addExtent
=
true
;
break
;
case
AxisDirection
.
right
:
mainAxisUnit
=
const
Offset
(
1.0
,
0.0
);
crossAxisUnit
=
const
Offset
(
0.0
,
1.0
);
unitOffset
=
const
Offset
(
1.0
,
0.0
);
originOffset
=
offset
;
addExtent
=
false
;
break
;
case
AxisDirection
.
down
:
mainAxisUnit
=
const
Offset
(
0.0
,
1.0
);
crossAxisUnit
=
const
Offset
(
1.0
,
0.0
);
unitOffset
=
const
Offset
(
0.0
,
1.0
);
originOffset
=
offset
;
addExtent
=
false
;
break
;
case
AxisDirection
.
left
:
mainAxisUnit
=
const
Offset
(-
1.0
,
0.0
);
crossAxisUnit
=
const
Offset
(
0.0
,
1.0
);
unitOffset
=
const
Offset
(-
1.0
,
0.0
);
originOffset
=
offset
+
new
Offset
(
geometry
.
paintExtent
,
0.0
);
addExtent
=
true
;
break
;
}
assert
(
mainAxisUni
t
!=
null
);
assert
(
unitOffse
t
!=
null
);
assert
(
addExtent
!=
null
);
RenderBox
child
=
firstChild
;
while
(
child
!=
null
)
{
final
double
mainAxisDelta
=
childMainAxisPosition
(
child
);
final
double
crossAxisDelta
=
childCrossAxisPosition
(
child
);
Offset
childOffset
=
new
Offset
(
originOffset
.
dx
+
mainAxisUnit
.
dx
*
mainAxisDelta
+
crossAxisUnit
.
dx
*
crossAxisDelta
,
originOffset
.
dy
+
mainAxisUnit
.
dy
*
mainAxisDelta
+
crossAxisUnit
.
dy
*
crossAxisDelta
,
);
Offset
childOffset
=
originOffset
+
unitOffset
*
childPosition
(
child
);
if
(
addExtent
)
childOffset
+=
mainAxisUni
t
*
paintExtentOf
(
child
);
childOffset
+=
unitOffse
t
*
paintExtentOf
(
child
);
context
.
paintChild
(
child
,
childOffset
);
child
=
childAfter
(
child
);
}
...
...
packages/flutter/lib/src/rendering/sliver_padding.dart
View file @
32784d35
...
...
@@ -262,24 +262,17 @@ class RenderSliverPadding extends RenderSliver with RenderObjectWithChildMixin<R
@override
bool
hitTestChildren
(
HitTestResult
result
,
{
@required
double
mainAxisPosition
,
@required
double
crossAxisPosition
})
{
if
(
child
.
geometry
.
hitTestExtent
>
0.0
)
return
child
.
hitTest
(
result
,
mainAxisPosition:
mainAxisPosition
-
child
MainAxisPosition
(
child
),
crossAxisPosition:
crossAxisPosition
-
childCrossAxisPosition
(
child
)
);
return
child
.
hitTest
(
result
,
mainAxisPosition:
mainAxisPosition
-
child
Position
(
child
),
crossAxisPosition:
crossAxisPosition
-
startPadding
);
return
false
;
}
@override
double
child
MainAxis
Position
(
RenderSliver
child
)
{
double
childPosition
(
RenderSliver
child
)
{
assert
(
child
!=
null
);
assert
(
child
==
this
.
child
);
return
calculatePaintOffset
(
constraints
,
from:
0.0
,
to:
beforePadding
);
}
@override
double
childCrossAxisPosition
(
RenderSliver
child
)
{
assert
(
child
!=
null
);
assert
(
child
==
this
.
child
);
return
startPadding
;
}
@override
void
applyPaintTransform
(
RenderObject
child
,
Matrix4
transform
)
{
assert
(
child
!=
null
);
...
...
packages/flutter/lib/src/widgets/scroll_view.dart
View file @
32784d35
...
...
@@ -3,31 +3,21 @@
// found in the LICENSE file.
import
'package:flutter/rendering.dart'
;
import
'package:meta/meta.dart'
;
import
'framework.dart'
;
import
'basic.dart'
;
import
'scrollable.dart'
;
import
'sliver.dart'
;
AxisDirection
_getDirection
(
BuildContext
context
,
Axis
scrollDirection
)
{
// TODO(abarth): Consider reading direction.
switch
(
scrollDirection
)
{
case
Axis
.
horizontal
:
return
AxisDirection
.
right
;
case
Axis
.
vertical
:
return
AxisDirection
.
down
;
}
return
null
;
}
class
ScrollView
extends
StatelessWidget
{
ScrollView
({
Key
key
,
this
.
padding
,
this
.
scrollDirection
:
Axis
.
vertical
,
this
.
anchor
:
0.0
,
this
.
initialScrollOffset
:
0.0
,
this
.
itemExtent
,
this
.
center
,
this
.
children
,
})
:
super
(
key:
key
);
...
...
@@ -35,109 +25,50 @@ class ScrollView extends StatelessWidget {
final
Axis
scrollDirection
;
final
double
anchor
;
final
double
initialScrollOffset
;
final
double
itemExtent
;
final
List
<
Widget
>
children
;
Widget
_buildChildLayout
()
{
final
SliverChildListDelegate
delegate
=
new
SliverChildListDelegate
(
children
);
final
Key
center
;
if
(
itemExtent
!=
null
)
{
return
new
SliverList
(
delegate:
delegate
,
itemExtent:
itemExtent
,
);
}
final
List
<
Widget
>
children
;
return
new
SliverBlock
(
delegate:
delegate
);
AxisDirection
_getDirection
(
BuildContext
context
)
{
// TODO(abarth): Consider reading direction.
switch
(
scrollDirection
)
{
case
Axis
.
horizontal
:
return
AxisDirection
.
right
;
case
Axis
.
vertical
:
return
AxisDirection
.
down
;
}
@override
Widget
build
(
BuildContext
context
)
{
Widget
sliver
=
_buildChildLayout
();
if
(
padding
!=
null
)
sliver
=
new
SliverPadding
(
padding:
padding
,
child:
sliver
);
return
new
ScrollableViewport2
(
axisDirection:
_getDirection
(
context
,
scrollDirection
),
initialScrollOffset:
initialScrollOffset
,
slivers:
<
Widget
>[
sliver
],
);
return
null
;
}
}
class
ScrollGrid
extends
StatelessWidget
{
ScrollGrid
({
Key
key
,
this
.
padding
,
this
.
scrollDirection
:
Axis
.
vertical
,
this
.
initialScrollOffset
:
0.0
,
this
.
gridDelegate
,
this
.
children
,
})
:
super
(
key:
key
);
ScrollGrid
.
count
({
Key
key
,
this
.
padding
,
this
.
scrollDirection
:
Axis
.
vertical
,
this
.
initialScrollOffset
:
0.0
,
@required
int
crossAxisCount
,
double
mainAxisSpacing:
0.0
,
double
crossAxisSpacing:
0.0
,
double
childAspectRatio:
1.0
,
this
.
children
,
})
:
gridDelegate
=
new
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
crossAxisCount
,
mainAxisSpacing:
mainAxisSpacing
,
crossAxisSpacing:
crossAxisSpacing
,
childAspectRatio:
childAspectRatio
,
),
super
(
key:
key
);
ScrollGrid
.
extent
({
Key
key
,
this
.
padding
,
this
.
scrollDirection
:
Axis
.
vertical
,
this
.
initialScrollOffset
:
0.0
,
@required
double
maxCrossAxisExtent
,
double
mainAxisSpacing:
0.0
,
double
crossAxisSpacing:
0.0
,
double
childAspectRatio:
1.0
,
this
.
children
,
})
:
gridDelegate
=
new
SliverGridDelegateWithMaxCrossAxisExtent
(
maxCrossAxisExtent:
maxCrossAxisExtent
,
mainAxisSpacing:
mainAxisSpacing
,
crossAxisSpacing:
crossAxisSpacing
,
childAspectRatio:
childAspectRatio
,
),
super
(
key:
key
);
final
EdgeInsets
padding
;
final
Axis
scrollDirection
;
final
double
initialScrollOffset
;
final
SliverGridDelegate
gridDelegate
;
final
List
<
Widget
>
children
;
@override
Widget
build
(
BuildContext
context
)
{
final
SliverChildListDelegate
delegate
=
new
SliverChildListDelegate
(
children
);
Widget
sliver
=
new
SliverGrid
(
Widget
sliver
;
if
(
itemExtent
==
null
)
{
sliver
=
new
SliverBlock
(
delegate:
delegate
);
}
else
{
sliver
=
new
SliverList
(
delegate:
delegate
,
gridDelegate:
gridDelegate
,
itemExtent:
itemExtent
,
);
}
if
(
padding
!=
null
)
sliver
=
new
SliverPadding
(
padding:
padding
,
child:
sliver
);
return
new
ScrollableViewport2
(
axisDirection:
_getDirection
(
context
,
scrollDirection
),
axisDirection:
_getDirection
(
context
),
anchor:
anchor
,
initialScrollOffset:
initialScrollOffset
,
center:
center
,
slivers:
<
Widget
>[
sliver
],
);
}
...
...
packages/flutter/lib/src/widgets/sliver.dart
View file @
32784d35
...
...
@@ -10,11 +10,6 @@ import 'package:flutter/rendering.dart';
import
'framework.dart'
;
import
'basic.dart'
;
export
'package:flutter/rendering.dart'
show
SliverGridDelegate
,
SliverGridDelegateWithFixedCrossAxisCount
,
SliverGridDelegateWithMaxCrossAxisExtent
;
abstract
class
SliverChildDelegate
{
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
...
...
@@ -22,23 +17,24 @@ abstract class SliverChildDelegate {
Widget
build
(
BuildContext
context
,
int
index
);
/// Returns an estimate of the number of children this delegate will build.
///
/// Used to estimate the maximum scroll offset if [estimateMaxScrollOffset]
/// returns null.
///
/// Return null if there are an unbounded number of children or if it would
/// be too difficult to estimate the number of children.
int
get
estimatedChildCount
=>
null
;
bool
shouldRebuild
(
@checked
SliverChildDelegate
oldDelegate
);
int
get
childCount
;
double
estimate
MaxScrollOffse
t
(
double
estimate
ScrollOffsetExten
t
(
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
double
trailingScrollOffset
,
)
=>
null
;
bool
shouldRebuild
(
@checked
SliverChildDelegate
oldDelegate
);
)
{
final
int
childCount
=
this
.
childCount
;
if
(
lastIndex
==
childCount
-
1
)
return
trailingScrollOffset
;
final
int
reifiedCount
=
lastIndex
-
firstIndex
+
1
;
final
double
averageExtent
=
(
trailingScrollOffset
-
leadingScrollOffset
)
/
reifiedCount
;
final
int
remainingCount
=
childCount
-
lastIndex
-
1
;
return
trailingScrollOffset
+
averageExtent
*
remainingCount
;
}
}
// ///
...
...
@@ -68,13 +64,13 @@ class SliverChildListDelegate extends SliverChildDelegate {
return
children
[
index
];
}
@override
int
get
estimatedChildCount
=>
children
.
length
;
@override
bool
shouldRebuild
(
@checked
SliverChildListDelegate
oldDelegate
)
{
return
children
!=
oldDelegate
.
children
;
}
@override
int
get
childCount
=>
children
.
length
;
}
abstract
class
SliverMultiBoxAdaptorWidget
extends
RenderObjectWidget
{
...
...
@@ -93,22 +89,6 @@ abstract class SliverMultiBoxAdaptorWidget extends RenderObjectWidget {
@override
RenderSliverMultiBoxAdaptor
createRenderObject
(
BuildContext
context
);
double
estimateMaxScrollOffset
(
SliverConstraints
constraints
,
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
double
trailingScrollOffset
,
)
{
assert
(
lastIndex
>=
firstIndex
);
return
delegate
.
estimateMaxScrollOffset
(
firstIndex
,
lastIndex
,
leadingScrollOffset
,
trailingScrollOffset
,
);
}
@override
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
...
...
@@ -150,44 +130,6 @@ class SliverList extends SliverMultiBoxAdaptorWidget {
}
}
class
SliverGrid
extends
SliverMultiBoxAdaptorWidget
{
SliverGrid
({
Key
key
,
@required
SliverChildDelegate
delegate
,
@required
this
.
gridDelegate
,
})
:
super
(
key:
key
,
delegate:
delegate
);
final
SliverGridDelegate
gridDelegate
;
@override
RenderSliverGrid
createRenderObject
(
BuildContext
context
)
{
final
SliverMultiBoxAdaptorElement
element
=
context
;
return
new
RenderSliverGrid
(
childManager:
element
,
gridDelegate:
gridDelegate
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
RenderSliverGrid
renderObject
)
{
renderObject
.
gridDelegate
=
gridDelegate
;
}
@override
double
estimateMaxScrollOffset
(
SliverConstraints
constraints
,
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
double
trailingScrollOffset
,
)
{
return
super
.
estimateMaxScrollOffset
(
constraints
,
firstIndex
,
lastIndex
,
leadingScrollOffset
,
trailingScrollOffset
,
)
??
gridDelegate
.
estimateMaxScrollOffset
(
constraints
,
delegate
.
estimatedChildCount
);
}
}
class
SliverMultiBoxAdaptorElement
extends
RenderObjectElement
implements
RenderSliverBoxChildManager
{
SliverMultiBoxAdaptorElement
(
SliverMultiBoxAdaptorWidget
widget
)
:
super
(
widget
);
...
...
@@ -299,41 +241,19 @@ class SliverMultiBoxAdaptorElement extends RenderObjectElement implements Render
});
}
double
_extrapolateMaxScrollOffset
(
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
double
trailingScrollOffset
,
)
{
final
int
childCount
=
widget
.
delegate
.
estimatedChildCount
;
if
(
childCount
==
null
)
return
double
.
INFINITY
;
if
(
lastIndex
==
childCount
-
1
)
return
trailingScrollOffset
;
final
int
reifiedCount
=
lastIndex
-
firstIndex
+
1
;
final
double
averageExtent
=
(
trailingScrollOffset
-
leadingScrollOffset
)
/
reifiedCount
;
final
int
remainingCount
=
childCount
-
lastIndex
-
1
;
return
trailingScrollOffset
+
averageExtent
*
remainingCount
;
}
@override
double
estimate
MaxScrollOffset
(
SliverConstraints
constraints
,
{
double
estimate
ScrollOffsetExtent
(
{
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
double
trailingScrollOffset
,
})
{
return
widget
.
estimateMaxScrollOffset
(
constraints
,
firstIndex
,
lastIndex
,
leadingScrollOffset
,
trailingScrollOffset
,
)
??
_extrapolateMaxScrollOffset
(
assert
(
lastIndex
>=
firstIndex
);
return
widget
.
delegate
.
estimateScrollOffsetExtent
(
firstIndex
,
lastIndex
,
leadingScrollOffset
,
trailingScrollOffset
,
trailingScrollOffset
);
}
...
...
packages/flutter/test/rendering/slivers_block_test.dart
View file @
32784d35
...
...
@@ -43,7 +43,7 @@ class TestRenderSliverBoxChildManager extends RenderSliverBoxChildManager {
}
@override
double
estimate
MaxScrollOffset
(
SliverConstraints
constraints
,
{
double
estimate
ScrollOffsetExtent
(
{
int
firstIndex
,
int
lastIndex
,
double
leadingScrollOffset
,
...
...
packages/flutter/test/widgets/block_test.dart
View file @
32784d35
...
...
@@ -3,7 +3,6 @@
// found in the LICENSE file.
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
final
Key
blockKey
=
new
Key
(
'test'
);
...
...
@@ -121,7 +120,7 @@ void main() {
expect
(
key
.
currentState
.
scrollOffset
,
0.0
);
});
testWidgets
(
'SliverBlockChildListDelegate.estimate
MaxScrollOffse
t hits end'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'SliverBlockChildListDelegate.estimate
ScrollOffsetExten
t hits end'
,
(
WidgetTester
tester
)
async
{
SliverChildListDelegate
delegate
=
new
SliverChildListDelegate
(<
Widget
>[
new
Container
(),
new
Container
(),
...
...
@@ -130,23 +129,6 @@ void main() {
new
Container
(),
]);
await
tester
.
pumpWidget
(
new
ScrollableViewport2
(
slivers:
<
Widget
>[
new
SliverBlock
(
delegate:
delegate
,
),
],
));
final
SliverMultiBoxAdaptorElement
element
=
tester
.
element
(
find
.
byType
(
SliverBlock
));
final
double
maxScrollOffset
=
element
.
estimateMaxScrollOffset
(
null
,
firstIndex:
3
,
lastIndex:
4
,
leadingScrollOffset:
25.0
,
trailingScrollOffset:
26.0
);
expect
(
maxScrollOffset
,
equals
(
26.0
));
expect
(
delegate
.
estimateScrollOffsetExtent
(
3
,
4
,
25.0
,
26.0
),
equals
(
26.0
));
});
}
packages/flutter/test/widgets/scroll_grid_test.dart
deleted
100644 → 0
View file @
a0f0c42f
// Copyright 2017 The Chromium 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_test/flutter_test.dart'
;
import
'package:flutter/widgets.dart'
;
import
'states.dart'
;
void
main
(
)
{
testWidgets
(
'Empty ScrollGrid'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
new
ScrollGrid
.
count
(
crossAxisCount:
4
,
children:
const
<
Widget
>[],
));
});
testWidgets
(
'ScrollGrid.count control test'
,
(
WidgetTester
tester
)
async
{
List
<
String
>
log
=
<
String
>[];
await
tester
.
pumpWidget
(
new
ScrollGrid
.
count
(
crossAxisCount:
4
,
children:
kStates
.
map
((
String
state
)
{
return
new
GestureDetector
(
onTap:
()
{
log
.
add
(
state
);
},
child:
new
Container
(
decoration:
const
BoxDecoration
(
backgroundColor:
const
Color
(
0xFF0000FF
),
),
child:
new
Text
(
state
),
),
);
}).
toList
(),
));
expect
(
tester
.
getSize
(
find
.
text
(
'Arkansas'
)),
equals
(
const
Size
(
200.0
,
200.0
)));
for
(
int
i
=
0
;
i
<
8
;
++
i
)
{
await
tester
.
tap
(
find
.
text
(
kStates
[
i
]));
expect
(
log
,
equals
(<
String
>[
kStates
[
i
]]));
log
.
clear
();
}
expect
(
find
.
text
(
kStates
[
12
]),
findsNothing
);
expect
(
find
.
text
(
'Nevada'
),
findsNothing
);
await
tester
.
scroll
(
find
.
text
(
'Arkansas'
),
const
Offset
(
0.0
,
-
200.0
));
await
tester
.
pump
();
for
(
int
i
=
0
;
i
<
4
;
++
i
)
expect
(
find
.
text
(
kStates
[
i
]),
findsNothing
);
for
(
int
i
=
4
;
i
<
12
;
++
i
)
{
await
tester
.
tap
(
find
.
text
(
kStates
[
i
]));
expect
(
log
,
equals
(<
String
>[
kStates
[
i
]]));
log
.
clear
();
}
await
tester
.
scroll
(
find
.
text
(
'Delaware'
),
const
Offset
(
0.0
,
-
4000.0
));
await
tester
.
pump
();
expect
(
find
.
text
(
'Alabama'
),
findsNothing
);
expect
(
find
.
text
(
'Pennsylvania'
),
findsNothing
);
expect
(
tester
.
getCenter
(
find
.
text
(
'Tennessee'
)),
equals
(
const
Point
(
300.0
,
100.0
)));
await
tester
.
tap
(
find
.
text
(
'Tennessee'
));
expect
(
log
,
equals
(<
String
>[
'Tennessee'
]));
log
.
clear
();
await
tester
.
scroll
(
find
.
text
(
'Tennessee'
),
const
Offset
(
0.0
,
200.0
));
await
tester
.
pump
();
await
tester
.
tap
(
find
.
text
(
'Tennessee'
));
expect
(
log
,
equals
(<
String
>[
'Tennessee'
]));
log
.
clear
();
await
tester
.
tap
(
find
.
text
(
'Pennsylvania'
));
expect
(
log
,
equals
(<
String
>[
'Pennsylvania'
]));
log
.
clear
();
});
testWidgets
(
'ScrollGrid.extent control test'
,
(
WidgetTester
tester
)
async
{
List
<
String
>
log
=
<
String
>[];
await
tester
.
pumpWidget
(
new
ScrollGrid
.
extent
(
maxCrossAxisExtent:
200.0
,
children:
kStates
.
map
((
String
state
)
{
return
new
GestureDetector
(
onTap:
()
{
log
.
add
(
state
);
},
child:
new
Container
(
decoration:
const
BoxDecoration
(
backgroundColor:
const
Color
(
0xFF0000FF
),
),
child:
new
Text
(
state
),
),
);
}).
toList
(),
));
expect
(
tester
.
getSize
(
find
.
text
(
'Arkansas'
)),
equals
(
const
Size
(
200.0
,
200.0
)));
for
(
int
i
=
0
;
i
<
8
;
++
i
)
{
await
tester
.
tap
(
find
.
text
(
kStates
[
i
]));
expect
(
log
,
equals
(<
String
>[
kStates
[
i
]]));
log
.
clear
();
}
expect
(
find
.
text
(
'Nevada'
),
findsNothing
);
await
tester
.
scroll
(
find
.
text
(
'Arkansas'
),
const
Offset
(
0.0
,
-
4000.0
));
await
tester
.
pump
();
expect
(
find
.
text
(
'Alabama'
),
findsNothing
);
expect
(
tester
.
getCenter
(
find
.
text
(
'Tennessee'
)),
equals
(
const
Point
(
300.0
,
100.0
)));
await
tester
.
tap
(
find
.
text
(
'Tennessee'
));
expect
(
log
,
equals
(<
String
>[
'Tennessee'
]));
log
.
clear
();
});
testWidgets
(
'ScrollGrid large scroll jump'
,
(
WidgetTester
tester
)
async
{
List
<
int
>
log
=
<
int
>[];
await
tester
.
pumpWidget
(
new
ScrollGrid
.
extent
(
scrollDirection:
Axis
.
horizontal
,
maxCrossAxisExtent:
200.0
,
childAspectRatio:
0.75
,
children:
new
List
<
Widget
>.
generate
(
80
,
(
int
i
)
{
return
new
Builder
(
builder:
(
BuildContext
context
)
{
log
.
add
(
i
);
return
new
Container
(
child:
new
Text
(
'
$i
'
),
);
}
);
}),
),
);
expect
(
tester
.
getSize
(
find
.
text
(
'4'
)),
equals
(
const
Size
(
200.0
/
0.75
,
200.0
)));
expect
(
log
,
equals
(<
int
>[
0
,
1
,
2
,
// col 0
3
,
4
,
5
,
// col 1
6
,
7
,
8
,
// col 2
]));
log
.
clear
();
Scrollable2State
state
=
tester
.
state
(
find
.
byType
(
Scrollable2
));
AbsoluteScrollPosition
position
=
state
.
position
;
position
.
jumpTo
(
3025.0
);
expect
(
log
,
isEmpty
);
await
tester
.
pump
();
expect
(
log
,
equals
(<
int
>[
33
,
34
,
35
,
// col 11
36
,
37
,
38
,
// col 12
39
,
40
,
41
,
// col 13
42
,
43
,
44
,
// col 14
]));
log
.
clear
();
position
.
jumpTo
(
975.0
);
expect
(
log
,
isEmpty
);
await
tester
.
pump
();
expect
(
log
,
equals
(<
int
>[
9
,
10
,
11
,
// col 3
12
,
13
,
14
,
// col 4
15
,
16
,
17
,
// col 5
18
,
19
,
20
,
// col 6
]));
log
.
clear
();
});
testWidgets
(
'ScrollGrid - change crossAxisCount'
,
(
WidgetTester
tester
)
async
{
List
<
int
>
log
=
<
int
>[];
await
tester
.
pumpWidget
(
new
ScrollGrid
(
gridDelegate:
new
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
4
,
),
children:
new
List
<
Widget
>.
generate
(
40
,
(
int
i
)
{
return
new
Builder
(
builder:
(
BuildContext
context
)
{
log
.
add
(
i
);
return
new
Container
(
child:
new
Text
(
'
$i
'
),
);
}
);
}),
),
);
expect
(
tester
.
getSize
(
find
.
text
(
'4'
)),
equals
(
const
Size
(
200.0
,
200.0
)));
expect
(
log
,
equals
(<
int
>[
0
,
1
,
2
,
3
,
// row 0
4
,
5
,
6
,
7
,
// row 1
8
,
9
,
10
,
11
,
// row 2
]));
log
.
clear
();
await
tester
.
pumpWidget
(
new
ScrollGrid
(
gridDelegate:
new
SliverGridDelegateWithFixedCrossAxisCount
(
crossAxisCount:
2
,
),
children:
new
List
<
Widget
>.
generate
(
40
,
(
int
i
)
{
return
new
Builder
(
builder:
(
BuildContext
context
)
{
log
.
add
(
i
);
return
new
Container
(
child:
new
Text
(
'
$i
'
),
);
}
);
}),
),
);
expect
(
log
,
equals
(<
int
>[
0
,
1
,
2
,
3
,
// row 0
4
,
5
,
6
,
7
,
// row 1
8
,
9
,
10
,
11
,
// row 2
]));
log
.
clear
();
expect
(
tester
.
getSize
(
find
.
text
(
'3'
)),
equals
(
const
Size
(
400.0
,
400.0
)));
expect
(
find
.
text
(
'4'
),
findsNothing
);
});
testWidgets
(
'ScrollGrid - change maxChildCrossAxisExtent'
,
(
WidgetTester
tester
)
async
{
List
<
int
>
log
=
<
int
>[];
await
tester
.
pumpWidget
(
new
ScrollGrid
(
gridDelegate:
new
SliverGridDelegateWithMaxCrossAxisExtent
(
maxCrossAxisExtent:
200.0
,
),
children:
new
List
<
Widget
>.
generate
(
40
,
(
int
i
)
{
return
new
Builder
(
builder:
(
BuildContext
context
)
{
log
.
add
(
i
);
return
new
Container
(
child:
new
Text
(
'
$i
'
),
);
}
);
}),
),
);
expect
(
tester
.
getSize
(
find
.
text
(
'4'
)),
equals
(
const
Size
(
200.0
,
200.0
)));
expect
(
log
,
equals
(<
int
>[
0
,
1
,
2
,
3
,
// row 0
4
,
5
,
6
,
7
,
// row 1
8
,
9
,
10
,
11
,
// row 2
]));
log
.
clear
();
await
tester
.
pumpWidget
(
new
ScrollGrid
(
gridDelegate:
new
SliverGridDelegateWithMaxCrossAxisExtent
(
maxCrossAxisExtent:
400.0
,
),
children:
new
List
<
Widget
>.
generate
(
40
,
(
int
i
)
{
return
new
Builder
(
builder:
(
BuildContext
context
)
{
log
.
add
(
i
);
return
new
Container
(
child:
new
Text
(
'
$i
'
),
);
}
);
}),
),
);
expect
(
log
,
equals
(<
int
>[
0
,
1
,
2
,
3
,
// row 0
4
,
5
,
6
,
7
,
// row 1
8
,
9
,
10
,
11
,
// row 2
]));
log
.
clear
();
expect
(
tester
.
getSize
(
find
.
text
(
'3'
)),
equals
(
const
Size
(
400.0
,
400.0
)));
expect
(
find
.
text
(
'4'
),
findsNothing
);
});
}
packages/flutter/test/widgets/scroll_view_test.dart
View file @
32784d35
...
...
@@ -5,14 +5,65 @@
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/widgets.dart'
;
import
'states.dart'
;
const
List
<
String
>
_kStates
=
const
<
String
>[
'Alabama'
,
'Alaska'
,
'Arizona'
,
'Arkansas'
,
'California'
,
'Colorado'
,
'Connecticut'
,
'Delaware'
,
'Florida'
,
'Georgia'
,
'Hawaii'
,
'Idaho'
,
'Illinois'
,
'Indiana'
,
'Iowa'
,
'Kansas'
,
'Kentucky'
,
'Louisiana'
,
'Maine'
,
'Maryland'
,
'Massachusetts'
,
'Michigan'
,
'Minnesota'
,
'Mississippi'
,
'Missouri'
,
'Montana'
,
'Nebraska'
,
'Nevada'
,
'New Hampshire'
,
'New Jersey'
,
'New Mexico'
,
'New York'
,
'North Carolina'
,
'North Dakota'
,
'Ohio'
,
'Oklahoma'
,
'Oregon'
,
'Pennsylvania'
,
'Rhode Island'
,
'South Carolina'
,
'South Dakota'
,
'Tennessee'
,
'Texas'
,
'Utah'
,
'Vermont'
,
'Virginia'
,
'Washington'
,
'West Virginia'
,
'Wisconsin'
,
'Wyoming'
,
];
void
main
(
)
{
testWidgets
(
'ScrollView control test'
,
(
WidgetTester
tester
)
async
{
List
<
String
>
log
=
<
String
>[];
await
tester
.
pumpWidget
(
new
ScrollView
(
children:
kStates
.
map
<
Widget
>((
String
state
)
{
children:
_
kStates
.
map
<
Widget
>((
String
state
)
{
return
new
GestureDetector
(
onTap:
()
{
log
.
add
(
state
);
...
...
@@ -48,7 +99,7 @@ void main() {
testWidgets
(
'ScrollView restart ballistic activity out of range'
,
(
WidgetTester
tester
)
async
{
Widget
buildScrollView
(
int
n
)
{
return
new
ScrollView
(
children:
kStates
.
take
(
n
).
map
<
Widget
>((
String
state
)
{
children:
_
kStates
.
take
(
n
).
map
<
Widget
>((
String
state
)
{
return
new
Container
(
height:
200.0
,
decoration:
const
BoxDecoration
(
...
...
packages/flutter/test/widgets/states.dart
deleted
100644 → 0
View file @
a0f0c42f
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const
List
<
String
>
kStates
=
const
<
String
>[
'Alabama'
,
'Alaska'
,
'Arizona'
,
'Arkansas'
,
'California'
,
'Colorado'
,
'Connecticut'
,
'Delaware'
,
'Florida'
,
'Georgia'
,
'Hawaii'
,
'Idaho'
,
'Illinois'
,
'Indiana'
,
'Iowa'
,
'Kansas'
,
'Kentucky'
,
'Louisiana'
,
'Maine'
,
'Maryland'
,
'Massachusetts'
,
'Michigan'
,
'Minnesota'
,
'Mississippi'
,
'Missouri'
,
'Montana'
,
'Nebraska'
,
'Nevada'
,
'New Hampshire'
,
'New Jersey'
,
'New Mexico'
,
'New York'
,
'North Carolina'
,
'North Dakota'
,
'Ohio'
,
'Oklahoma'
,
'Oregon'
,
'Pennsylvania'
,
'Rhode Island'
,
'South Carolina'
,
'South Dakota'
,
'Tennessee'
,
'Texas'
,
'Utah'
,
'Vermont'
,
'Virginia'
,
'Washington'
,
'West Virginia'
,
'Wisconsin'
,
'Wyoming'
,
];
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