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
d46f0ceb
Commit
d46f0ceb
authored
Jan 07, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1098 from abarth/pageable_list2
Switch PageableList over to using RenderList
parents
e1b16729
e64d93a5
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
179 additions
and
173 deletions
+179
-173
tabs_demo.dart
examples/material_gallery/lib/demo/tabs_demo.dart
+1
-1
stock_home.dart
examples/stocks/lib/stock_home.dart
+1
-1
pageable_list.dart
examples/widgets/pageable_list.dart
+3
-4
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+12
-12
list.dart
packages/flutter/lib/src/rendering/list.dart
+16
-7
homogeneous_viewport.dart
packages/flutter/lib/src/widgets/homogeneous_viewport.dart
+0
-77
pageable_list.dart
packages/flutter/lib/src/widgets/pageable_list.dart
+107
-38
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+0
-2
scrollable_grid.dart
packages/flutter/lib/src/widgets/scrollable_grid.dart
+6
-6
scrollable_list.dart
packages/flutter/lib/src/widgets/scrollable_list.dart
+13
-9
virtual_viewport.dart
packages/flutter/lib/src/widgets/virtual_viewport.dart
+16
-11
pageable_list_test.dart
packages/flutter/test/widget/pageable_list_test.dart
+4
-5
No files found.
examples/material_gallery/lib/demo/tabs_demo.dart
View file @
d46f0ceb
...
@@ -29,7 +29,7 @@ class _TabsDemoState extends State<TabsDemo> {
...
@@ -29,7 +29,7 @@ class _TabsDemoState extends State<TabsDemo> {
Widget
build
(
_
)
{
Widget
build
(
_
)
{
return
new
TabBarView
<
String
>(
return
new
TabBarView
<
String
>(
items:
_iconNames
,
items:
_iconNames
,
itemBuilder:
(
BuildContext
context
,
String
iconName
,
int
index
)
{
itemBuilder:
(
String
iconName
)
{
return
new
Container
(
return
new
Container
(
key:
new
ValueKey
<
String
>(
iconName
),
key:
new
ValueKey
<
String
>(
iconName
),
padding:
const
EdgeDims
.
all
(
12.0
),
padding:
const
EdgeDims
.
all
(
12.0
),
...
...
examples/stocks/lib/stock_home.dart
View file @
d46f0ceb
...
@@ -273,7 +273,7 @@ class StockHomeState extends State<StockHome> {
...
@@ -273,7 +273,7 @@ class StockHomeState extends State<StockHome> {
drawer:
_buildDrawer
(
context
),
drawer:
_buildDrawer
(
context
),
body:
new
TabBarView
<
StockHomeTab
>(
body:
new
TabBarView
<
StockHomeTab
>(
items:
<
StockHomeTab
>[
StockHomeTab
.
market
,
StockHomeTab
.
portfolio
],
items:
<
StockHomeTab
>[
StockHomeTab
.
market
,
StockHomeTab
.
portfolio
],
itemBuilder:
(
BuildContext
context
,
StockHomeTab
tab
,
_
)
{
itemBuilder:
(
StockHomeTab
tab
)
{
switch
(
tab
)
{
switch
(
tab
)
{
case
StockHomeTab
.
market
:
case
StockHomeTab
.
market
:
return
_buildStockTab
(
context
,
tab
,
config
.
symbols
);
return
_buildStockTab
(
context
,
tab
,
config
.
symbols
);
...
...
examples/widgets/pageable_list.dart
View file @
d46f0ceb
...
@@ -41,7 +41,7 @@ class PageableListAppState extends State<PageableListApp> {
...
@@ -41,7 +41,7 @@ class PageableListAppState extends State<PageableListApp> {
ScrollDirection
scrollDirection
=
ScrollDirection
.
horizontal
;
ScrollDirection
scrollDirection
=
ScrollDirection
.
horizontal
;
bool
itemsWrap
=
false
;
bool
itemsWrap
=
false
;
Widget
buildCard
(
BuildContext
context
,
CardModel
cardModel
,
int
index
)
{
Widget
buildCard
(
CardModel
cardModel
)
{
Widget
card
=
new
Card
(
Widget
card
=
new
Card
(
color:
cardModel
.
color
,
color:
cardModel
.
color
,
child:
new
Container
(
child:
new
Container
(
...
@@ -114,10 +114,9 @@ class PageableListAppState extends State<PageableListApp> {
...
@@ -114,10 +114,9 @@ class PageableListAppState extends State<PageableListApp> {
}
}
Widget
_buildBody
(
BuildContext
context
)
{
Widget
_buildBody
(
BuildContext
context
)
{
return
new
PageableList
<
CardModel
>
(
return
new
PageableList
(
items:
cardModels
,
children:
cardModels
.
map
(
buildCard
)
,
itemsWrap:
itemsWrap
,
itemsWrap:
itemsWrap
,
itemBuilder:
buildCard
,
scrollDirection:
scrollDirection
scrollDirection:
scrollDirection
);
);
}
}
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
d46f0ceb
...
@@ -772,26 +772,30 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
...
@@ -772,26 +772,30 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
}
}
}
}
class
TabBarView
<
T
>
extends
PageableList
<
T
>
{
typedef
Widget
TabItemBuilder
<
T
>(
T
item
);
class
TabBarView
<
T
>
extends
PageableList
{
TabBarView
({
TabBarView
({
Key
key
,
Key
key
,
List
<
T
>
items
,
List
<
T
>
items
,
ItemBuilder
<
T
>
itemBuilder
Tab
ItemBuilder
<
T
>
itemBuilder
})
:
super
(
})
:
items
=
items
,
itemBuilder
=
itemBuilder
,
super
(
key:
key
,
key:
key
,
scrollDirection:
ScrollDirection
.
horizontal
,
scrollDirection:
ScrollDirection
.
horizontal
,
items:
items
,
children:
items
.
map
((
T
item
)
=>
itemBuilder
(
item
)),
itemBuilder:
itemBuilder
,
itemsWrap:
false
itemsWrap:
false
)
{
)
{
assert
(
items
!=
null
);
assert
(
items
!=
null
);
assert
(
items
.
length
>
1
);
assert
(
items
.
length
>
1
);
}
}
final
List
<
T
>
items
;
final
TabItemBuilder
<
T
>
itemBuilder
;
_TabBarViewState
createState
()
=>
new
_TabBarViewState
<
T
>();
_TabBarViewState
createState
()
=>
new
_TabBarViewState
<
T
>();
}
}
class
_TabBarViewState
<
T
>
extends
PageableListState
<
T
,
T
abBarView
<
T
>>
implements
TabBarSelectionPerformanceListener
{
class
_TabBarViewState
<
T
>
extends
PageableListState
<
TabBarView
<
T
>>
implements
TabBarSelectionPerformanceListener
{
TabBarSelectionState
_selection
;
TabBarSelectionState
_selection
;
List
<
int
>
_itemIndices
=
[
0
,
1
];
List
<
int
>
_itemIndices
=
[
0
,
1
];
...
@@ -916,14 +920,10 @@ class _TabBarViewState<T> extends PageableListState<T, TabBarView<T>> implements
...
@@ -916,14 +920,10 @@ class _TabBarViewState<T> extends PageableListState<T, TabBarView<T>> implements
return
settleScrollOffset
();
return
settleScrollOffset
();
}
}
List
<
Widget
>
buildItems
(
BuildContext
context
,
int
start
,
int
coun
t
)
{
Widget
buildContent
(
BuildContext
contex
t
)
{
TabBarSelectionState
<
T
>
newSelection
=
TabBarSelection
.
of
(
context
);
TabBarSelectionState
<
T
>
newSelection
=
TabBarSelection
.
of
(
context
);
if
(
_selection
!=
newSelection
)
if
(
_selection
!=
newSelection
)
_initSelection
(
newSelection
);
_initSelection
(
newSelection
);
return
_itemIndices
return
super
.
buildContent
(
context
);
.
skip
(
start
)
.
take
(
count
)
.
map
((
int
i
)
=>
config
.
itemBuilder
(
context
,
config
.
items
[
i
],
i
))
.
toList
();
}
}
}
}
packages/flutter/lib/src/rendering/list.dart
View file @
d46f0ceb
...
@@ -28,7 +28,6 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
...
@@ -28,7 +28,6 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
paintOffset:
paintOffset
,
paintOffset:
paintOffset
,
callback:
callback
callback:
callback
)
{
)
{
assert
(
itemExtent
!=
null
);
addAll
(
children
);
addAll
(
children
);
}
}
...
@@ -75,6 +74,8 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
...
@@ -75,6 +74,8 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
}
}
double
get
_preferredExtent
{
double
get
_preferredExtent
{
if
(
itemExtent
==
null
)
return
double
.
INFINITY
;
double
extent
=
itemExtent
*
virtualChildCount
;
double
extent
=
itemExtent
*
virtualChildCount
;
if
(
padding
!=
null
)
if
(
padding
!=
null
)
extent
+=
_scrollAxisPadding
;
extent
+=
_scrollAxisPadding
;
...
@@ -118,8 +119,16 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
...
@@ -118,8 +119,16 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
}
}
void
performLayout
()
{
void
performLayout
()
{
size
=
new
Size
(
constraints
.
maxWidth
,
switch
(
scrollDirection
)
{
constraints
.
constrainHeight
(
_preferredExtent
));
case
ScrollDirection
.
vertical
:
size
=
new
Size
(
constraints
.
maxWidth
,
constraints
.
constrainHeight
(
_preferredExtent
));
break
;
case
ScrollDirection
.
horizontal
:
size
=
new
Size
(
constraints
.
constrainWidth
(
_preferredExtent
),
constraints
.
maxHeight
);
break
;
}
if
(
callback
!=
null
)
if
(
callback
!=
null
)
invokeLayoutCallback
(
callback
);
invokeLayoutCallback
(
callback
);
...
@@ -136,15 +145,15 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
...
@@ -136,15 +145,15 @@ class RenderList extends RenderVirtualViewport<ListParentData> implements HasScr
switch
(
scrollDirection
)
{
switch
(
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
case
ScrollDirection
.
vertical
:
itemWidth
=
math
.
max
(
0
,
size
.
width
-
(
padding
==
null
?
0.0
:
padding
.
horizontal
));
itemWidth
=
math
.
max
(
0
,
size
.
width
-
(
padding
==
null
?
0.0
:
padding
.
horizontal
));
itemHeight
=
itemExtent
;
itemHeight
=
itemExtent
??
size
.
height
;
y
=
padding
!=
null
?
padding
.
top
:
0.0
;
y
=
padding
!=
null
?
padding
.
top
:
0.0
;
dy
=
item
Exten
t
;
dy
=
item
Heigh
t
;
break
;
break
;
case
ScrollDirection
.
horizontal
:
case
ScrollDirection
.
horizontal
:
itemWidth
=
itemExtent
;
itemWidth
=
itemExtent
??
size
.
width
;
itemHeight
=
math
.
max
(
0
,
size
.
height
-
(
padding
==
null
?
0.0
:
padding
.
vertical
));
itemHeight
=
math
.
max
(
0
,
size
.
height
-
(
padding
==
null
?
0.0
:
padding
.
vertical
));
x
=
padding
!=
null
?
padding
.
left
:
0.0
;
x
=
padding
!=
null
?
padding
.
left
:
0.0
;
dx
=
item
Extent
;
dx
=
item
Width
;
break
;
break
;
}
}
...
...
packages/flutter/lib/src/widgets/homogeneous_viewport.dart
View file @
d46f0ceb
...
@@ -220,80 +220,3 @@ class _HomogeneousViewportElement extends _ViewportBaseElement<HomogeneousViewpo
...
@@ -220,80 +220,3 @@ class _HomogeneousViewportElement extends _ViewportBaseElement<HomogeneousViewpo
return
widget
.
itemCount
!=
null
?
widget
.
itemCount
*
widget
.
itemExtent
:
double
.
INFINITY
;
return
widget
.
itemCount
!=
null
?
widget
.
itemCount
*
widget
.
itemExtent
:
double
.
INFINITY
;
}
}
}
}
class
HomogeneousPageViewport
extends
_ViewportBase
{
HomogeneousPageViewport
({
Key
key
,
ListBuilder
builder
,
bool
itemsWrap:
false
,
int
itemCount
,
// optional, but you cannot shrink-wrap this class or otherwise use its intrinsic dimensions if you don't specify it
ScrollDirection
direction:
ScrollDirection
.
vertical
,
double
startOffset:
0.0
,
Painter
overlayPainter
})
:
super
(
key:
key
,
builder:
builder
,
itemsWrap:
itemsWrap
,
itemCount:
itemCount
,
direction:
direction
,
startOffset:
startOffset
,
overlayPainter:
overlayPainter
);
_HomogeneousPageViewportElement
createElement
()
=>
new
_HomogeneousPageViewportElement
(
this
);
}
class
_HomogeneousPageViewportElement
extends
_ViewportBaseElement
<
HomogeneousPageViewport
>
{
_HomogeneousPageViewportElement
(
HomogeneousPageViewport
widget
)
:
super
(
widget
);
void
layout
(
BoxConstraints
constraints
)
{
// We enter a build scope (meaning that markNeedsBuild() is forbidden)
// because we are in the middle of layout and if we allowed people to set
// state, they'd expect to have that state reflected immediately, which, if
// we were to try to honour it, would potentially result in assertions
// because you can't normally mutate the render object tree during layout.
// (If there were a way to limit these writes to descendants of this, it'd
// be ok because we are exempt from that assert since we are still actively
// doing our own layout.)
BuildableElement
.
lockState
(()
{
double
itemExtent
=
widget
.
direction
==
ScrollDirection
.
vertical
?
constraints
.
maxHeight
:
constraints
.
maxWidth
;
double
offset
;
if
(
widget
.
startOffset
<=
0.0
&&
!
widget
.
itemsWrap
)
{
_layoutFirstIndex
=
0
;
offset
=
-
widget
.
startOffset
*
itemExtent
;
}
else
{
_layoutFirstIndex
=
widget
.
startOffset
.
floor
();
offset
=
-((
widget
.
startOffset
*
itemExtent
)
%
itemExtent
);
}
if
(
itemExtent
<
double
.
INFINITY
&&
widget
.
itemCount
!=
null
)
{
final
double
contentExtent
=
itemExtent
*
widget
.
itemCount
;
_layoutItemCount
=
contentExtent
==
0.0
?
0
:
((
contentExtent
-
offset
)
/
contentExtent
).
ceil
();
if
(!
widget
.
itemsWrap
)
_layoutItemCount
=
math
.
min
(
_layoutItemCount
,
widget
.
itemCount
-
_layoutFirstIndex
);
}
else
{
assert
(()
{
'This HomogeneousPageViewport has no specified number of items (meaning it has infinite items), '
+
'and has been placed in an unconstrained environment where all items can be rendered. '
+
'It is most likely that you have placed your HomogeneousPageViewport (which is an internal '
+
'component of several scrollable widgets) inside either another scrolling box, a flexible '
+
'box (Row, Column), or a Stack, without giving it a specific size.'
;
return
widget
.
itemCount
!=
null
;
});
_layoutItemCount
=
widget
.
itemCount
-
_layoutFirstIndex
;
}
_layoutItemCount
=
math
.
max
(
0
,
_layoutItemCount
);
_updateChildren
();
// Update the renderObject configuration
renderObject
.
direction
=
widget
.
direction
==
ScrollDirection
.
vertical
?
BlockDirection
.
vertical
:
BlockDirection
.
horizontal
;
renderObject
.
itemExtent
=
itemExtent
;
renderObject
.
minExtent
=
itemExtent
;
renderObject
.
startOffset
=
offset
;
renderObject
.
overlayPainter
=
widget
.
overlayPainter
;
},
building:
true
);
}
double
getTotalExtent
(
BoxConstraints
constraints
)
{
double
itemExtent
=
widget
.
direction
==
ScrollDirection
.
vertical
?
constraints
.
maxHeight
:
constraints
.
maxWidth
;
return
widget
.
itemCount
!=
null
?
widget
.
itemCount
*
itemExtent
:
double
.
INFINITY
;
}
}
packages/flutter/lib/src/widgets/pageable_list.dart
View file @
d46f0ceb
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:async'
;
import
'dart:math'
as
math
;
import
'package:flutter/animation.dart'
;
import
'package:flutter/animation.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/gestures.dart'
;
...
@@ -11,8 +10,8 @@ import 'package:flutter/rendering.dart';
...
@@ -11,8 +10,8 @@ import 'package:flutter/rendering.dart';
import
'basic.dart'
;
import
'basic.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
import
'homogeneous_viewport.dart'
;
import
'scrollable.dart'
;
import
'scrollable.dart'
;
import
'virtual_viewport.dart'
;
/// Controls what alignment items use when settling.
/// Controls what alignment items use when settling.
enum
ItemsSnapAlignment
{
enum
ItemsSnapAlignment
{
...
@@ -22,7 +21,7 @@ enum ItemsSnapAlignment {
...
@@ -22,7 +21,7 @@ enum ItemsSnapAlignment {
typedef
void
PageChangedCallback
(
int
newPage
);
typedef
void
PageChangedCallback
(
int
newPage
);
class
PageableList
<
T
>
extends
Scrollable
{
class
PageableList
extends
Scrollable
{
PageableList
({
PageableList
({
Key
key
,
Key
key
,
initialScrollOffset
,
initialScrollOffset
,
...
@@ -32,14 +31,13 @@ class PageableList<T> extends Scrollable {
...
@@ -32,14 +31,13 @@ class PageableList<T> extends Scrollable {
ScrollListener
onScrollEnd
,
ScrollListener
onScrollEnd
,
SnapOffsetCallback
snapOffsetCallback
,
SnapOffsetCallback
snapOffsetCallback
,
double
snapAlignmentOffset:
0.0
,
double
snapAlignmentOffset:
0.0
,
this
.
items
,
this
.
itemBuilder
,
this
.
itemsWrap
:
false
,
this
.
itemsWrap
:
false
,
this
.
itemsSnapAlignment
:
ItemsSnapAlignment
.
adjacentItem
,
this
.
itemsSnapAlignment
:
ItemsSnapAlignment
.
adjacentItem
,
this
.
onPageChanged
,
this
.
onPageChanged
,
this
.
scrollableListPainter
,
this
.
scrollableListPainter
,
this
.
duration
:
const
Duration
(
milliseconds:
200
),
this
.
duration
:
const
Duration
(
milliseconds:
200
),
this
.
curve
:
Curves
.
ease
this
.
curve
:
Curves
.
ease
,
this
.
children
})
:
super
(
})
:
super
(
key:
key
,
key:
key
,
initialScrollOffset:
initialScrollOffset
,
initialScrollOffset:
initialScrollOffset
,
...
@@ -51,21 +49,19 @@ class PageableList<T> extends Scrollable {
...
@@ -51,21 +49,19 @@ class PageableList<T> extends Scrollable {
snapAlignmentOffset:
snapAlignmentOffset
snapAlignmentOffset:
snapAlignmentOffset
);
);
final
List
<
T
>
items
;
final
ItemBuilder
<
T
>
itemBuilder
;
final
ItemsSnapAlignment
itemsSnapAlignment
;
final
bool
itemsWrap
;
final
bool
itemsWrap
;
final
ItemsSnapAlignment
itemsSnapAlignment
;
final
PageChangedCallback
onPageChanged
;
final
PageChangedCallback
onPageChanged
;
final
ScrollableListPainter
scrollableListPainter
;
final
ScrollableListPainter
scrollableListPainter
;
final
Duration
duration
;
final
Duration
duration
;
final
Curve
curve
;
final
Curve
curve
;
final
Iterable
<
Widget
>
children
;
PageableListState
<
T
,
PageableList
<
T
>>
createState
()
=>
new
PageableListState
<
T
,
PageableList
<
T
>>
();
PageableListState
createState
()
=>
new
PageableListState
();
}
}
class
PageableListState
<
T
,
Config
extends
PageableList
<
T
>>
extends
ScrollableState
<
Config
>
{
class
PageableListState
<
T
extends
PageableList
>
extends
ScrollableState
<
T
>
{
int
get
itemCount
=>
config
.
children
?.
length
??
0
;
int
get
itemCount
=>
config
.
items
?.
length
??
0
;
int
_previousItemCount
;
int
_previousItemCount
;
double
pixelToScrollOffset
(
double
value
)
{
double
pixelToScrollOffset
(
double
value
)
{
...
@@ -76,7 +72,12 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
...
@@ -76,7 +72,12 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
return
pixelScrollExtent
==
0.0
?
0.0
:
value
/
pixelScrollExtent
;
return
pixelScrollExtent
==
0.0
?
0.0
:
value
/
pixelScrollExtent
;
}
}
void
didUpdateConfig
(
Config
oldConfig
)
{
void
initState
()
{
super
.
initState
();
_updateScrollBehavior
();
}
void
didUpdateConfig
(
PageableList
oldConfig
)
{
super
.
didUpdateConfig
(
oldConfig
);
super
.
didUpdateConfig
(
oldConfig
);
bool
scrollBehaviorUpdateNeeded
=
config
.
scrollDirection
!=
oldConfig
.
scrollDirection
;
bool
scrollBehaviorUpdateNeeded
=
config
.
scrollDirection
!=
oldConfig
.
scrollDirection
;
...
@@ -94,9 +95,7 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
...
@@ -94,9 +95,7 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
}
}
void
_updateScrollBehavior
()
{
void
_updateScrollBehavior
()
{
// if you don't call this from build(), you must call it from setState().
config
.
scrollableListPainter
?.
contentExtent
=
itemCount
.
toDouble
();
if
(
config
.
scrollableListPainter
!=
null
)
config
.
scrollableListPainter
.
contentExtent
=
itemCount
.
toDouble
();
scrollTo
(
scrollBehavior
.
updateExtents
(
scrollTo
(
scrollBehavior
.
updateExtents
(
contentExtent:
itemCount
.
toDouble
(),
contentExtent:
itemCount
.
toDouble
(),
containerExtent:
1.0
,
containerExtent:
1.0
,
...
@@ -111,8 +110,7 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
...
@@ -111,8 +110,7 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
void
dispatchOnScroll
()
{
void
dispatchOnScroll
()
{
super
.
dispatchOnScroll
();
super
.
dispatchOnScroll
();
if
(
config
.
scrollableListPainter
!=
null
)
config
.
scrollableListPainter
?.
scrollOffset
=
scrollOffset
;
config
.
scrollableListPainter
.
scrollOffset
=
scrollOffset
;
}
}
void
dispatchOnScrollEnd
()
{
void
dispatchOnScrollEnd
()
{
...
@@ -121,17 +119,12 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
...
@@ -121,17 +119,12 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
}
}
Widget
buildContent
(
BuildContext
context
)
{
Widget
buildContent
(
BuildContext
context
)
{
if
(
itemCount
!=
_previousItemCount
)
{
return
new
PageViewport
(
_previousItemCount
=
itemCount
;
_updateScrollBehavior
();
}
return
new
HomogeneousPageViewport
(
builder:
buildItems
,
itemsWrap:
config
.
itemsWrap
,
itemsWrap:
config
.
itemsWrap
,
itemCount:
itemCount
,
scrollDirection:
config
.
scrollDirection
,
direction:
config
.
scrollDirection
,
startOffset:
scrollOffset
,
startOffset:
scrollOffset
,
overlayPainter:
config
.
scrollableListPainter
overlayPainter:
config
.
scrollableListPainter
,
children:
config
.
children
);
);
}
}
...
@@ -180,18 +173,94 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
...
@@ -180,18 +173,94 @@ class PageableListState<T, Config extends PageableList<T>> extends ScrollableSta
.
then
(
_notifyPageChanged
);
.
then
(
_notifyPageChanged
);
}
}
List
<
Widget
>
buildItems
(
BuildContext
context
,
int
start
,
int
count
)
{
final
List
<
Widget
>
result
=
new
List
<
Widget
>();
final
int
begin
=
config
.
itemsWrap
?
start
:
math
.
max
(
0
,
start
);
final
int
end
=
config
.
itemsWrap
?
begin
+
count
:
math
.
min
(
begin
+
count
,
itemCount
);
for
(
int
i
=
begin
;
i
<
end
;
++
i
)
result
.
add
(
config
.
itemBuilder
(
context
,
config
.
items
[
i
%
itemCount
],
i
));
assert
(
result
.
every
((
Widget
item
)
=>
item
.
key
!=
null
));
return
result
;
}
void
_notifyPageChanged
(
_
)
{
void
_notifyPageChanged
(
_
)
{
if
(
config
.
onPageChanged
!=
null
)
if
(
config
.
onPageChanged
!=
null
)
config
.
onPageChanged
(
itemCount
==
0
?
0
:
scrollOffset
.
floor
()
%
itemCount
);
config
.
onPageChanged
(
itemCount
==
0
?
0
:
scrollOffset
.
floor
()
%
itemCount
);
}
}
}
}
class
PageViewport
extends
VirtualViewport
{
PageViewport
({
Key
key
,
this
.
startOffset
:
0.0
,
this
.
scrollDirection
:
ScrollDirection
.
vertical
,
this
.
itemsWrap
:
false
,
this
.
overlayPainter
,
this
.
children
})
{
assert
(
scrollDirection
!=
null
);
}
final
double
startOffset
;
final
ScrollDirection
scrollDirection
;
final
bool
itemsWrap
;
final
Painter
overlayPainter
;
final
Iterable
<
Widget
>
children
;
RenderList
createRenderObject
()
=>
new
RenderList
();
_PageViewportElement
createElement
()
=>
new
_PageViewportElement
(
this
);
}
class
_PageViewportElement
extends
VirtualViewportElement
<
PageViewport
>
{
_PageViewportElement
(
PageViewport
widget
)
:
super
(
widget
);
RenderList
get
renderObject
=>
super
.
renderObject
;
int
get
materializedChildBase
=>
_materializedChildBase
;
int
_materializedChildBase
;
int
get
materializedChildCount
=>
_materializedChildCount
;
int
_materializedChildCount
;
double
get
startOffsetBase
=>
_repaintOffsetBase
;
double
_repaintOffsetBase
;
double
get
startOffsetLimit
=>
_repaintOffsetLimit
;
double
_repaintOffsetLimit
;
double
get
paintOffset
{
if
(
_containerExtent
==
null
)
return
0.0
;
return
-(
widget
.
startOffset
-
startOffsetBase
)
*
_containerExtent
;
}
void
updateRenderObject
()
{
renderObject
.
scrollDirection
=
widget
.
scrollDirection
;
renderObject
.
overlayPainter
=
widget
.
overlayPainter
;
super
.
updateRenderObject
();
}
double
_containerExtent
;
double
_getContainerExtentFromRenderObject
()
{
switch
(
widget
.
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
return
renderObject
.
size
.
height
;
case
ScrollDirection
.
horizontal
:
return
renderObject
.
size
.
width
;
}
}
void
layout
(
BoxConstraints
constraints
)
{
int
length
=
renderObject
.
virtualChildCount
;
_containerExtent
=
_getContainerExtentFromRenderObject
();
_materializedChildBase
=
widget
.
startOffset
.
floor
();
int
materializedChildLimit
=
(
widget
.
startOffset
+
1.0
).
ceil
();
if
(!
widget
.
itemsWrap
)
{
_materializedChildBase
=
_materializedChildBase
.
clamp
(
0
,
length
);
materializedChildLimit
=
materializedChildLimit
.
clamp
(
0
,
length
);
}
else
if
(
length
==
0
)
{
materializedChildLimit
=
_materializedChildBase
;
}
_materializedChildCount
=
materializedChildLimit
-
_materializedChildBase
;
_repaintOffsetBase
=
_materializedChildBase
.
toDouble
();
_repaintOffsetLimit
=
(
materializedChildLimit
-
1
).
toDouble
();
super
.
layout
(
constraints
);
}
}
packages/flutter/lib/src/widgets/scrollable.dart
View file @
d46f0ceb
...
@@ -664,8 +664,6 @@ abstract class ScrollableWidgetListState<T extends ScrollableWidgetList> extends
...
@@ -664,8 +664,6 @@ abstract class ScrollableWidgetListState<T extends ScrollableWidgetList> extends
}
}
typedef
Widget
ItemBuilder
<
T
>(
BuildContext
context
,
T
item
,
int
index
);
/// A general scrollable list for a large number of children that might not all
/// A general scrollable list for a large number of children that might not all
/// have the same height. Prefer [ScrollableWidgetList] when all the children
/// have the same height. Prefer [ScrollableWidgetList] when all the children
/// have the same height because it can use that property to be more efficient.
/// have the same height because it can use that property to be more efficient.
...
...
packages/flutter/lib/src/widgets/scrollable_grid.dart
View file @
d46f0ceb
...
@@ -116,11 +116,11 @@ class _GridViewportElement extends VirtualViewportElement<GridViewport> {
...
@@ -116,11 +116,11 @@ class _GridViewportElement extends VirtualViewportElement<GridViewport> {
int
get
materializedChildCount
=>
_materializedChildCount
;
int
get
materializedChildCount
=>
_materializedChildCount
;
int
_materializedChildCount
;
int
_materializedChildCount
;
double
get
repaintOffsetBase
=>
_repain
tOffsetBase
;
double
get
startOffsetBase
=>
_star
tOffsetBase
;
double
_
repain
tOffsetBase
;
double
_
star
tOffsetBase
;
double
get
repaintOffsetLimit
=>
_repain
tOffsetLimit
;
double
get
startOffsetLimit
=>
_star
tOffsetLimit
;
double
_
repain
tOffsetLimit
;
double
_
star
tOffsetLimit
;
void
updateRenderObject
()
{
void
updateRenderObject
()
{
renderObject
.
delegate
=
widget
.
delegate
;
renderObject
.
delegate
=
widget
.
delegate
;
...
@@ -141,8 +141,8 @@ class _GridViewportElement extends VirtualViewportElement<GridViewport> {
...
@@ -141,8 +141,8 @@ class _GridViewportElement extends VirtualViewportElement<GridViewport> {
_materializedChildBase
=
(
materializedRowBase
*
_specification
.
columnCount
).
clamp
(
0
,
renderObject
.
virtualChildCount
);
_materializedChildBase
=
(
materializedRowBase
*
_specification
.
columnCount
).
clamp
(
0
,
renderObject
.
virtualChildCount
);
_materializedChildCount
=
(
materializedRowLimit
*
_specification
.
columnCount
).
clamp
(
0
,
renderObject
.
virtualChildCount
)
-
_materializedChildBase
;
_materializedChildCount
=
(
materializedRowLimit
*
_specification
.
columnCount
).
clamp
(
0
,
renderObject
.
virtualChildCount
)
-
_materializedChildBase
;
_
repain
tOffsetBase
=
_specification
.
rowOffsets
[
materializedRowBase
];
_
star
tOffsetBase
=
_specification
.
rowOffsets
[
materializedRowBase
];
_
repain
tOffsetLimit
=
_specification
.
rowOffsets
[
materializedRowLimit
]
-
containerExtent
;
_
star
tOffsetLimit
=
_specification
.
rowOffsets
[
materializedRowLimit
]
-
containerExtent
;
super
.
layout
(
constraints
);
super
.
layout
(
constraints
);
...
...
packages/flutter/lib/src/widgets/scrollable_list.dart
View file @
d46f0ceb
...
@@ -129,11 +129,11 @@ class _ListViewportElement extends VirtualViewportElement<ListViewport> {
...
@@ -129,11 +129,11 @@ class _ListViewportElement extends VirtualViewportElement<ListViewport> {
int
get
materializedChildCount
=>
_materializedChildCount
;
int
get
materializedChildCount
=>
_materializedChildCount
;
int
_materializedChildCount
;
int
_materializedChildCount
;
double
get
repaintOffsetBase
=>
_repain
tOffsetBase
;
double
get
startOffsetBase
=>
_star
tOffsetBase
;
double
_
repain
tOffsetBase
;
double
_
star
tOffsetBase
;
double
get
repaintOffsetLimit
=>
_repain
tOffsetLimit
;
double
get
startOffsetLimit
=>
_star
tOffsetLimit
;
double
_
repain
tOffsetLimit
;
double
_
star
tOffsetLimit
;
void
updateRenderObject
()
{
void
updateRenderObject
()
{
renderObject
.
scrollDirection
=
widget
.
scrollDirection
;
renderObject
.
scrollDirection
=
widget
.
scrollDirection
;
...
@@ -156,21 +156,25 @@ class _ListViewportElement extends VirtualViewportElement<ListViewport> {
...
@@ -156,21 +156,25 @@ class _ListViewportElement extends VirtualViewportElement<ListViewport> {
}
}
void
layout
(
BoxConstraints
constraints
)
{
void
layout
(
BoxConstraints
constraints
)
{
int
length
=
renderObject
.
virtualChildCount
;
final
int
length
=
renderObject
.
virtualChildCount
;
final
double
itemExtent
=
widget
.
itemExtent
;
double
contentExtent
=
widget
.
itemExtent
*
length
;
double
contentExtent
=
widget
.
itemExtent
*
length
;
double
containerExtent
=
_getContainerExtentFromRenderObject
();
double
containerExtent
=
_getContainerExtentFromRenderObject
();
_materializedChildBase
=
math
.
max
(
0
,
widget
.
startOffset
~/
widget
.
itemExtent
);
_materializedChildBase
=
math
.
max
(
0
,
widget
.
startOffset
~/
itemExtent
);
int
materializedChildLimit
=
math
.
max
(
0
,
((
widget
.
startOffset
+
containerExtent
)
/
widget
.
itemExtent
).
ceil
());
int
materializedChildLimit
=
math
.
max
(
0
,
((
widget
.
startOffset
+
containerExtent
)
/
itemExtent
).
ceil
());
if
(!
widget
.
itemsWrap
)
{
if
(!
widget
.
itemsWrap
)
{
_materializedChildBase
=
math
.
min
(
length
,
_materializedChildBase
);
_materializedChildBase
=
math
.
min
(
length
,
_materializedChildBase
);
materializedChildLimit
=
math
.
min
(
length
,
materializedChildLimit
);
materializedChildLimit
=
math
.
min
(
length
,
materializedChildLimit
);
}
else
if
(
length
==
0
)
{
materializedChildLimit
=
_materializedChildBase
;
}
}
_materializedChildCount
=
materializedChildLimit
-
_materializedChildBase
;
_materializedChildCount
=
materializedChildLimit
-
_materializedChildBase
;
_
repaintOffsetBase
=
_materializedChildBase
*
widget
.
itemExtent
;
_
startOffsetBase
=
_materializedChildBase
*
itemExtent
;
_
repaintOffsetLimit
=
materializedChildLimit
*
widget
.
itemExtent
-
containerExtent
;
_
startOffsetLimit
=
materializedChildLimit
*
itemExtent
-
containerExtent
;
super
.
layout
(
constraints
);
super
.
layout
(
constraints
);
...
...
packages/flutter/lib/src/widgets/virtual_viewport.dart
View file @
d46f0ceb
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'basic.dart'
;
import
'basic.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
...
@@ -20,8 +22,10 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -20,8 +22,10 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
int
get
materializedChildBase
;
int
get
materializedChildBase
;
int
get
materializedChildCount
;
int
get
materializedChildCount
;
double
get
repaintOffsetBase
;
double
get
startOffsetBase
;
double
get
repaintOffsetLimit
;
double
get
startOffsetLimit
;
double
get
paintOffset
=>
-(
widget
.
startOffset
-
startOffsetBase
);
List
<
Element
>
_materializedChildren
=
const
<
Element
>[];
List
<
Element
>
_materializedChildren
=
const
<
Element
>[];
...
@@ -61,10 +65,10 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -61,10 +65,10 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
void
_updatePaintOffset
()
{
void
_updatePaintOffset
()
{
switch
(
widget
.
scrollDirection
)
{
switch
(
widget
.
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
case
ScrollDirection
.
vertical
:
renderObject
.
paintOffset
=
new
Offset
(
0.0
,
-(
widget
.
startOffset
-
repaintOffsetBase
)
);
renderObject
.
paintOffset
=
new
Offset
(
0.0
,
paintOffset
);
break
;
break
;
case
ScrollDirection
.
horizontal
:
case
ScrollDirection
.
horizontal
:
renderObject
.
paintOffset
=
new
Offset
(
-(
widget
.
startOffset
-
repaintOffsetBase
)
,
0.0
);
renderObject
.
paintOffset
=
new
Offset
(
paintOffset
,
0.0
);
break
;
break
;
}
}
}
}
...
@@ -72,24 +76,25 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -72,24 +76,25 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
void
updateRenderObject
()
{
void
updateRenderObject
()
{
renderObject
.
virtualChildCount
=
widget
.
children
.
length
;
renderObject
.
virtualChildCount
=
widget
.
children
.
length
;
if
(
repain
tOffsetBase
!=
null
)
{
if
(
star
tOffsetBase
!=
null
)
{
_updatePaintOffset
();
_updatePaintOffset
();
// If we don't already need layout, we need to request a layout if the
// If we don't already need layout, we need to request a layout if the
// viewport has shifted to expose new children.
// viewport has shifted to expose new children.
if
(!
renderObject
.
needsLayout
)
{
if
(!
renderObject
.
needsLayout
)
{
if
(
repaintOffsetBase
!=
null
&&
widget
.
startOffset
<
repain
tOffsetBase
)
if
(
startOffsetBase
!=
null
&&
widget
.
startOffset
<
star
tOffsetBase
)
renderObject
.
markNeedsLayout
();
renderObject
.
markNeedsLayout
();
else
if
(
repaintOffsetLimit
!=
null
&&
widget
.
startOffset
>
repain
tOffsetLimit
)
else
if
(
startOffsetLimit
!=
null
&&
widget
.
startOffset
>
star
tOffsetLimit
)
renderObject
.
markNeedsLayout
();
renderObject
.
markNeedsLayout
();
}
}
}
}
}
}
void
layout
(
BoxConstraints
constraints
)
{
void
layout
(
BoxConstraints
constraints
)
{
assert
(
repain
tOffsetBase
!=
null
);
assert
(
star
tOffsetBase
!=
null
);
assert
(
repain
tOffsetLimit
!=
null
);
assert
(
star
tOffsetLimit
!=
null
);
_updatePaintOffset
();
_updatePaintOffset
();
// TODO(abarth): Set building: true here.
BuildableElement
.
lockState
(
_materializeChildren
);
BuildableElement
.
lockState
(
_materializeChildren
);
}
}
...
@@ -119,11 +124,11 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -119,11 +124,11 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
int
length
=
renderObject
.
virtualChildCount
;
int
length
=
renderObject
.
virtualChildCount
;
assert
(
base
!=
null
);
assert
(
base
!=
null
);
assert
(
count
!=
null
);
assert
(
count
!=
null
);
_populateWidgets
(
base
+
count
);
_populateWidgets
(
base
<
0
?
length
:
math
.
min
(
length
,
base
+
count
)
);
List
<
Widget
>
newWidgets
=
new
List
<
Widget
>(
count
);
List
<
Widget
>
newWidgets
=
new
List
<
Widget
>(
count
);
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
count
;
++
i
)
{
int
childIndex
=
base
+
i
;
int
childIndex
=
base
+
i
;
Widget
child
=
_widgets
[
childIndex
%
length
];
Widget
child
=
_widgets
[
(
childIndex
%
length
).
abs
()
];
Key
key
=
new
ValueKey
(
child
.
key
??
childIndex
);
Key
key
=
new
ValueKey
(
child
.
key
??
childIndex
);
newWidgets
[
i
]
=
new
RepaintBoundary
(
key:
key
,
child:
child
);
newWidgets
[
i
]
=
new
RepaintBoundary
(
key:
key
,
child:
child
);
}
}
...
...
packages/flutter/test/widget/pageable_list_test.dart
View file @
d46f0ceb
...
@@ -13,7 +13,7 @@ final List<GlobalKey> globalKeys = defaultPages.map((_) => new GlobalKey()).toLi
...
@@ -13,7 +13,7 @@ final List<GlobalKey> globalKeys = defaultPages.map((_) => new GlobalKey()).toLi
int
currentPage
=
null
;
int
currentPage
=
null
;
bool
itemsWrap
=
false
;
bool
itemsWrap
=
false
;
Widget
buildPage
(
BuildContext
context
,
int
page
,
int
index
)
{
Widget
buildPage
(
int
page
)
{
return
new
Container
(
return
new
Container
(
key:
globalKeys
[
page
],
key:
globalKeys
[
page
],
width:
pageSize
.
width
,
width:
pageSize
.
width
,
...
@@ -23,9 +23,8 @@ Widget buildPage(BuildContext context, int page, int index) {
...
@@ -23,9 +23,8 @@ Widget buildPage(BuildContext context, int page, int index) {
}
}
Widget
buildFrame
(
{
List
<
int
>
pages:
defaultPages
})
{
Widget
buildFrame
(
{
List
<
int
>
pages:
defaultPages
})
{
final
list
=
new
PageableList
<
int
>(
final
list
=
new
PageableList
(
items:
pages
,
children:
pages
.
map
(
buildPage
),
itemBuilder:
buildPage
,
itemsWrap:
itemsWrap
,
itemsWrap:
itemsWrap
,
scrollDirection:
ScrollDirection
.
horizontal
,
scrollDirection:
ScrollDirection
.
horizontal
,
onPageChanged:
(
int
page
)
{
currentPage
=
page
;
}
onPageChanged:
(
int
page
)
{
currentPage
=
page
;
}
...
@@ -136,7 +135,7 @@ void main() {
...
@@ -136,7 +135,7 @@ void main() {
testWidgets
((
WidgetTester
tester
)
{
testWidgets
((
WidgetTester
tester
)
{
currentPage
=
null
;
currentPage
=
null
;
itemsWrap
=
true
;
itemsWrap
=
true
;
tester
.
pumpWidget
(
buildFrame
(
pages:
null
));
tester
.
pumpWidget
(
buildFrame
(
pages:
<
int
>[]
));
expect
(
currentPage
,
isNull
);
expect
(
currentPage
,
isNull
);
});
});
});
});
...
...
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