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
c4faad11
Commit
c4faad11
authored
Jan 06, 2016
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1074 from abarth/scrollable_list_features
Complete features of ScrollableList2
parents
f72c8f6d
b1f9138f
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
379 additions
and
162 deletions
+379
-162
feed.dart
examples/fitness/lib/feed.dart
+2
-3
stock_list.dart
examples/stocks/lib/stock_list.dart
+3
-4
card_collection.dart
examples/widgets/card_collection.dart
+3
-4
media_query.dart
examples/widgets/media_query.dart
+2
-2
scrollbar.dart
examples/widgets/scrollbar.dart
+18
-10
material_list.dart
packages/flutter/lib/src/material/material_list.dart
+10
-19
scrollbar_painter.dart
packages/flutter/lib/src/material/scrollbar_painter.dart
+20
-17
block.dart
packages/flutter/lib/src/rendering/block.dart
+8
-2
list.dart
packages/flutter/lib/src/rendering/list.dart
+101
-20
viewport.dart
packages/flutter/lib/src/rendering/viewport.dart
+35
-4
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+11
-7
scrollable_grid.dart
packages/flutter/lib/src/widgets/scrollable_grid.dart
+7
-4
scrollable_list.dart
packages/flutter/lib/src/widgets/scrollable_list.dart
+75
-16
virtual_viewport.dart
packages/flutter/lib/src/widgets/virtual_viewport.dart
+49
-5
dismissable_test.dart
packages/flutter/test/widget/dismissable_test.dart
+6
-5
reparent_state_test.dart
packages/flutter/test/widget/reparent_state_test.dart
+5
-6
scrollable_list_hit_testing_test.dart
...flutter/test/widget/scrollable_list_hit_testing_test.dart
+10
-14
scrollable_list_horizontal_test.dart
.../flutter/test/widget/scrollable_list_horizontal_test.dart
+5
-7
scrollable_list_vertical_test.dart
...es/flutter/test/widget/scrollable_list_vertical_test.dart
+5
-7
snap_scrolling_test.dart
packages/flutter/test/widget/snap_scrolling_test.dart
+4
-6
No files found.
examples/fitness/lib/feed.dart
View file @
c4faad11
...
@@ -14,11 +14,10 @@ class FitnessItemList extends StatelessComponent {
...
@@ -14,11 +14,10 @@ class FitnessItemList extends StatelessComponent {
final
FitnessItemHandler
onDismissed
;
final
FitnessItemHandler
onDismissed
;
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
new
ScrollableList
<
FitnessItem
>
(
return
new
ScrollableList
2
(
padding:
const
EdgeDims
.
all
(
4.0
),
padding:
const
EdgeDims
.
all
(
4.0
),
items:
items
,
itemExtent:
kFitnessItemHeight
,
itemExtent:
kFitnessItemHeight
,
itemBuilder:
(
BuildContext
context
,
FitnessItem
item
,
int
index
)
=>
item
.
toRow
(
onDismissed:
onDismissed
)
children:
items
.
map
((
FitnessItem
item
)
=>
item
.
toRow
(
onDismissed:
onDismissed
)
)
);
);
}
}
}
}
...
...
examples/stocks/lib/stock_list.dart
View file @
c4faad11
...
@@ -14,10 +14,9 @@ class StockList extends StatelessComponent {
...
@@ -14,10 +14,9 @@ class StockList extends StatelessComponent {
final
StockRowActionCallback
onAction
;
final
StockRowActionCallback
onAction
;
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
new
ScrollableList
<
Stock
>(
return
new
ScrollableList2
(
items:
stocks
,
itemExtent:
StockRow
.
kHeight
,
itemExtent:
StockRow
.
kHeight
,
itemBuilder:
(
BuildContext
context
,
Stock
stock
,
int
index
)
{
children:
stocks
.
map
((
Stock
stock
)
{
return
new
StockRow
(
return
new
StockRow
(
keySalt:
keySalt
,
keySalt:
keySalt
,
stock:
stock
,
stock:
stock
,
...
@@ -25,7 +24,7 @@ class StockList extends StatelessComponent {
...
@@ -25,7 +24,7 @@ class StockList extends StatelessComponent {
onDoubleTap:
onShow
,
onDoubleTap:
onShow
,
onLongPressed:
onAction
onLongPressed:
onAction
);
);
}
}
)
);
);
}
}
}
}
examples/widgets/card_collection.dart
View file @
c4faad11
...
@@ -393,12 +393,11 @@ class CardCollectionState extends State<CardCollection> {
...
@@ -393,12 +393,11 @@ class CardCollectionState extends State<CardCollection> {
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
Widget
cardCollection
;
Widget
cardCollection
;
if
(
_fixedSizeCards
)
{
if
(
_fixedSizeCards
)
{
cardCollection
=
new
ScrollableList
<
CardModel
>
(
cardCollection
=
new
ScrollableList
2
(
snapOffsetCallback:
_snapToCenter
?
_toSnapOffset
:
null
,
snapOffsetCallback:
_snapToCenter
?
_toSnapOffset
:
null
,
snapAlignmentOffset:
_cardCollectionSize
.
height
/
2.0
,
snapAlignmentOffset:
_cardCollectionSize
.
height
/
2.0
,
items:
_cardModels
,
itemExtent:
_cardModels
[
0
].
height
,
itemBuilder:
(
BuildContext
context
,
CardModel
card
,
int
index
)
=>
_buildCard
(
context
,
card
.
value
),
children:
_cardModels
.
map
((
CardModel
card
)
=>
_buildCard
(
context
,
card
.
value
))
itemExtent:
_cardModels
[
0
].
height
);
);
}
else
{
}
else
{
cardCollection
=
new
ScrollableMixedWidgetList
(
cardCollection
=
new
ScrollableMixedWidgetList
(
...
...
examples/widgets/media_query.dart
View file @
c4faad11
...
@@ -74,12 +74,12 @@ class MediaQueryExample extends StatelessComponent {
...
@@ -74,12 +74,12 @@ class MediaQueryExample extends StatelessComponent {
if
(
MediaQuery
.
of
(
context
).
size
.
width
<
_gridViewBreakpoint
)
{
if
(
MediaQuery
.
of
(
context
).
size
.
width
<
_gridViewBreakpoint
)
{
return
new
ScrollableList2
(
return
new
ScrollableList2
(
itemExtent:
50.0
,
itemExtent:
50.0
,
children:
items
.
map
((
AdaptiveItem
item
)
=>
item
.
toListItem
())
.
toList
()
children:
items
.
map
((
AdaptiveItem
item
)
=>
item
.
toListItem
())
);
);
}
else
{
}
else
{
return
new
ScrollableGrid
(
return
new
ScrollableGrid
(
delegate:
new
MaxTileWidthGridDelegate
(
maxTileWidth:
_maxTileWidth
),
delegate:
new
MaxTileWidthGridDelegate
(
maxTileWidth:
_maxTileWidth
),
children:
items
.
map
((
AdaptiveItem
item
)
=>
item
.
toCard
())
.
toList
()
children:
items
.
map
((
AdaptiveItem
item
)
=>
item
.
toCard
())
);
);
}
}
}
}
...
...
examples/widgets/scrollbar.dart
View file @
c4faad11
...
@@ -5,6 +5,21 @@
...
@@ -5,6 +5,21 @@
import
'package:intl/intl.dart'
;
import
'package:intl/intl.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
final
NumberFormat
_dd
=
new
NumberFormat
(
"00"
,
"en_US"
);
class
_Item
extends
StatelessComponent
{
_Item
(
this
.
index
);
int
index
;
Widget
build
(
BuildContext
context
)
{
return
new
Text
(
'Item
${_dd.format(index)}
'
,
key:
new
ValueKey
<
int
>(
index
),
style:
Theme
.
of
(
context
).
text
.
title
);
}
}
class
ScrollbarApp
extends
StatefulComponent
{
class
ScrollbarApp
extends
StatefulComponent
{
ScrollbarAppState
createState
()
=>
new
ScrollbarAppState
();
ScrollbarAppState
createState
()
=>
new
ScrollbarAppState
();
}
}
...
@@ -15,17 +30,10 @@ class ScrollbarAppState extends State<ScrollbarApp> {
...
@@ -15,17 +30,10 @@ class ScrollbarAppState extends State<ScrollbarApp> {
final
ScrollbarPainter
_scrollbarPainter
=
new
ScrollbarPainter
();
final
ScrollbarPainter
_scrollbarPainter
=
new
ScrollbarPainter
();
Widget
_buildMenu
(
BuildContext
context
)
{
Widget
_buildMenu
(
BuildContext
context
)
{
NumberFormat
dd
=
new
NumberFormat
(
"00"
,
"en_US"
);
return
new
ScrollableList2
(
return
new
ScrollableList
<
int
>(
items:
new
List
<
int
>.
generate
(
_itemCount
,
(
int
i
)
=>
i
),
itemExtent:
_itemExtent
,
itemExtent:
_itemExtent
,
itemBuilder:
(
_
,
__
,
int
index
)
{
scrollableListPainter:
_scrollbarPainter
,
return
new
Text
(
'Item
${dd.format(index)}
'
,
children:
new
List
<
Widget
>.
generate
(
_itemCount
,
(
int
i
)
=>
new
_Item
(
i
))
key:
new
ValueKey
<
int
>(
index
),
style:
Theme
.
of
(
context
).
text
.
title
);
},
scrollableListPainter:
_scrollbarPainter
);
);
}
}
...
...
packages/flutter/lib/src/material/material_list.dart
View file @
c4faad11
...
@@ -21,44 +21,35 @@ Map<MaterialListType, double> _kItemExtent = const <MaterialListType, double>{
...
@@ -21,44 +21,35 @@ Map<MaterialListType, double> _kItemExtent = const <MaterialListType, double>{
MaterialListType
.
threeLine
:
kThreeLineListItemHeight
,
MaterialListType
.
threeLine
:
kThreeLineListItemHeight
,
};
};
class
MaterialList
<
T
>
extends
StatefulComponent
{
class
MaterialList
extends
StatefulComponent
{
MaterialList
({
MaterialList
({
Key
key
,
Key
key
,
this
.
initialScrollOffset
,
this
.
initialScrollOffset
,
this
.
onScroll
,
this
.
onScroll
,
this
.
items
,
this
.
type
:
MaterialListType
.
twoLine
,
this
.
itemBuilder
,
this
.
children
this
.
type
:
MaterialListType
.
twoLine
})
:
super
(
key:
key
);
})
:
super
(
key:
key
);
final
double
initialScrollOffset
;
final
double
initialScrollOffset
;
final
ScrollListener
onScroll
;
final
ScrollListener
onScroll
;
final
List
<
T
>
items
;
final
ItemBuilder
<
T
>
itemBuilder
;
final
MaterialListType
type
;
final
MaterialListType
type
;
final
Iterable
<
Widget
>
children
;
_MaterialListState
<
T
>
createState
()
=>
new
_MaterialListState
<
T
>
();
_MaterialListState
createState
()
=>
new
_MaterialListState
();
}
}
class
_MaterialListState
<
T
>
extends
State
<
MaterialList
<
T
>>
{
class
_MaterialListState
extends
State
<
MaterialList
>
{
ScrollbarPainter
_scrollbarPainter
=
new
ScrollbarPainter
();
void
initState
()
{
super
.
initState
();
_scrollbarPainter
=
new
ScrollbarPainter
();
}
ScrollbarPainter
_scrollbarPainter
;
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
new
ScrollableList
<
T
>
(
return
new
ScrollableList
2
(
initialScrollOffset:
config
.
initialScrollOffset
,
initialScrollOffset:
config
.
initialScrollOffset
,
scrollDirection:
ScrollDirection
.
vertical
,
scrollDirection:
ScrollDirection
.
vertical
,
onScroll:
config
.
onScroll
,
onScroll:
config
.
onScroll
,
items:
config
.
items
,
itemBuilder:
config
.
itemBuilder
,
itemExtent:
_kItemExtent
[
config
.
type
],
itemExtent:
_kItemExtent
[
config
.
type
],
padding:
const
EdgeDims
.
symmetric
(
vertical:
8.0
),
padding:
const
EdgeDims
.
symmetric
(
vertical:
8.0
),
scrollableListPainter:
_scrollbarPainter
scrollableListPainter:
_scrollbarPainter
,
children:
config
.
children
);
);
}
}
}
}
packages/flutter/lib/src/material/scrollbar_painter.dart
View file @
c4faad11
...
@@ -30,22 +30,25 @@ class ScrollbarPainter extends ScrollableListPainter {
...
@@ -30,22 +30,25 @@ class ScrollbarPainter extends ScrollableListPainter {
Point
thumbOrigin
;
Point
thumbOrigin
;
Size
thumbSize
;
Size
thumbSize
;
if
(
isVertical
)
{
switch
(
scrollDirection
)
{
double
thumbHeight
=
viewportBounds
.
height
*
viewportBounds
.
height
/
contentExtent
;
case
ScrollDirection
.
vertical
:
thumbHeight
=
thumbHeight
.
clamp
(
_kMinScrollbarThumbLength
,
viewportBounds
.
height
);
double
thumbHeight
=
viewportBounds
.
height
*
viewportBounds
.
height
/
contentExtent
;
final
double
maxThumbTop
=
viewportBounds
.
height
-
thumbHeight
;
thumbHeight
=
thumbHeight
.
clamp
(
_kMinScrollbarThumbLength
,
viewportBounds
.
height
);
double
thumbTop
=
(
scrollOffset
/
(
contentExtent
-
viewportBounds
.
height
))
*
maxThumbTop
;
final
double
maxThumbTop
=
viewportBounds
.
height
-
thumbHeight
;
thumbTop
=
viewportBounds
.
top
+
thumbTop
.
clamp
(
0.0
,
maxThumbTop
);
double
thumbTop
=
(
scrollOffset
/
(
contentExtent
-
viewportBounds
.
height
))
*
maxThumbTop
;
thumbOrigin
=
new
Point
(
viewportBounds
.
right
-
_kScrollbarThumbGirth
,
thumbTop
);
thumbTop
=
viewportBounds
.
top
+
thumbTop
.
clamp
(
0.0
,
maxThumbTop
);
thumbSize
=
new
Size
(
_kScrollbarThumbGirth
,
thumbHeight
);
thumbOrigin
=
new
Point
(
viewportBounds
.
right
-
_kScrollbarThumbGirth
,
thumbTop
);
}
else
{
thumbSize
=
new
Size
(
_kScrollbarThumbGirth
,
thumbHeight
);
double
thumbWidth
=
viewportBounds
.
width
*
viewportBounds
.
width
/
contentExtent
;
break
;
thumbWidth
=
thumbWidth
.
clamp
(
_kMinScrollbarThumbLength
,
viewportBounds
.
width
);
case
ScrollDirection
.
horizontal
:
final
double
maxThumbLeft
=
viewportBounds
.
width
-
thumbWidth
;
double
thumbWidth
=
viewportBounds
.
width
*
viewportBounds
.
width
/
contentExtent
;
double
thumbLeft
=
(
scrollOffset
/
(
contentExtent
-
viewportBounds
.
width
))
*
maxThumbLeft
;
thumbWidth
=
thumbWidth
.
clamp
(
_kMinScrollbarThumbLength
,
viewportBounds
.
width
);
thumbLeft
=
viewportBounds
.
left
+
thumbLeft
.
clamp
(
0.0
,
maxThumbLeft
);
final
double
maxThumbLeft
=
viewportBounds
.
width
-
thumbWidth
;
thumbOrigin
=
new
Point
(
thumbLeft
,
viewportBounds
.
height
-
_kScrollbarThumbGirth
);
double
thumbLeft
=
(
scrollOffset
/
(
contentExtent
-
viewportBounds
.
width
))
*
maxThumbLeft
;
thumbSize
=
new
Size
(
thumbWidth
,
_kScrollbarThumbGirth
);
thumbLeft
=
viewportBounds
.
left
+
thumbLeft
.
clamp
(
0.0
,
maxThumbLeft
);
thumbOrigin
=
new
Point
(
thumbLeft
,
viewportBounds
.
height
-
_kScrollbarThumbGirth
);
thumbSize
=
new
Size
(
thumbWidth
,
_kScrollbarThumbGirth
);
break
;
}
}
paintThumb
(
context
,
thumbOrigin
&
thumbSize
);
paintThumb
(
context
,
thumbOrigin
&
thumbSize
);
...
@@ -65,7 +68,7 @@ class ScrollbarPainter extends ScrollableListPainter {
...
@@ -65,7 +68,7 @@ class ScrollbarPainter extends ScrollableListPainter {
..
variable
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
Curves
.
ease
)
..
variable
=
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
Curves
.
ease
)
..
addListener
(()
{
..
addListener
(()
{
_opacity
=
_fade
.
value
;
_opacity
=
_fade
.
value
;
render
er
?.
markNeedsPaint
();
render
Object
?.
markNeedsPaint
();
});
});
return
_fade
.
forward
();
return
_fade
.
forward
();
}
}
...
...
packages/flutter/lib/src/rendering/block.dart
View file @
c4faad11
...
@@ -8,6 +8,7 @@ import 'package:vector_math/vector_math_64.dart';
...
@@ -8,6 +8,7 @@ import 'package:vector_math/vector_math_64.dart';
import
'box.dart'
;
import
'box.dart'
;
import
'object.dart'
;
import
'object.dart'
;
import
'viewport.dart'
;
/// Parent data for use with [RenderBlockBase].
/// Parent data for use with [RenderBlockBase].
class
BlockParentData
extends
ContainerBoxParentDataMixin
<
RenderBox
>
{
}
class
BlockParentData
extends
ContainerBoxParentDataMixin
<
RenderBox
>
{
}
...
@@ -32,8 +33,10 @@ typedef double _Constrainer(double value);
...
@@ -32,8 +33,10 @@ typedef double _Constrainer(double value);
/// children. Because blocks expand in the main axis, blocks must be given
/// children. Because blocks expand in the main axis, blocks must be given
/// unlimited space in the main axis, typically by being contained in a
/// unlimited space in the main axis, typically by being contained in a
/// viewport with a scrolling direction that matches the block's main axis.
/// viewport with a scrolling direction that matches the block's main axis.
abstract
class
RenderBlockBase
extends
RenderBox
with
ContainerRenderObjectMixin
<
RenderBox
,
BlockParentData
>,
abstract
class
RenderBlockBase
extends
RenderBox
RenderBoxContainerDefaultsMixin
<
RenderBox
,
BlockParentData
>
{
with
ContainerRenderObjectMixin
<
RenderBox
,
BlockParentData
>,
RenderBoxContainerDefaultsMixin
<
RenderBox
,
BlockParentData
>
implements
HasScrollDirection
{
RenderBlockBase
({
RenderBlockBase
({
List
<
RenderBox
>
children
,
List
<
RenderBox
>
children
,
...
@@ -82,6 +85,9 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
...
@@ -82,6 +85,9 @@ abstract class RenderBlockBase extends RenderBox with ContainerRenderObjectMixin
/// Whether the main axis is vertical.
/// Whether the main axis is vertical.
bool
get
isVertical
=>
_direction
==
BlockDirection
.
vertical
;
bool
get
isVertical
=>
_direction
==
BlockDirection
.
vertical
;
// TODO(abarth): Remove BlockDirection in favor of ScrollDirection.
ScrollDirection
get
scrollDirection
=>
isVertical
?
ScrollDirection
.
vertical
:
ScrollDirection
.
horizontal
;
BoxConstraints
_getInnerConstraints
(
BoxConstraints
constraints
)
{
BoxConstraints
_getInnerConstraints
(
BoxConstraints
constraints
)
{
if
(
isVertical
)
if
(
isVertical
)
return
new
BoxConstraints
.
tightFor
(
width:
constraints
.
constrainWidth
(
constraints
.
maxWidth
),
return
new
BoxConstraints
.
tightFor
(
width:
constraints
.
constrainWidth
(
constraints
.
maxWidth
),
...
...
packages/flutter/lib/src/rendering/list.dart
View file @
c4faad11
...
@@ -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
'box.dart'
;
import
'box.dart'
;
import
'object.dart'
;
import
'object.dart'
;
import
'viewport.dart'
;
import
'viewport.dart'
;
...
@@ -9,18 +11,23 @@ import 'viewport.dart';
...
@@ -9,18 +11,23 @@ import 'viewport.dart';
/// Parent data for use with [RenderList].
/// Parent data for use with [RenderList].
class
ListParentData
extends
ContainerBoxParentDataMixin
<
RenderBox
>
{
}
class
ListParentData
extends
ContainerBoxParentDataMixin
<
RenderBox
>
{
}
class
RenderList
extends
RenderVirtualViewport
<
ListParentData
>
{
class
RenderList
extends
RenderVirtualViewport
<
ListParentData
>
implements
HasScrollDirection
{
RenderList
({
RenderList
({
List
<
RenderBox
>
children
,
List
<
RenderBox
>
children
,
double
itemExtent
,
double
itemExtent
,
EdgeDims
padding
,
int
virtualChildCount
,
int
virtualChildCount
,
Offset
paintOffset:
Offset
.
zero
,
Offset
paintOffset:
Offset
.
zero
,
ScrollDirection
scrollDirection:
ScrollDirection
.
vertical
,
LayoutCallback
callback
LayoutCallback
callback
})
:
_itemExtent
=
itemExtent
,
super
(
})
:
_itemExtent
=
itemExtent
,
virtualChildCount:
virtualChildCount
,
_padding
=
padding
,
paintOffset:
paintOffset
,
_scrollDirection
=
scrollDirection
,
callback:
callback
super
(
)
{
virtualChildCount:
virtualChildCount
,
paintOffset:
paintOffset
,
callback:
callback
)
{
assert
(
itemExtent
!=
null
);
assert
(
itemExtent
!=
null
);
addAll
(
children
);
addAll
(
children
);
}
}
...
@@ -35,50 +42,124 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
...
@@ -35,50 +42,124 @@ class RenderList extends RenderVirtualViewport<ListParentData> {
markNeedsLayout
();
markNeedsLayout
();
}
}
EdgeDims
get
padding
=>
_padding
;
EdgeDims
_padding
;
void
set
padding
(
EdgeDims
newValue
)
{
if
(
_padding
==
newValue
)
return
;
_padding
=
newValue
;
markNeedsLayout
();
}
ScrollDirection
get
scrollDirection
=>
_scrollDirection
;
ScrollDirection
_scrollDirection
;
void
set
scrollDirection
(
ScrollDirection
newValue
)
{
if
(
_scrollDirection
==
newValue
)
return
;
_scrollDirection
=
newValue
;
markNeedsLayout
();
}
void
setupParentData
(
RenderBox
child
)
{
void
setupParentData
(
RenderBox
child
)
{
if
(
child
.
parentData
is
!
ListParentData
)
if
(
child
.
parentData
is
!
ListParentData
)
child
.
parentData
=
new
ListParentData
();
child
.
parentData
=
new
ListParentData
();
}
}
double
get
_preferredMainAxisExtent
=>
itemExtent
*
virtualChildCount
;
double
get
_scrollAxisPadding
{
switch
(
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
return
padding
.
vertical
;
case
ScrollDirection
.
horizontal
:
return
padding
.
horizontal
;
}
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
get
_preferredExtent
{
double
extent
=
itemExtent
*
virtualChildCount
;
if
(
padding
!=
null
)
extent
+=
_scrollAxisPadding
;
return
extent
;
}
double
_getIntrinsicWidth
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
isNormalized
);
assert
(
constraints
.
isNormalized
);
return
constraints
.
constrainWidth
(
0.0
);
switch
(
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
return
constraints
.
constrainWidth
(
0.0
);
case
ScrollDirection
.
horizontal
:
return
constraints
.
constrainWidth
(
_preferredExtent
);
}
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
_getIntrinsicWidth
(
constraints
);
}
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
return
_getIntrinsicWidth
(
constraints
);
}
double
_getIntrinsicHeight
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
isNormalized
);
assert
(
constraints
.
isNormalized
);
return
constraints
.
constrainWidth
(
0.0
);
switch
(
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
return
constraints
.
constrainHeight
(
_preferredExtent
);
case
ScrollDirection
.
horizontal
:
return
constraints
.
constrainHeight
(
0.0
);
}
}
}
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
isNormalized
);
return
_getIntrinsicHeight
(
constraints
);
return
constraints
.
constrainHeight
(
_preferredMainAxisExtent
);
}
}
double
getMaxIntrinsicHeight
(
BoxConstraints
constraints
)
{
double
getMaxIntrinsicHeight
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
isNormalized
);
return
_getIntrinsicHeight
(
constraints
);
return
constraints
.
constrainHeight
(
_preferredMainAxisExtent
);
}
}
void
performLayout
()
{
void
performLayout
()
{
double
height
=
_preferredMainAxisExtent
;
size
=
new
Size
(
constraints
.
maxWidth
,
size
=
new
Size
(
constraints
.
maxWidth
,
constraints
.
constrainHeight
(
heigh
t
));
constraints
.
constrainHeight
(
_preferredExten
t
));
if
(
callback
!=
null
)
if
(
callback
!=
null
)
invokeLayoutCallback
(
callback
);
invokeLayoutCallback
(
callback
);
double
itemWidth
;
double
itemHeight
;
double
x
=
0.0
;
double
dx
=
0.0
;
double
y
=
0.0
;
double
dy
=
0.0
;
switch
(
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
itemWidth
=
math
.
max
(
0
,
size
.
width
-
(
padding
==
null
?
0.0
:
padding
.
horizontal
));
itemHeight
=
itemExtent
;
y
=
padding
!=
null
?
padding
.
top
:
0.0
;
dy
=
itemExtent
;
break
;
case
ScrollDirection
.
horizontal
:
itemWidth
=
itemExtent
;
itemHeight
=
math
.
max
(
0
,
size
.
height
-
(
padding
==
null
?
0.0
:
padding
.
vertical
));
x
=
padding
!=
null
?
padding
.
left
:
0.0
;
dx
=
itemExtent
;
break
;
}
BoxConstraints
innerConstraints
=
BoxConstraints
innerConstraints
=
new
BoxConstraints
.
tightFor
(
width:
size
.
width
,
height:
itemExten
t
);
new
BoxConstraints
.
tightFor
(
width:
itemWidth
,
height:
itemHeigh
t
);
int
childIndex
=
0
;
RenderBox
child
=
firstChild
;
RenderBox
child
=
firstChild
;
while
(
child
!=
null
)
{
while
(
child
!=
null
)
{
child
.
layout
(
innerConstraints
);
child
.
layout
(
innerConstraints
);
final
ListParentData
childParentData
=
child
.
parentData
;
final
ListParentData
childParentData
=
child
.
parentData
;
childParentData
.
offset
=
new
Offset
(
0.0
,
childIndex
*
itemExtent
);
childParentData
.
offset
=
new
Offset
(
x
,
y
);
childIndex
+=
1
;
x
+=
dx
;
y
+=
dy
;
assert
(
child
.
parentData
==
childParentData
);
assert
(
child
.
parentData
==
childParentData
);
child
=
childParentData
.
nextSibling
;
child
=
childParentData
.
nextSibling
;
}
}
...
...
packages/flutter/lib/src/rendering/viewport.dart
View file @
c4faad11
...
@@ -18,6 +18,10 @@ enum ScrollDirection {
...
@@ -18,6 +18,10 @@ enum ScrollDirection {
vertical
,
vertical
,
}
}
abstract
class
HasScrollDirection
{
ScrollDirection
get
scrollDirection
;
}
/// A render object that's bigger on the inside.
/// A render object that's bigger on the inside.
///
///
/// The child of a viewport can layout to a larger size than the viewport
/// The child of a viewport can layout to a larger size than the viewport
...
@@ -27,7 +31,8 @@ enum ScrollDirection {
...
@@ -27,7 +31,8 @@ enum ScrollDirection {
///
///
/// Viewport is the core scrolling primitive in the system, but it can be used
/// Viewport is the core scrolling primitive in the system, but it can be used
/// in other situations.
/// in other situations.
class
RenderViewport
extends
RenderBox
with
RenderObjectWithChildMixin
<
RenderBox
>
{
class
RenderViewport
extends
RenderBox
with
RenderObjectWithChildMixin
<
RenderBox
>
implements
HasScrollDirection
{
RenderViewport
({
RenderViewport
({
RenderBox
child
,
RenderBox
child
,
...
@@ -177,10 +182,12 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
...
@@ -177,10 +182,12 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
RenderVirtualViewport
({
RenderVirtualViewport
({
int
virtualChildCount
,
int
virtualChildCount
,
Offset
paintOffset
,
Offset
paintOffset
,
LayoutCallback
callback
LayoutCallback
callback
,
Painter
overlayPainter
})
:
_virtualChildCount
=
virtualChildCount
,
})
:
_virtualChildCount
=
virtualChildCount
,
_paintOffset
=
paintOffset
,
_paintOffset
=
paintOffset
,
_callback
=
callback
;
_callback
=
callback
,
_overlayPainter
=
overlayPainter
;
int
get
virtualChildCount
=>
_virtualChildCount
??
childCount
;
int
get
virtualChildCount
=>
_virtualChildCount
??
childCount
;
int
_virtualChildCount
;
int
_virtualChildCount
;
...
@@ -217,8 +224,31 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
...
@@ -217,8 +224,31 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
markNeedsLayout
();
markNeedsLayout
();
}
}
Painter
get
overlayPainter
=>
_overlayPainter
;
Painter
_overlayPainter
;
void
set
overlayPainter
(
Painter
value
)
{
if
(
_overlayPainter
==
value
)
return
;
if
(
attached
)
_overlayPainter
?.
detach
();
_overlayPainter
=
value
;
if
(
attached
)
_overlayPainter
?.
attach
(
this
);
markNeedsPaint
();
}
void
attach
()
{
super
.
attach
();
_overlayPainter
?.
attach
(
this
);
}
void
detach
()
{
super
.
detach
();
_overlayPainter
?.
detach
();
}
void
applyPaintTransform
(
RenderBox
child
,
Matrix4
transform
)
{
void
applyPaintTransform
(
RenderBox
child
,
Matrix4
transform
)
{
super
.
applyPaintTransform
(
child
,
transform
.
translate
(
paintOffset
));
super
.
applyPaintTransform
(
child
,
transform
.
translate
(
paintOffset
.
dx
,
paintOffset
.
dy
));
}
}
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
...
@@ -227,6 +257,7 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
...
@@ -227,6 +257,7 @@ abstract class RenderVirtualViewport<T extends ContainerBoxParentDataMixin<Rende
void
_paintContents
(
PaintingContext
context
,
Offset
offset
)
{
void
_paintContents
(
PaintingContext
context
,
Offset
offset
)
{
defaultPaint
(
context
,
offset
+
paintOffset
);
defaultPaint
(
context
,
offset
+
paintOffset
);
_overlayPainter
?.
paint
(
context
,
offset
);
}
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
...
...
packages/flutter/lib/src/widgets/scrollable.dart
View file @
c4faad11
...
@@ -445,15 +445,19 @@ class Block extends StatelessComponent {
...
@@ -445,15 +445,19 @@ class Block extends StatelessComponent {
abstract
class
ScrollableListPainter
extends
Painter
{
abstract
class
ScrollableListPainter
extends
Painter
{
void
attach
(
RenderObject
renderObject
)
{
void
attach
(
RenderObject
renderObject
)
{
assert
(
renderObject
is
RenderBlockViewport
);
assert
(
renderObject
is
RenderBox
);
assert
(
renderObject
is
HasScrollDirection
);
super
.
attach
(
renderObject
);
super
.
attach
(
renderObject
);
}
}
RenderB
lockViewport
get
renderer
=>
renderObject
;
RenderB
ox
get
renderObject
=>
super
.
renderObject
;
bool
get
isVertical
=>
renderer
.
isVertical
;
ScrollDirection
get
scrollDirection
{
HasScrollDirection
scrollable
=
renderObject
as
dynamic
;
return
scrollable
?.
scrollDirection
;
}
Size
get
viewportSize
=>
render
er
.
size
;
Size
get
viewportSize
=>
render
Object
.
size
;
double
get
contentExtent
=>
_contentExtent
;
double
get
contentExtent
=>
_contentExtent
;
double
_contentExtent
=
0.0
;
double
_contentExtent
=
0.0
;
...
@@ -463,7 +467,7 @@ abstract class ScrollableListPainter extends Painter {
...
@@ -463,7 +467,7 @@ abstract class ScrollableListPainter extends Painter {
if
(
_contentExtent
==
value
)
if
(
_contentExtent
==
value
)
return
;
return
;
_contentExtent
=
value
;
_contentExtent
=
value
;
render
er
?.
markNeedsPaint
();
render
Object
?.
markNeedsPaint
();
}
}
double
get
scrollOffset
=>
_scrollOffset
;
double
get
scrollOffset
=>
_scrollOffset
;
...
@@ -473,7 +477,7 @@ abstract class ScrollableListPainter extends Painter {
...
@@ -473,7 +477,7 @@ abstract class ScrollableListPainter extends Painter {
if
(
_scrollOffset
==
value
)
if
(
_scrollOffset
==
value
)
return
;
return
;
_scrollOffset
=
value
;
_scrollOffset
=
value
;
render
er
?.
markNeedsPaint
();
render
Object
?.
markNeedsPaint
();
}
}
/// Called when a scroll starts. Subclasses may override this method to
/// Called when a scroll starts. Subclasses may override this method to
...
@@ -675,7 +679,7 @@ class ScrollableList<T> extends ScrollableWidgetList {
...
@@ -675,7 +679,7 @@ class ScrollableList<T> extends ScrollableWidgetList {
double
snapAlignmentOffset:
0.0
,
double
snapAlignmentOffset:
0.0
,
this
.
items
,
this
.
items
,
this
.
itemBuilder
,
this
.
itemBuilder
,
itemsWrap:
false
,
bool
itemsWrap:
false
,
double
itemExtent
,
double
itemExtent
,
EdgeDims
padding
,
EdgeDims
padding
,
ScrollableListPainter
scrollableListPainter
ScrollableListPainter
scrollableListPainter
...
...
packages/flutter/lib/src/widgets/scrollable_grid.dart
View file @
c4faad11
...
@@ -36,7 +36,7 @@ class ScrollableGrid extends Scrollable {
...
@@ -36,7 +36,7 @@ class ScrollableGrid extends Scrollable {
);
);
final
GridDelegate
delegate
;
final
GridDelegate
delegate
;
final
List
<
Widget
>
children
;
final
Iterable
<
Widget
>
children
;
ScrollableState
createState
()
=>
new
_ScrollableGridState
();
ScrollableState
createState
()
=>
new
_ScrollableGridState
();
}
}
...
@@ -77,7 +77,10 @@ class GridViewport extends VirtualViewport {
...
@@ -77,7 +77,10 @@ class GridViewport extends VirtualViewport {
final
double
startOffset
;
final
double
startOffset
;
final
GridDelegate
delegate
;
final
GridDelegate
delegate
;
final
ExtentsChangedCallback
onExtentsChanged
;
final
ExtentsChangedCallback
onExtentsChanged
;
final
List
<
Widget
>
children
;
final
Iterable
<
Widget
>
children
;
// TODO(abarth): Support horizontal scrolling;
ScrollDirection
get
scrollDirection
=>
ScrollDirection
.
vertical
;
RenderGrid
createRenderObject
()
=>
new
RenderGrid
(
delegate:
delegate
);
RenderGrid
createRenderObject
()
=>
new
RenderGrid
(
delegate:
delegate
);
...
@@ -136,8 +139,8 @@ class _GridViewportElement extends VirtualViewportElement<GridViewport> {
...
@@ -136,8 +139,8 @@ class _GridViewportElement extends VirtualViewportElement<GridViewport> {
int
materializedRowBase
=
math
.
max
(
0
,
_lowerBound
(
_specification
.
rowOffsets
,
widget
.
startOffset
)
-
1
);
int
materializedRowBase
=
math
.
max
(
0
,
_lowerBound
(
_specification
.
rowOffsets
,
widget
.
startOffset
)
-
1
);
int
materializedRowLimit
=
math
.
min
(
_specification
.
rowCount
,
_lowerBound
(
_specification
.
rowOffsets
,
widget
.
startOffset
+
containerExtent
));
int
materializedRowLimit
=
math
.
min
(
_specification
.
rowCount
,
_lowerBound
(
_specification
.
rowOffsets
,
widget
.
startOffset
+
containerExtent
));
_materializedChildBase
=
(
materializedRowBase
*
_specification
.
columnCount
).
clamp
(
0
,
widget
.
children
.
length
);
_materializedChildBase
=
(
materializedRowBase
*
_specification
.
columnCount
).
clamp
(
0
,
renderObject
.
virtualChildCount
);
_materializedChildCount
=
(
materializedRowLimit
*
_specification
.
columnCount
).
clamp
(
0
,
widget
.
children
.
length
)
-
_materializedChildBase
;
_materializedChildCount
=
(
materializedRowLimit
*
_specification
.
columnCount
).
clamp
(
0
,
renderObject
.
virtualChildCount
)
-
_materializedChildBase
;
_repaintOffsetBase
=
_specification
.
rowOffsets
[
materializedRowBase
];
_repaintOffsetBase
=
_specification
.
rowOffsets
[
materializedRowBase
];
_repaintOffsetLimit
=
_specification
.
rowOffsets
[
materializedRowLimit
];
_repaintOffsetLimit
=
_specification
.
rowOffsets
[
materializedRowLimit
];
...
...
packages/flutter/lib/src/widgets/scrollable_list.dart
View file @
c4faad11
...
@@ -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
'framework.dart'
;
import
'framework.dart'
;
import
'scrollable.dart'
;
import
'scrollable.dart'
;
import
'virtual_viewport.dart'
;
import
'virtual_viewport.dart'
;
...
@@ -13,23 +15,31 @@ class ScrollableList2 extends Scrollable {
...
@@ -13,23 +15,31 @@ class ScrollableList2 extends Scrollable {
ScrollableList2
({
ScrollableList2
({
Key
key
,
Key
key
,
double
initialScrollOffset
,
double
initialScrollOffset
,
ScrollDirection
scrollDirection:
ScrollDirection
.
vertical
,
ScrollListener
onScroll
,
ScrollListener
onScroll
,
SnapOffsetCallback
snapOffsetCallback
,
SnapOffsetCallback
snapOffsetCallback
,
double
snapAlignmentOffset:
0.0
,
double
snapAlignmentOffset:
0.0
,
this
.
itemExtent
,
this
.
itemExtent
,
this
.
itemsWrap
:
false
,
this
.
padding
,
this
.
scrollableListPainter
,
this
.
children
this
.
children
})
:
super
(
})
:
super
(
key:
key
,
key:
key
,
initialScrollOffset:
initialScrollOffset
,
initialScrollOffset:
initialScrollOffset
,
// TODO(abarth): Support horizontal offsets.
scrollDirection:
scrollDirection
,
scrollDirection:
ScrollDirection
.
vertical
,
onScroll:
onScroll
,
onScroll:
onScroll
,
snapOffsetCallback:
snapOffsetCallback
,
snapOffsetCallback:
snapOffsetCallback
,
snapAlignmentOffset:
snapAlignmentOffset
snapAlignmentOffset:
snapAlignmentOffset
);
)
{
assert
(
itemExtent
!=
null
);
}
final
double
itemExtent
;
final
double
itemExtent
;
final
List
<
Widget
>
children
;
final
bool
itemsWrap
;
final
EdgeDims
padding
;
final
ScrollableListPainter
scrollableListPainter
;
final
Iterable
<
Widget
>
children
;
ScrollableState
createState
()
=>
new
_ScrollableList2State
();
ScrollableState
createState
()
=>
new
_ScrollableList2State
();
}
}
...
@@ -39,20 +49,40 @@ class _ScrollableList2State extends ScrollableState<ScrollableList2> {
...
@@ -39,20 +49,40 @@ class _ScrollableList2State extends ScrollableState<ScrollableList2> {
ExtentScrollBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
ExtentScrollBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
void
_handleExtentsChanged
(
double
contentExtent
,
double
containerExtent
)
{
void
_handleExtentsChanged
(
double
contentExtent
,
double
containerExtent
)
{
config
.
scrollableListPainter
?.
contentExtent
=
contentExtent
;
setState
(()
{
setState
(()
{
scrollTo
(
scrollBehavior
.
updateExtents
(
scrollTo
(
scrollBehavior
.
updateExtents
(
contentExtent:
contentExtent
,
contentExtent:
con
fig
.
itemsWrap
?
double
.
INFINITY
:
con
tentExtent
,
containerExtent:
containerExtent
,
containerExtent:
containerExtent
,
scrollOffset:
scrollOffset
scrollOffset:
scrollOffset
));
));
});
});
}
}
void
dispatchOnScrollStart
()
{
super
.
dispatchOnScrollStart
();
config
.
scrollableListPainter
?.
scrollStarted
();
}
void
dispatchOnScroll
()
{
super
.
dispatchOnScroll
();
config
.
scrollableListPainter
?.
scrollOffset
=
scrollOffset
;
}
void
dispatchOnScrollEnd
()
{
super
.
dispatchOnScrollEnd
();
config
.
scrollableListPainter
?.
scrollEnded
();
}
Widget
buildContent
(
BuildContext
context
)
{
Widget
buildContent
(
BuildContext
context
)
{
return
new
ListViewport
(
return
new
ListViewport
(
onExtentsChanged:
_handleExtentsChanged
,
startOffset:
scrollOffset
,
startOffset:
scrollOffset
,
scrollDirection:
config
.
scrollDirection
,
itemExtent:
config
.
itemExtent
,
itemExtent:
config
.
itemExtent
,
onExtentsChanged:
_handleExtentsChanged
,
itemsWrap:
config
.
itemsWrap
,
padding:
config
.
padding
,
overlayPainter:
config
.
scrollableListPainter
,
children:
config
.
children
children:
config
.
children
);
);
}
}
...
@@ -61,16 +91,27 @@ class _ScrollableList2State extends ScrollableState<ScrollableList2> {
...
@@ -61,16 +91,27 @@ class _ScrollableList2State extends ScrollableState<ScrollableList2> {
class
ListViewport
extends
VirtualViewport
{
class
ListViewport
extends
VirtualViewport
{
ListViewport
({
ListViewport
({
Key
key
,
Key
key
,
this
.
startOffset
,
this
.
itemExtent
,
this
.
onExtentsChanged
,
this
.
onExtentsChanged
,
this
.
startOffset
:
0.0
,
this
.
scrollDirection
:
ScrollDirection
.
vertical
,
this
.
itemExtent
,
this
.
itemsWrap
:
false
,
this
.
padding
,
this
.
overlayPainter
,
this
.
children
this
.
children
});
})
{
assert
(
scrollDirection
!=
null
);
assert
(
itemExtent
!=
null
);
}
final
ExtentsChangedCallback
onExtentsChanged
;
final
double
startOffset
;
final
double
startOffset
;
final
ScrollDirection
scrollDirection
;
final
double
itemExtent
;
final
double
itemExtent
;
final
ExtentsChangedCallback
onExtentsChanged
;
final
bool
itemsWrap
;
final
List
<
Widget
>
children
;
final
EdgeDims
padding
;
final
Painter
overlayPainter
;
final
Iterable
<
Widget
>
children
;
RenderList
createRenderObject
()
=>
new
RenderList
(
itemExtent:
itemExtent
);
RenderList
createRenderObject
()
=>
new
RenderList
(
itemExtent:
itemExtent
);
...
@@ -95,21 +136,39 @@ class _ListViewportElement extends VirtualViewportElement<ListViewport> {
...
@@ -95,21 +136,39 @@ class _ListViewportElement extends VirtualViewportElement<ListViewport> {
double
_repaintOffsetLimit
;
double
_repaintOffsetLimit
;
void
updateRenderObject
()
{
void
updateRenderObject
()
{
renderObject
.
scrollDirection
=
widget
.
scrollDirection
;
renderObject
.
itemExtent
=
widget
.
itemExtent
;
renderObject
.
itemExtent
=
widget
.
itemExtent
;
renderObject
.
padding
=
widget
.
padding
;
renderObject
.
overlayPainter
=
widget
.
overlayPainter
;
super
.
updateRenderObject
();
super
.
updateRenderObject
();
}
}
double
_contentExtent
;
double
_contentExtent
;
double
_containerExtent
;
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
)
{
void
layout
(
BoxConstraints
constraints
)
{
double
contentExtent
=
widget
.
itemExtent
*
widget
.
children
.
length
;
int
length
=
renderObject
.
virtualChildCount
;
double
containerExtent
=
renderObject
.
size
.
height
;
double
contentExtent
=
widget
.
itemExtent
*
length
;
double
containerExtent
=
_getContainerExtentFromRenderObject
();
_materializedChildBase
=
(
widget
.
startOffset
~/
widget
.
itemExtent
).
clamp
(
0
,
widget
.
children
.
length
);
_materializedChildBase
=
math
.
max
(
0
,
widget
.
startOffset
~/
widget
.
itemExtent
);
int
materializedChildLimit
=
((
widget
.
startOffset
+
containerExtent
)
/
widget
.
itemExtent
).
ceil
().
clamp
(
0
,
widget
.
children
.
length
);
int
materializedChildLimit
=
math
.
max
(
0
,
((
widget
.
startOffset
+
containerExtent
)
/
widget
.
itemExtent
).
ceil
());
_materializedChildCount
=
materializedChildLimit
-
_materializedChildBase
;
if
(!
widget
.
itemsWrap
)
{
_materializedChildBase
=
math
.
min
(
length
,
_materializedChildBase
);
materializedChildLimit
=
math
.
min
(
length
,
materializedChildLimit
);
}
_materializedChildCount
=
materializedChildLimit
-
_materializedChildBase
;
_repaintOffsetBase
=
_materializedChildBase
*
widget
.
itemExtent
;
_repaintOffsetBase
=
_materializedChildBase
*
widget
.
itemExtent
;
_repaintOffsetLimit
=
materializedChildLimit
*
widget
.
itemExtent
;
_repaintOffsetLimit
=
materializedChildLimit
*
widget
.
itemExtent
;
...
...
packages/flutter/lib/src/widgets/virtual_viewport.dart
View file @
c4faad11
...
@@ -11,7 +11,8 @@ typedef void ExtentsChangedCallback(double contentExtent, double containerExtent
...
@@ -11,7 +11,8 @@ typedef void ExtentsChangedCallback(double contentExtent, double containerExtent
abstract
class
VirtualViewport
extends
RenderObjectWidget
{
abstract
class
VirtualViewport
extends
RenderObjectWidget
{
double
get
startOffset
;
double
get
startOffset
;
List
<
Widget
>
get
children
;
ScrollDirection
get
scrollDirection
;
Iterable
<
Widget
>
get
children
;
}
}
abstract
class
VirtualViewportElement
<
T
extends
VirtualViewport
>
extends
RenderObjectElement
<
T
>
{
abstract
class
VirtualViewportElement
<
T
extends
VirtualViewport
>
extends
RenderObjectElement
<
T
>
{
...
@@ -35,6 +36,8 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -35,6 +36,8 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
super
.
mount
(
parent
,
newSlot
);
super
.
mount
(
parent
,
newSlot
);
_iterator
=
null
;
_widgets
=
<
Widget
>[];
renderObject
.
callback
=
layout
;
renderObject
.
callback
=
layout
;
updateRenderObject
();
updateRenderObject
();
}
}
...
@@ -45,6 +48,10 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -45,6 +48,10 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
}
}
void
update
(
T
newWidget
)
{
void
update
(
T
newWidget
)
{
if
(
widget
.
children
!=
newWidget
.
children
)
{
_iterator
=
null
;
_widgets
=
<
Widget
>[];
}
super
.
update
(
newWidget
);
super
.
update
(
newWidget
);
updateRenderObject
();
updateRenderObject
();
if
(!
renderObject
.
needsLayout
)
if
(!
renderObject
.
needsLayout
)
...
@@ -52,8 +59,23 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -52,8 +59,23 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
}
}
void
_updatePaintOffset
()
{
void
_updatePaintOffset
()
{
renderObject
.
paintOffset
=
switch
(
widget
.
scrollDirection
)
{
renderObject
.
paintOffset
=
new
Offset
(
0.0
,
-(
widget
.
startOffset
-
repaintOffsetBase
));
case
ScrollDirection
.
vertical
:
renderObject
.
paintOffset
=
new
Offset
(
0.0
,
-(
widget
.
startOffset
-
repaintOffsetBase
));
break
;
case
ScrollDirection
.
horizontal
:
renderObject
.
paintOffset
=
new
Offset
(-(
widget
.
startOffset
-
repaintOffsetBase
),
0.0
);
break
;
}
}
double
get
_containerExtent
{
switch
(
widget
.
scrollDirection
)
{
case
ScrollDirection
.
vertical
:
return
renderObject
.
size
.
height
;
case
ScrollDirection
.
horizontal
:
return
renderObject
.
size
.
width
;
}
}
}
void
updateRenderObject
()
{
void
updateRenderObject
()
{
...
@@ -67,7 +89,7 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -67,7 +89,7 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
if
(!
renderObject
.
needsLayout
)
{
if
(!
renderObject
.
needsLayout
)
{
if
(
repaintOffsetBase
!=
null
&&
widget
.
startOffset
<
repaintOffsetBase
)
if
(
repaintOffsetBase
!=
null
&&
widget
.
startOffset
<
repaintOffsetBase
)
renderObject
.
markNeedsLayout
();
renderObject
.
markNeedsLayout
();
else
if
(
repaintOffsetLimit
!=
null
&&
widget
.
startOffset
+
renderObject
.
size
.
heigh
t
>
repaintOffsetLimit
)
else
if
(
repaintOffsetLimit
!=
null
&&
widget
.
startOffset
+
_containerExten
t
>
repaintOffsetLimit
)
renderObject
.
markNeedsLayout
();
renderObject
.
markNeedsLayout
();
}
}
}
}
...
@@ -80,15 +102,37 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
...
@@ -80,15 +102,37 @@ abstract class VirtualViewportElement<T extends VirtualViewport> extends RenderO
BuildableElement
.
lockState
(
_materializeChildren
);
BuildableElement
.
lockState
(
_materializeChildren
);
}
}
Iterator
<
Widget
>
_iterator
;
List
<
Widget
>
_widgets
;
void
_populateWidgets
(
int
limit
)
{
if
(
limit
<=
_widgets
.
length
)
return
;
if
(
widget
.
children
is
List
<
Widget
>)
{
_widgets
=
widget
.
children
;
return
;
}
_iterator
??=
widget
.
children
.
iterator
;
while
(
_widgets
.
length
<
limit
)
{
bool
moved
=
_iterator
.
moveNext
();
assert
(
moved
);
Widget
current
=
_iterator
.
current
;
assert
(
current
!=
null
);
_widgets
.
add
(
current
);
}
}
void
_materializeChildren
()
{
void
_materializeChildren
()
{
int
base
=
materializedChildBase
;
int
base
=
materializedChildBase
;
int
count
=
materializedChildCount
;
int
count
=
materializedChildCount
;
int
length
=
renderObject
.
virtualChildCount
;
assert
(
base
!=
null
);
assert
(
base
!=
null
);
assert
(
count
!=
null
);
assert
(
count
!=
null
);
_populateWidgets
(
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
=
widget
.
children
[
childIndex
];
Widget
child
=
_widgets
[
childIndex
%
length
];
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/dismissable_test.dart
View file @
c4faad11
...
@@ -21,7 +21,7 @@ void handleOnDismissed(int item) {
...
@@ -21,7 +21,7 @@ void handleOnDismissed(int item) {
dismissedItems
.
add
(
item
);
dismissedItems
.
add
(
item
);
}
}
Widget
buildDismissableItem
(
BuildContext
context
,
int
item
,
int
index
)
{
Widget
buildDismissableItem
(
int
item
)
{
return
new
Dismissable
(
return
new
Dismissable
(
key:
new
ValueKey
<
int
>(
item
),
key:
new
ValueKey
<
int
>(
item
),
direction:
dismissDirection
,
direction:
dismissDirection
,
...
@@ -38,11 +38,12 @@ Widget buildDismissableItem(BuildContext context, int item, int index) {
...
@@ -38,11 +38,12 @@ Widget buildDismissableItem(BuildContext context, int item, int index) {
Widget
widgetBuilder
(
)
{
Widget
widgetBuilder
(
)
{
return
new
Container
(
return
new
Container
(
padding:
const
EdgeDims
.
all
(
10.0
),
padding:
const
EdgeDims
.
all
(
10.0
),
child:
new
ScrollableList
<
int
>(
child:
new
ScrollableList2
(
items:
<
int
>[
0
,
1
,
2
,
3
,
4
].
where
((
int
i
)
=>
!
dismissedItems
.
contains
(
i
)).
toList
(),
itemBuilder:
buildDismissableItem
,
scrollDirection:
scrollDirection
,
scrollDirection:
scrollDirection
,
itemExtent:
itemExtent
itemExtent:
itemExtent
,
children:
<
int
>[
0
,
1
,
2
,
3
,
4
].
where
(
(
int
i
)
=>
!
dismissedItems
.
contains
(
i
)
).
map
(
buildDismissableItem
)
)
)
);
);
}
}
...
...
packages/flutter/test/widget/reparent_state_test.dart
View file @
c4faad11
...
@@ -99,16 +99,15 @@ void main() {
...
@@ -99,16 +99,15 @@ void main() {
(
key
.
currentState
as
StateMarkerState
).
marker
=
"marked"
;
(
key
.
currentState
as
StateMarkerState
).
marker
=
"marked"
;
tester
.
pumpWidget
(
new
ScrollableList
<
int
>(
tester
.
pumpWidget
(
new
ScrollableList2
(
items:
<
int
>[
0
],
itemExtent:
100.0
,
itemExtent:
100.0
,
itemBuilder:
(
BuildContext
context
,
int
item
,
int
index
)
{
children:
<
Widget
>[
return
new
Container
(
new
Container
(
key:
new
Key
(
'container'
),
key:
new
Key
(
'container'
),
height:
100.0
,
height:
100.0
,
child:
new
StateMarker
(
key:
key
)
child:
new
StateMarker
(
key:
key
)
)
;
)
}
]
));
));
expect
((
key
.
currentState
as
StateMarkerState
).
marker
,
equals
(
"marked"
));
expect
((
key
.
currentState
as
StateMarkerState
).
marker
,
equals
(
"marked"
));
...
...
packages/flutter/test/widget/scrollable_list_hit_testing_test.dart
View file @
c4faad11
...
@@ -17,20 +17,18 @@ void main() {
...
@@ -17,20 +17,18 @@ void main() {
tester
.
pumpWidget
(
new
Center
(
tester
.
pumpWidget
(
new
Center
(
child:
new
Container
(
child:
new
Container
(
height:
50.0
,
height:
50.0
,
child:
new
ScrollableList
<
int
>
(
child:
new
ScrollableList
2
(
key:
new
GlobalKey
(),
key:
new
GlobalKey
(),
items:
items
,
itemExtent:
290.0
,
itemBuilder:
(
BuildContext
context
,
int
item
,
int
index
)
{
scrollDirection:
ScrollDirection
.
horizontal
,
children:
items
.
map
((
int
item
)
{
return
new
Container
(
return
new
Container
(
key:
new
ValueKey
<
int
>(
item
),
child:
new
GestureDetector
(
child:
new
GestureDetector
(
onTap:
()
{
tapped
.
add
(
item
);
},
onTap:
()
{
tapped
.
add
(
item
);
},
child:
new
Text
(
'
$item
'
)
child:
new
Text
(
'
$item
'
)
)
)
);
);
},
})
itemExtent:
290.0
,
scrollDirection:
ScrollDirection
.
horizontal
)
)
)
)
));
));
...
@@ -59,20 +57,18 @@ void main() {
...
@@ -59,20 +57,18 @@ void main() {
tester
.
pumpWidget
(
new
Center
(
tester
.
pumpWidget
(
new
Center
(
child:
new
Container
(
child:
new
Container
(
width:
50.0
,
width:
50.0
,
child:
new
ScrollableList
<
int
>
(
child:
new
ScrollableList
2
(
key:
new
GlobalKey
(),
key:
new
GlobalKey
(),
items:
items
,
itemExtent:
290.0
,
itemBuilder:
(
BuildContext
context
,
int
item
,
int
index
)
{
scrollDirection:
ScrollDirection
.
vertical
,
children:
items
.
map
((
int
item
)
{
return
new
Container
(
return
new
Container
(
key:
new
ValueKey
<
int
>(
item
),
child:
new
GestureDetector
(
child:
new
GestureDetector
(
onTap:
()
{
tapped
.
add
(
item
);
},
onTap:
()
{
tapped
.
add
(
item
);
},
child:
new
Text
(
'
$item
'
)
child:
new
Text
(
'
$item
'
)
)
)
);
);
},
})
itemExtent:
290.0
,
scrollDirection:
ScrollDirection
.
vertical
)
)
)
)
));
));
...
...
packages/flutter/test/widget/scrollable_list_horizontal_test.dart
View file @
c4faad11
...
@@ -13,16 +13,14 @@ Widget buildFrame() {
...
@@ -13,16 +13,14 @@ Widget buildFrame() {
return
new
Center
(
return
new
Center
(
child:
new
Container
(
child:
new
Container
(
height:
50.0
,
height:
50.0
,
child:
new
ScrollableList
<
int
>(
child:
new
ScrollableList2
(
items:
items
,
itemExtent:
290.0
,
itemBuilder:
(
BuildContext
context
,
int
item
,
int
index
)
{
scrollDirection:
ScrollDirection
.
horizontal
,
children:
items
.
map
((
int
item
)
{
return
new
Container
(
return
new
Container
(
key:
new
ValueKey
<
int
>(
item
),
child:
new
Text
(
'
$item
'
)
child:
new
Text
(
'
$item
'
)
);
);
},
})
itemExtent:
290.0
,
scrollDirection:
ScrollDirection
.
horizontal
)
)
)
)
);
);
...
...
packages/flutter/test/widget/scrollable_list_vertical_test.dart
View file @
c4faad11
...
@@ -9,16 +9,14 @@ import 'package:test/test.dart';
...
@@ -9,16 +9,14 @@ import 'package:test/test.dart';
const
List
<
int
>
items
=
const
<
int
>[
0
,
1
,
2
,
3
,
4
,
5
];
const
List
<
int
>
items
=
const
<
int
>[
0
,
1
,
2
,
3
,
4
,
5
];
Widget
buildFrame
(
)
{
Widget
buildFrame
(
)
{
return
new
ScrollableList
<
int
>(
return
new
ScrollableList2
(
items:
items
,
itemExtent:
290.0
,
itemBuilder:
(
BuildContext
context
,
int
item
,
int
index
)
{
scrollDirection:
ScrollDirection
.
vertical
,
children:
items
.
map
((
int
item
)
{
return
new
Container
(
return
new
Container
(
key:
new
ValueKey
<
int
>(
item
),
child:
new
Text
(
'
$item
'
)
child:
new
Text
(
'
$item
'
)
);
);
},
})
itemExtent:
290.0
,
scrollDirection:
ScrollDirection
.
vertical
);
);
}
}
...
...
packages/flutter/test/widget/snap_scrolling_test.dart
View file @
c4faad11
...
@@ -12,9 +12,8 @@ const double itemExtent = 200.0;
...
@@ -12,9 +12,8 @@ const double itemExtent = 200.0;
ScrollDirection
scrollDirection
=
ScrollDirection
.
vertical
;
ScrollDirection
scrollDirection
=
ScrollDirection
.
vertical
;
GlobalKey
scrollableListKey
;
GlobalKey
scrollableListKey
;
Widget
buildItem
(
BuildContext
context
,
int
item
,
int
index
)
{
Widget
buildItem
(
int
item
)
{
return
new
Container
(
return
new
Container
(
key:
new
ValueKey
<
int
>(
item
),
width:
itemExtent
,
width:
itemExtent
,
height:
itemExtent
,
height:
itemExtent
,
child:
new
Text
(
item
.
toString
())
child:
new
Text
(
item
.
toString
())
...
@@ -30,13 +29,12 @@ Widget buildFrame() {
...
@@ -30,13 +29,12 @@ Widget buildFrame() {
return
new
Center
(
return
new
Center
(
child:
new
Container
(
child:
new
Container
(
height:
itemExtent
*
2.0
,
height:
itemExtent
*
2.0
,
child:
new
ScrollableList
<
int
>
(
child:
new
ScrollableList
2
(
key:
scrollableListKey
,
key:
scrollableListKey
,
snapOffsetCallback:
snapOffsetCallback
,
snapOffsetCallback:
snapOffsetCallback
,
scrollDirection:
scrollDirection
,
scrollDirection:
scrollDirection
,
items:
<
int
>[
0
,
1
,
2
,
3
,
4
,
5
,
7
,
8
,
9
],
itemExtent:
itemExtent
,
itemBuilder:
buildItem
,
children:
<
int
>[
0
,
1
,
2
,
3
,
4
,
5
,
7
,
8
,
9
].
map
(
buildItem
)
itemExtent:
itemExtent
)
)
)
)
);
);
...
...
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