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
1387bd75
Commit
1387bd75
authored
Jul 30, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #394 from abarth/merge_scrollable
Combine all the scrollable classes into scrollable.dart
parents
7045c782
a740dbd7
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
313 additions
and
331 deletions
+313
-331
main.dart
packages/flutter/example/address_book/lib/main.dart
+1
-1
main.dart
packages/flutter/example/demo_launcher/lib/main.dart
+1
-1
main.dart
packages/flutter/example/fitness/lib/main.dart
+1
-2
main.dart
packages/flutter/example/stocks/lib/main.dart
+18
-19
card_collection.dart
packages/flutter/example/widgets/card_collection.dart
+1
-1
dialog.dart
packages/flutter/lib/widgets/dialog.dart
+1
-1
drawer.dart
packages/flutter/lib/widgets/drawer.dart
+1
-1
fixed_height_scrollable.dart
packages/flutter/lib/widgets/fixed_height_scrollable.dart
+0
-106
popup_menu.dart
packages/flutter/lib/widgets/popup_menu.dart
+1
-1
scrollable.dart
packages/flutter/lib/widgets/scrollable.dart
+288
-1
scrollable_list.dart
packages/flutter/lib/widgets/scrollable_list.dart
+0
-39
scrollable_viewport.dart
packages/flutter/lib/widgets/scrollable_viewport.dart
+0
-67
variable_height_scrollable.dart
packages/flutter/lib/widgets/variable_height_scrollable.dart
+0
-91
No files found.
packages/flutter/example/address_book/lib/main.dart
View file @
1387bd75
...
...
@@ -17,7 +17,7 @@ import 'package:sky/widgets/icon_button.dart';
import
'package:sky/widgets/material.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/scaffold.dart'
;
import
'package:sky/widgets/scrollable
_viewport
.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/task_description.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:sky/widgets/tool_bar.dart'
;
...
...
packages/flutter/example/demo_launcher/lib/main.dart
View file @
1387bd75
...
...
@@ -16,7 +16,7 @@ import 'package:sky/widgets/scaffold.dart';
import
'package:sky/widgets/task_description.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:sky/widgets/tool_bar.dart'
;
import
'package:sky/widgets/scrollable
_list
.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/ink_well.dart'
;
AssetBundle
_initBundle
(
)
{
...
...
packages/flutter/example/fitness/lib/main.dart
View file @
1387bd75
...
...
@@ -25,8 +25,7 @@ import 'package:sky/widgets/ink_well.dart';
import
'package:sky/widgets/material.dart'
;
import
'package:sky/widgets/radio.dart'
;
import
'package:sky/widgets/scaffold.dart'
;
import
'package:sky/widgets/scrollable_list.dart'
;
import
'package:sky/widgets/scrollable_viewport.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/snack_bar.dart'
;
import
'package:sky/widgets/tool_bar.dart'
;
import
'package:sky/widgets/card.dart'
;
...
...
packages/flutter/example/stocks/lib/main.dart
View file @
1387bd75
...
...
@@ -7,40 +7,39 @@ library stocks;
import
'dart:math'
as
math
;
import
'dart:sky'
as
sky
;
import
'package:sky/editing/input.dart'
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/rendering/box.dart'
;
import
'package:sky/theme/colors.dart'
as
colors
;
import
'package:sky/theme/typography.dart'
as
typography
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/checkbox.dart'
;
import
'package:sky/widgets/default_text_style.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:sky/widgets/widget.dart'
;
import
'package:sky/widgets/task_description.dart'
;
import
'package:sky/rendering/box.dart'
;
import
'package:sky/editing/input.dart'
;
import
'package:sky/widgets/drawer.dart'
;
import
'package:sky/widgets/dialog.dart'
;
import
'package:sky/widgets/drawer_divider.dart'
;
import
'package:sky/widgets/drawer_header.dart'
;
import
'package:sky/widgets/drawer_item.dart'
;
import
'package:sky/widgets/drawer.dart'
;
import
'package:sky/widgets/flat_button.dart'
;
import
'package:sky/widgets/floating_action_button.dart'
;
import
'package:sky/widgets/icon.dart'
;
import
'package:sky/widgets/icon_button.dart'
;
import
'package:sky/widgets/icon.dart'
;
import
'package:sky/widgets/ink_well.dart'
;
import
'package:sky/widgets/material.dart'
;
import
'package:sky/widgets/modal_overlay.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/popup_menu_item.dart'
;
import
'package:sky/widgets/popup_menu.dart'
;
import
'package:sky/widgets/radio.dart'
;
import
'package:sky/widgets/snack_bar.dart'
;
import
'package:sky/widgets/scaffold.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/snack_bar.dart'
;
import
'package:sky/widgets/switch.dart'
;
import
'package:sky/widgets/tabs.dart'
;
import
'package:sky/widgets/task_description.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:sky/widgets/tool_bar.dart'
;
import
'package:sky/widgets/scrollable_list.dart'
;
import
'package:sky/widgets/material.dart'
;
import
'package:sky/widgets/checkbox.dart'
;
import
'package:sky/widgets/popup_menu_item.dart'
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/widgets/ink_well.dart'
;
import
'package:sky/widgets/dialog.dart'
;
import
'package:sky/widgets/flat_button.dart'
;
import
'package:sky/widgets/scrollable_viewport.dart'
;
import
'package:sky/widgets/switch.dart'
;
import
'package:sky/widgets/widget.dart'
;
//TODO(jimsimon): Is this needed?
export
'package:sky/widgets/popup_menu.dart'
show
PopupMenuStatus
;
...
...
packages/flutter/example/widgets/card_collection.dart
View file @
1387bd75
...
...
@@ -10,7 +10,7 @@ import 'package:sky/widgets/block_viewport.dart';
import
'package:sky/widgets/card.dart'
;
import
'package:sky/widgets/dismissable.dart'
;
import
'package:sky/widgets/icon.dart'
;
import
'package:sky/widgets/
variable_height_
scrollable.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/scaffold.dart'
;
import
'package:sky/widgets/theme.dart'
;
import
'package:sky/widgets/tool_bar.dart'
;
...
...
packages/flutter/lib/widgets/dialog.dart
View file @
1387bd75
...
...
@@ -10,7 +10,7 @@ import 'package:sky/widgets/default_text_style.dart';
import
'package:sky/widgets/focus.dart'
;
import
'package:sky/widgets/material.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/scrollable
_viewport
.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/theme.dart'
;
typedef
Widget
DialogBuilder
(
Navigator
navigator
);
...
...
packages/flutter/lib/widgets/drawer.dart
View file @
1387bd75
...
...
@@ -13,7 +13,7 @@ import 'package:sky/widgets/animated_container.dart';
import
'package:sky/widgets/animation_intentions.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/scrollable
_viewport
.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/theme.dart'
;
export
'package:sky/animation/animation_performance.dart'
show
AnimationStatus
;
...
...
packages/flutter/lib/widgets/fixed_height_scrollable.dart
deleted
100644 → 0
View file @
7045c782
// Copyright 2015 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:sky/animation/scroll_behavior.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
abstract
class
FixedHeightScrollable
extends
Scrollable
{
FixedHeightScrollable
({
Key
key
,
this
.
itemHeight
,
this
.
padding
})
:
super
(
key:
key
)
{
assert
(
itemHeight
!=
null
);
}
EdgeDims
padding
;
double
itemHeight
;
/// Subclasses must implement `get itemCount` to tell FixedHeightScrollable
/// how many items there are in the list.
int
get
itemCount
;
int
_previousItemCount
;
void
syncFields
(
FixedHeightScrollable
source
)
{
padding
=
source
.
padding
;
itemHeight
=
source
.
itemHeight
;
super
.
syncFields
(
source
);
}
ScrollBehavior
createScrollBehavior
()
=>
new
OverscrollBehavior
();
OverscrollBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
double
_height
;
void
_handleSizeChanged
(
Size
newSize
)
{
setState
(()
{
_height
=
newSize
.
height
;
scrollBehavior
.
containerSize
=
_height
;
});
}
void
_updateContentsHeight
()
{
double
contentsHeight
=
itemHeight
*
itemCount
;
if
(
padding
!=
null
)
contentsHeight
+=
padding
.
top
+
padding
.
bottom
;
scrollBehavior
.
contentsSize
=
contentsHeight
;
}
void
_updateScrollOffset
()
{
if
(
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
settleScrollOffset
();
}
Widget
buildContent
()
{
if
(
itemCount
!=
_previousItemCount
)
{
_previousItemCount
=
itemCount
;
_updateContentsHeight
();
_updateScrollOffset
();
}
int
itemShowIndex
=
0
;
int
itemShowCount
=
0
;
double
offsetY
=
0.0
;
if
(
_height
!=
null
&&
_height
>
0.0
)
{
if
(
scrollOffset
<
0.0
)
{
double
visibleHeight
=
_height
+
scrollOffset
;
itemShowCount
=
(
visibleHeight
/
itemHeight
).
round
()
+
1
;
offsetY
=
scrollOffset
;
}
else
{
itemShowCount
=
(
_height
/
itemHeight
).
ceil
();
double
alignmentDelta
=
-
scrollOffset
%
itemHeight
;
double
drawStart
;
if
(
alignmentDelta
!=
0.0
)
{
alignmentDelta
-=
itemHeight
;
itemShowCount
+=
1
;
drawStart
=
scrollOffset
+
alignmentDelta
;
offsetY
=
-
alignmentDelta
;
}
else
{
drawStart
=
scrollOffset
;
}
itemShowIndex
=
math
.
max
(
0
,
(
drawStart
/
itemHeight
).
floor
());
}
}
List
<
Widget
>
items
=
buildItems
(
itemShowIndex
,
itemShowCount
);
assert
(
items
.
every
((
item
)
=>
item
.
key
!=
null
));
// TODO(ianh): Refactor this so that it does the building in the
// same frame as the size observing, similar to BlockViewport, but
// keeping the fixed-height optimisations.
return
new
SizeObserver
(
callback:
_handleSizeChanged
,
child:
new
Viewport
(
offset:
offsetY
,
child:
new
Container
(
padding:
padding
,
child:
new
Block
(
items
)
)
)
);
}
List
<
Widget
>
buildItems
(
int
start
,
int
count
);
}
packages/flutter/lib/widgets/popup_menu.dart
View file @
1387bd75
...
...
@@ -14,7 +14,7 @@ import 'package:sky/widgets/animated_component.dart';
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/navigator.dart'
;
import
'package:sky/widgets/popup_menu_item.dart'
;
import
'package:sky/widgets/scrollable
_viewport
.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
export
'package:sky/animation/animation_performance.dart'
show
AnimationStatus
;
...
...
packages/flutter/lib/widgets/scrollable.dart
View file @
1387bd75
...
...
@@ -2,16 +2,22 @@
// 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
'dart:sky'
as
sky
;
import
'package:newton/newton.dart'
;
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/animation/animated_simulation.dart'
;
import
'package:sky/animation/animated_value.dart'
;
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/animation/curves.dart'
;
import
'package:sky/animation/scroll_behavior.dart'
;
import
'package:sky/theme/view_configuration.dart'
as
config
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/block_viewport.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/widget.dart'
;
export
'package:sky/widgets/block_viewport.dart'
show
BlockViewportLayoutState
;
const
double
_kMillisecondsPerSecond
=
1000.0
;
...
...
@@ -27,6 +33,8 @@ abstract class ScrollClient {
enum
ScrollDirection
{
vertical
,
horizontal
}
/// A base class for scrollable widgets that reacts to user input and generates
/// a scrollOffset.
abstract
class
Scrollable
extends
StatefulComponent
{
Scrollable
({
...
...
@@ -203,3 +211,282 @@ abstract class Scrollable extends StatefulComponent {
scrollBy
(-
event
.
offsetY
);
}
}
/// A simple scrollable widget that has a single child. Use this component if
/// you are not worried about offscreen widgets consuming resources.
class
ScrollableViewport
extends
Scrollable
{
ScrollableViewport
({
Key
key
,
this
.
child
})
:
super
(
key:
key
);
Widget
child
;
void
syncFields
(
ScrollableViewport
source
)
{
child
=
source
.
child
;
super
.
syncFields
(
source
);
}
ScrollBehavior
createScrollBehavior
()
=>
new
FlingBehavior
();
FlingBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
double
_viewportHeight
=
0.0
;
double
_childHeight
=
0.0
;
void
_handleViewportSizeChanged
(
Size
newSize
)
{
_viewportHeight
=
newSize
.
height
;
_updateScrollBehaviour
();
}
void
_handleChildSizeChanged
(
Size
newSize
)
{
_childHeight
=
newSize
.
height
;
_updateScrollBehaviour
();
}
void
_updateScrollBehaviour
()
{
scrollBehavior
.
contentsSize
=
_childHeight
;
scrollBehavior
.
containerSize
=
_viewportHeight
;
if
(
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
settleScrollOffset
();
}
Widget
buildContent
()
{
return
new
SizeObserver
(
callback:
_handleViewportSizeChanged
,
child:
new
Viewport
(
offset:
scrollOffset
,
child:
new
SizeObserver
(
callback:
_handleChildSizeChanged
,
child:
child
)
)
);
}
}
/// A mashup of [ScrollableViewport] and [Block]. Useful when you have a small,
/// fixed number of children that you wish to arrange in a block layout and that
/// might exceed the height of its container (and therefore need to scroll).
class
ScrollableBlock
extends
Component
{
ScrollableBlock
(
this
.
children
,
{
Key
key
})
:
super
(
key:
key
);
final
List
<
Widget
>
children
;
Widget
build
()
{
return
new
ScrollableViewport
(
child:
new
Block
(
children
)
);
}
}
/// An optimized scrollable widget for a large number of children that are all
/// of the same height. Use this widget when you have a large number of children
/// or when you are concerned about offscreen widgets consuming resources.
abstract
class
FixedHeightScrollable
extends
Scrollable
{
FixedHeightScrollable
({
Key
key
,
this
.
itemHeight
,
this
.
padding
})
:
super
(
key:
key
)
{
assert
(
itemHeight
!=
null
);
}
EdgeDims
padding
;
double
itemHeight
;
/// Subclasses must implement `get itemCount` to tell FixedHeightScrollable
/// how many items there are in the list.
int
get
itemCount
;
int
_previousItemCount
;
void
syncFields
(
FixedHeightScrollable
source
)
{
padding
=
source
.
padding
;
itemHeight
=
source
.
itemHeight
;
super
.
syncFields
(
source
);
}
ScrollBehavior
createScrollBehavior
()
=>
new
OverscrollBehavior
();
OverscrollBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
double
_height
;
void
_handleSizeChanged
(
Size
newSize
)
{
setState
(()
{
_height
=
newSize
.
height
;
scrollBehavior
.
containerSize
=
_height
;
});
}
void
_updateContentsHeight
()
{
double
contentsHeight
=
itemHeight
*
itemCount
;
if
(
padding
!=
null
)
contentsHeight
+=
padding
.
top
+
padding
.
bottom
;
scrollBehavior
.
contentsSize
=
contentsHeight
;
}
void
_updateScrollOffset
()
{
if
(
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
settleScrollOffset
();
}
Widget
buildContent
()
{
if
(
itemCount
!=
_previousItemCount
)
{
_previousItemCount
=
itemCount
;
_updateContentsHeight
();
_updateScrollOffset
();
}
int
itemShowIndex
=
0
;
int
itemShowCount
=
0
;
double
offsetY
=
0.0
;
if
(
_height
!=
null
&&
_height
>
0.0
)
{
if
(
scrollOffset
<
0.0
)
{
double
visibleHeight
=
_height
+
scrollOffset
;
itemShowCount
=
(
visibleHeight
/
itemHeight
).
round
()
+
1
;
offsetY
=
scrollOffset
;
}
else
{
itemShowCount
=
(
_height
/
itemHeight
).
ceil
();
double
alignmentDelta
=
-
scrollOffset
%
itemHeight
;
double
drawStart
;
if
(
alignmentDelta
!=
0.0
)
{
alignmentDelta
-=
itemHeight
;
itemShowCount
+=
1
;
drawStart
=
scrollOffset
+
alignmentDelta
;
offsetY
=
-
alignmentDelta
;
}
else
{
drawStart
=
scrollOffset
;
}
itemShowIndex
=
math
.
max
(
0
,
(
drawStart
/
itemHeight
).
floor
());
}
}
List
<
Widget
>
items
=
buildItems
(
itemShowIndex
,
itemShowCount
);
assert
(
items
.
every
((
item
)
=>
item
.
key
!=
null
));
// TODO(ianh): Refactor this so that it does the building in the
// same frame as the size observing, similar to BlockViewport, but
// keeping the fixed-height optimisations.
return
new
SizeObserver
(
callback:
_handleSizeChanged
,
child:
new
Viewport
(
offset:
offsetY
,
child:
new
Container
(
padding:
padding
,
child:
new
Block
(
items
)
)
)
);
}
List
<
Widget
>
buildItems
(
int
start
,
int
count
);
}
typedef
Widget
ItemBuilder
<
T
>(
T
item
);
/// A wrapper around [FixedHeightScrollable] that helps you translate a list of
/// model objects into a scrollable list of widgets. Assumes all the widgets
/// have the same height.
class
ScrollableList
<
T
>
extends
FixedHeightScrollable
{
ScrollableList
({
Key
key
,
this
.
items
,
this
.
itemBuilder
,
double
itemHeight
,
EdgeDims
padding
})
:
super
(
key:
key
,
itemHeight:
itemHeight
,
padding:
padding
);
List
<
T
>
items
;
ItemBuilder
<
T
>
itemBuilder
;
void
syncFields
(
ScrollableList
<
T
>
source
)
{
items
=
source
.
items
;
itemBuilder
=
source
.
itemBuilder
;
super
.
syncFields
(
source
);
}
int
get
itemCount
=>
items
.
length
;
List
<
Widget
>
buildItems
(
int
start
,
int
count
)
{
List
<
Widget
>
result
=
new
List
<
Widget
>();
int
end
=
math
.
min
(
start
+
count
,
items
.
length
);
for
(
int
i
=
start
;
i
<
end
;
++
i
)
result
.
add
(
itemBuilder
(
items
[
i
]));
return
result
;
}
}
/// A general scrollable list for a large number of children that might not all
/// have the same height. Prefer [FixedHeightScrollable] when all the children
/// have the same height because it can use that property to be more efficient.
/// Prefer [ScrollableViewport] with a single child.
class
VariableHeightScrollable
extends
Scrollable
{
VariableHeightScrollable
({
Key
key
,
this
.
builder
,
this
.
token
,
this
.
layoutState
})
:
super
(
key:
key
);
IndexedBuilder
builder
;
Object
token
;
BlockViewportLayoutState
layoutState
;
// When the token changes the scrollable's contents may have
// changed. Remember as much so that after the new contents
// have been laid out we can adjust the scrollOffset so that
// the last page of content is still visible.
bool
_contentsChanged
=
true
;
void
initState
()
{
assert
(
layoutState
!=
null
);
super
.
initState
();
}
void
didMount
()
{
layoutState
.
addListener
(
_handleLayoutChanged
);
super
.
didMount
();
}
void
didUnmount
()
{
layoutState
.
removeListener
(
_handleLayoutChanged
);
super
.
didUnmount
();
}
void
syncFields
(
VariableHeightScrollable
source
)
{
builder
=
source
.
builder
;
if
(
token
!=
source
.
token
)
_contentsChanged
=
true
;
token
=
source
.
token
;
if
(
layoutState
!=
source
.
layoutState
)
{
// Warning: this is unlikely to be what you intended.
assert
(
source
.
layoutState
!=
null
);
layoutState
.
removeListener
(
_handleLayoutChanged
);
layoutState
=
source
.
layoutState
;
layoutState
.
addListener
(
_handleLayoutChanged
);
}
super
.
syncFields
(
source
);
}
ScrollBehavior
createScrollBehavior
()
=>
new
OverscrollBehavior
();
OverscrollBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
void
_handleSizeChanged
(
Size
newSize
)
{
scrollBehavior
.
containerSize
=
newSize
.
height
;
}
void
_handleLayoutChanged
()
{
if
(
layoutState
.
didReachLastChild
)
{
scrollBehavior
.
contentsSize
=
layoutState
.
contentsSize
;
if
(
_contentsChanged
&&
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
{
_contentsChanged
=
false
;
settleScrollOffset
();
}
}
else
{
scrollBehavior
.
contentsSize
=
double
.
INFINITY
;
}
}
Widget
buildContent
()
{
return
new
SizeObserver
(
callback:
_handleSizeChanged
,
child:
new
BlockViewport
(
builder:
builder
,
layoutState:
layoutState
,
startOffset:
scrollOffset
,
token:
token
)
);
}
}
packages/flutter/lib/widgets/scrollable_list.dart
deleted
100644 → 0
View file @
7045c782
// Copyright 2015 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:sky/widgets/fixed_height_scrollable.dart'
;
import
'package:sky/widgets/basic.dart'
;
typedef
Widget
ItemBuilder
<
T
>(
T
item
);
class
ScrollableList
<
T
>
extends
FixedHeightScrollable
{
ScrollableList
({
Key
key
,
this
.
items
,
this
.
itemBuilder
,
double
itemHeight
,
EdgeDims
padding
})
:
super
(
key:
key
,
itemHeight:
itemHeight
,
padding:
padding
);
List
<
T
>
items
;
ItemBuilder
<
T
>
itemBuilder
;
void
syncFields
(
ScrollableList
<
T
>
source
)
{
items
=
source
.
items
;
itemBuilder
=
source
.
itemBuilder
;
super
.
syncFields
(
source
);
}
int
get
itemCount
=>
items
.
length
;
List
<
Widget
>
buildItems
(
int
start
,
int
count
)
{
List
<
Widget
>
result
=
new
List
<
Widget
>();
int
end
=
math
.
min
(
start
+
count
,
items
.
length
);
for
(
int
i
=
start
;
i
<
end
;
++
i
)
result
.
add
(
itemBuilder
(
items
[
i
]));
return
result
;
}
}
packages/flutter/lib/widgets/scrollable_viewport.dart
deleted
100644 → 0
View file @
7045c782
// Copyright 2015 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:sky/animation/scroll_behavior.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
class
ScrollableViewport
extends
Scrollable
{
ScrollableViewport
({
Key
key
,
this
.
child
})
:
super
(
key:
key
);
Widget
child
;
void
syncFields
(
ScrollableViewport
source
)
{
child
=
source
.
child
;
super
.
syncFields
(
source
);
}
ScrollBehavior
createScrollBehavior
()
=>
new
FlingBehavior
();
FlingBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
double
_viewportHeight
=
0.0
;
double
_childHeight
=
0.0
;
void
_handleViewportSizeChanged
(
Size
newSize
)
{
_viewportHeight
=
newSize
.
height
;
_updateScrollBehaviour
();
}
void
_handleChildSizeChanged
(
Size
newSize
)
{
_childHeight
=
newSize
.
height
;
_updateScrollBehaviour
();
}
void
_updateScrollBehaviour
()
{
scrollBehavior
.
contentsSize
=
_childHeight
;
scrollBehavior
.
containerSize
=
_viewportHeight
;
if
(
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
settleScrollOffset
();
}
Widget
buildContent
()
{
return
new
SizeObserver
(
callback:
_handleViewportSizeChanged
,
child:
new
Viewport
(
offset:
scrollOffset
,
child:
new
SizeObserver
(
callback:
_handleChildSizeChanged
,
child:
child
)
)
);
}
}
class
ScrollableBlock
extends
Component
{
ScrollableBlock
(
this
.
children
,
{
Key
key
})
:
super
(
key:
key
);
final
List
<
Widget
>
children
;
Widget
build
()
{
return
new
ScrollableViewport
(
child:
new
Block
(
children
)
);
}
}
packages/flutter/lib/widgets/variable_height_scrollable.dart
deleted
100644 → 0
View file @
7045c782
// Copyright 2015 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:sky/animation/scroll_behavior.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/block_viewport.dart'
;
import
'package:sky/widgets/scrollable.dart'
;
import
'package:sky/widgets/widget.dart'
;
export
'package:sky/widgets/block_viewport.dart'
show
BlockViewportLayoutState
;
class
VariableHeightScrollable
extends
Scrollable
{
VariableHeightScrollable
({
Key
key
,
this
.
builder
,
this
.
token
,
this
.
layoutState
})
:
super
(
key:
key
);
IndexedBuilder
builder
;
Object
token
;
BlockViewportLayoutState
layoutState
;
// When the token changes the scrollable's contents may have
// changed. Remember as much so that after the new contents
// have been laid out we can adjust the scrollOffset so that
// the last page of content is still visible.
bool
_contentsChanged
=
true
;
void
initState
()
{
assert
(
layoutState
!=
null
);
super
.
initState
();
}
void
didMount
()
{
layoutState
.
addListener
(
_handleLayoutChanged
);
super
.
didMount
();
}
void
didUnmount
()
{
layoutState
.
removeListener
(
_handleLayoutChanged
);
super
.
didUnmount
();
}
void
syncFields
(
VariableHeightScrollable
source
)
{
builder
=
source
.
builder
;
if
(
token
!=
source
.
token
)
_contentsChanged
=
true
;
token
=
source
.
token
;
if
(
layoutState
!=
source
.
layoutState
)
{
// Warning: this is unlikely to be what you intended.
assert
(
source
.
layoutState
!=
null
);
layoutState
.
removeListener
(
_handleLayoutChanged
);
layoutState
=
source
.
layoutState
;
layoutState
.
addListener
(
_handleLayoutChanged
);
}
super
.
syncFields
(
source
);
}
ScrollBehavior
createScrollBehavior
()
=>
new
OverscrollBehavior
();
OverscrollBehavior
get
scrollBehavior
=>
super
.
scrollBehavior
;
void
_handleSizeChanged
(
Size
newSize
)
{
scrollBehavior
.
containerSize
=
newSize
.
height
;
}
void
_handleLayoutChanged
()
{
if
(
layoutState
.
didReachLastChild
)
{
scrollBehavior
.
contentsSize
=
layoutState
.
contentsSize
;
if
(
_contentsChanged
&&
scrollOffset
>
scrollBehavior
.
maxScrollOffset
)
{
_contentsChanged
=
false
;
settleScrollOffset
();
}
}
else
{
scrollBehavior
.
contentsSize
=
double
.
INFINITY
;
}
}
Widget
buildContent
()
{
return
new
SizeObserver
(
callback:
_handleSizeChanged
,
child:
new
BlockViewport
(
builder:
builder
,
layoutState:
layoutState
,
startOffset:
scrollOffset
,
token:
token
)
);
}
}
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