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
c058cf2e
Commit
c058cf2e
authored
Apr 06, 2016
by
Hans Muller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Overscroll indicator for MaterialList
Overscroll indicator for MaterialList
parent
41338c35
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
249 additions
and
59 deletions
+249
-59
list_demo.dart
examples/material_gallery/lib/demo/list_demo.dart
+33
-36
material.dart
packages/flutter/lib/material.dart
+1
-0
animation_controller.dart
packages/flutter/lib/src/animation/animation_controller.dart
+1
-0
list.dart
packages/flutter/lib/src/material/list.dart
+19
-5
overscroll_painter.dart
packages/flutter/lib/src/material/overscroll_painter.dart
+134
-0
scrollbar_painter.dart
packages/flutter/lib/src/material/scrollbar_painter.dart
+4
-6
scrollable.dart
packages/flutter/lib/src/widgets/scrollable.dart
+51
-5
scrollable_list.dart
packages/flutter/lib/src/widgets/scrollable_list.dart
+6
-7
No files found.
examples/material_gallery/lib/demo/list_demo.dart
View file @
c058cf2e
...
...
@@ -4,12 +4,6 @@
import
'package:flutter/material.dart'
;
enum
ListDemoItemSize
{
oneLine
,
twoLine
,
threeLine
}
class
ListDemo
extends
StatefulWidget
{
ListDemo
({
Key
key
})
:
super
(
key:
key
);
...
...
@@ -21,7 +15,7 @@ class ListDemoState extends State<ListDemo> {
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
PersistentBottomSheetController
<
Null
>
_bottomSheet
;
ListDemoItemSize
_itemSize
=
ListDemoItemSiz
e
.
threeLine
;
MaterialListType
_itemType
=
MaterialListTyp
e
.
threeLine
;
bool
_dense
=
false
;
bool
_showAvatars
=
true
;
bool
_showIcons
=
false
;
...
...
@@ -31,9 +25,9 @@ class ListDemoState extends State<ListDemo> {
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
];
void
changeItem
Size
(
ListDemoItemSize
siz
e
)
{
void
changeItem
Type
(
MaterialListType
typ
e
)
{
setState
(()
{
_item
Size
=
siz
e
;
_item
Type
=
typ
e
;
});
_bottomSheet
?.
setState
(()
{
});
}
...
...
@@ -51,28 +45,28 @@ class ListDemoState extends State<ListDemo> {
new
ListItem
(
dense:
true
,
title:
new
Text
(
'One-line'
),
trailing:
new
Radio
<
ListDemoItemSiz
e
>(
value:
ListDemoItemSiz
e
.
oneLine
,
groupValue:
_item
Siz
e
,
onChanged:
changeItem
Siz
e
trailing:
new
Radio
<
MaterialListTyp
e
>(
value:
_showAvatars
?
MaterialListType
.
oneLineWithAvatar
:
MaterialListTyp
e
.
oneLine
,
groupValue:
_item
Typ
e
,
onChanged:
changeItem
Typ
e
)
),
new
ListItem
(
dense:
true
,
title:
new
Text
(
'Two-line'
),
trailing:
new
Radio
<
ListDemoItemSiz
e
>(
value:
ListDemoItemSiz
e
.
twoLine
,
groupValue:
_item
Siz
e
,
onChanged:
changeItem
Siz
e
trailing:
new
Radio
<
MaterialListTyp
e
>(
value:
MaterialListTyp
e
.
twoLine
,
groupValue:
_item
Typ
e
,
onChanged:
changeItem
Typ
e
)
),
new
ListItem
(
dense:
true
,
title:
new
Text
(
'Three-line'
),
trailing:
new
Radio
<
ListDemoItemSiz
e
>(
value:
ListDemoItemSiz
e
.
threeLine
,
groupValue:
_item
Siz
e
,
onChanged:
changeItem
Siz
e
trailing:
new
Radio
<
MaterialListTyp
e
>(
value:
MaterialListTyp
e
.
threeLine
,
groupValue:
_item
Typ
e
,
onChanged:
changeItem
Typ
e
)
),
new
ListItem
(
...
...
@@ -135,17 +129,17 @@ class ListDemoState extends State<ListDemo> {
Widget
buildListItem
(
BuildContext
context
,
String
item
)
{
Widget
secondary
;
if
(
_item
Size
==
ListDemoItemSiz
e
.
twoLine
)
{
if
(
_item
Type
==
MaterialListTyp
e
.
twoLine
)
{
secondary
=
new
Text
(
"Additional item information."
);
}
else
if
(
_item
Size
==
ListDemoItemSiz
e
.
threeLine
)
{
}
else
if
(
_item
Type
==
MaterialListTyp
e
.
threeLine
)
{
secondary
=
new
Text
(
"Even more additional list item information appears on line three."
);
}
return
new
ListItem
(
isThreeLine:
_item
Size
==
ListDemoItemSiz
e
.
threeLine
,
isThreeLine:
_item
Type
==
MaterialListTyp
e
.
threeLine
,
dense:
_dense
,
leading:
_showAvatars
?
new
CircleAvatar
(
child:
new
Text
(
item
))
:
null
,
title:
new
Text
(
'This item represents
$item
.'
),
...
...
@@ -157,16 +151,17 @@ class ListDemoState extends State<ListDemo> {
@override
Widget
build
(
BuildContext
context
)
{
final
String
layoutText
=
_dense
?
"
\
u2013 Dense"
:
""
;
String
itemSizeText
;
switch
(
_itemSize
)
{
case
ListDemoItemSize
.
oneLine
:
itemSizeText
=
'Single-Line'
;
String
itemTypeText
;
switch
(
_itemType
)
{
case
MaterialListType
.
oneLine
:
case
MaterialListType
.
oneLineWithAvatar
:
itemTypeText
=
'Single-line'
;
break
;
case
ListDemoItemSiz
e
.
twoLine
:
item
SizeText
=
'Two-L
ine'
;
case
MaterialListTyp
e
.
twoLine
:
item
TypeText
=
'Two-l
ine'
;
break
;
case
ListDemoItemSiz
e
.
threeLine
:
item
SizeText
=
'Three-L
ine'
;
case
MaterialListTyp
e
.
threeLine
:
item
TypeText
=
'Three-l
ine'
;
break
;
}
...
...
@@ -177,7 +172,7 @@ class ListDemoState extends State<ListDemo> {
return
new
Scaffold
(
key:
scaffoldKey
,
appBar:
new
AppBar
(
title:
new
Text
(
'Scrolling list
\n
$item
Siz
eText$layoutText
'
),
title:
new
Text
(
'Scrolling list
\n
$item
Typ
eText$layoutText
'
),
actions:
<
Widget
>[
new
IconButton
(
icon:
Icons
.
sort_by_alpha
,
...
...
@@ -196,9 +191,11 @@ class ListDemoState extends State<ListDemo> {
)
]
),
body:
new
Block
(
padding:
new
EdgeInsets
.
all
(
_dense
?
4.0
:
8.0
),
children:
listItems
.
toList
()
body:
new
MaterialList
(
type:
_itemType
,
scrollablePadding:
new
EdgeInsets
.
all
(
_dense
?
4.0
:
8.0
),
clampOverscrolls:
true
,
children:
listItems
)
);
}
...
...
packages/flutter/lib/material.dart
View file @
c058cf2e
...
...
@@ -40,6 +40,7 @@ export 'src/material/input.dart';
export
'src/material/list.dart'
;
export
'src/material/list_item.dart'
;
export
'src/material/material.dart'
;
export
'src/material/overscroll_painter.dart'
;
export
'src/material/page.dart'
;
export
'src/material/popup_menu.dart'
;
export
'src/material/progress_indicator.dart'
;
...
...
packages/flutter/lib/src/animation/animation_controller.dart
View file @
c058cf2e
...
...
@@ -166,6 +166,7 @@ class AnimationController extends Animation<double>
Future
<
Null
>
animateTo
(
double
target
,
{
Duration
duration
,
Curve
curve:
Curves
.
linear
})
{
Duration
simulationDuration
=
duration
;
if
(
simulationDuration
==
null
)
{
assert
(
this
.
duration
!=
null
);
double
range
=
upperBound
-
lowerBound
;
double
remainingFraction
=
range
.
isFinite
?
(
target
-
_value
).
abs
()
/
range
:
1.0
;
simulationDuration
=
this
.
duration
*
remainingFraction
;
...
...
packages/flutter/lib/src/material/list.dart
View file @
c058cf2e
...
...
@@ -5,6 +5,7 @@
import
'package:flutter/widgets.dart'
;
import
'constants.dart'
;
import
'overscroll_painter.dart'
;
import
'scrollbar_painter.dart'
;
import
'theme.dart'
;
...
...
@@ -28,6 +29,7 @@ class MaterialList extends StatefulWidget {
this
.
initialScrollOffset
,
this
.
onScroll
,
this
.
type
:
MaterialListType
.
twoLine
,
this
.
clampOverscrolls
:
false
,
this
.
children
,
this
.
scrollablePadding
:
EdgeInsets
.
zero
,
this
.
scrollableKey
...
...
@@ -36,6 +38,7 @@ class MaterialList extends StatefulWidget {
final
double
initialScrollOffset
;
final
ScrollListener
onScroll
;
final
MaterialListType
type
;
final
bool
clampOverscrolls
;
final
Iterable
<
Widget
>
children
;
final
EdgeInsets
scrollablePadding
;
final
Key
scrollableKey
;
...
...
@@ -45,26 +48,37 @@ class MaterialList extends StatefulWidget {
}
class
_MaterialListState
extends
State
<
MaterialList
>
{
ScrollbarPainter
_scrollbarPainter
;
ScrollableListPainter
_scrollbarPainter
;
ScrollableListPainter
_overscrollPainter
;
Color
_getScrollbarThumbColor
()
=>
Theme
.
of
(
context
).
highlightColor
;
Color
_getOverscrollIndicatorColor
()
=>
Theme
.
of
(
context
).
accentColor
.
withOpacity
(
0.35
);
@override
void
initState
()
{
super
.
initState
();
_scrollbarPainter
=
new
ScrollbarPainter
(
getThumbColor:
()
=>
Theme
.
of
(
context
).
highlightColor
);
_scrollbarPainter
=
new
ScrollbarPainter
(
getThumbColor:
_getScrollbarThumbColor
);
}
@override
Widget
build
(
BuildContext
context
)
{
ScrollableListPainter
painter
=
_scrollbarPainter
;
if
(
config
.
clampOverscrolls
)
{
_overscrollPainter
??=
new
OverscrollPainter
(
getIndicatorColor:
_getOverscrollIndicatorColor
);
painter
=
new
CompoundScrollableListPainter
(<
ScrollableListPainter
>[
_scrollbarPainter
,
_overscrollPainter
]);
}
return
new
ScrollableList
(
key:
config
.
scrollableKey
,
initialScrollOffset:
config
.
initialScrollOffset
,
scrollDirection:
Axis
.
vertical
,
clampOverscrolls:
config
.
clampOverscrolls
,
onScroll:
config
.
onScroll
,
itemExtent:
kListItemExtent
[
config
.
type
],
padding:
const
EdgeInsets
.
symmetric
(
vertical:
8.0
)
+
config
.
scrollablePadding
,
scrollableListPainter:
_scrollbarP
ainter
,
scrollableListPainter:
p
ainter
,
children:
config
.
children
);
}
...
...
packages/flutter/lib/src/material/overscroll_painter.dart
0 → 100644
View file @
c058cf2e
// Copyright 2016 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:async'
;
import
'package:flutter/widgets.dart'
;
const
double
_kMinIndicatorLength
=
0.0
;
const
double
_kMaxIndicatorLength
=
64.0
;
const
double
_kMinIndicatorOpacity
=
0.0
;
const
double
_kMaxIndicatorOpacity
=
0.25
;
const
Duration
_kIndicatorVanishDuration
=
const
Duration
(
milliseconds:
200
);
const
Duration
_kIndicatorTimeoutDuration
=
const
Duration
(
seconds:
1
);
final
Tween
<
double
>
_kIndicatorOpacity
=
new
Tween
<
double
>(
begin:
0.0
,
end:
0.3
);
typedef
Color
GetOverscrollIndicatorColor
(
);
class
OverscrollPainter
extends
ScrollableListPainter
{
OverscrollPainter
({
GetOverscrollIndicatorColor
getIndicatorColor
})
{
this
.
getIndicatorColor
=
getIndicatorColor
??
_defaultIndicatorColor
;
}
GetOverscrollIndicatorColor
getIndicatorColor
;
bool
_indicatorActive
=
false
;
AnimationController
_indicatorLength
;
Timer
_indicatorTimer
;
Color
_defaultIndicatorColor
()
=>
const
Color
(
0xFF00FF00
);
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
_indicatorLength
==
null
||
(
scrollOffset
>=
_minScrollOffset
&&
scrollOffset
<=
_maxScrollOffset
))
return
;
final
double
rectBias
=
_indicatorLength
.
value
/
2.0
;
final
double
arcBias
=
_indicatorLength
.
value
;
final
Rect
viewportRect
=
offset
&
viewportSize
;
final
Path
path
=
new
Path
();
switch
(
scrollDirection
)
{
case
Axis
.
vertical
:
final
double
width
=
viewportRect
.
width
;
if
(
scrollOffset
<
_minScrollOffset
)
{
path
.
moveTo
(
viewportRect
.
left
,
viewportRect
.
top
);
path
.
relativeLineTo
(
width
,
0.0
);
path
.
relativeLineTo
(
0.0
,
rectBias
);
path
.
relativeQuadraticBezierTo
(
width
/
-
2.0
,
arcBias
,
-
width
,
0.0
);
}
else
{
path
.
moveTo
(
viewportRect
.
left
,
viewportRect
.
bottom
);
path
.
relativeLineTo
(
width
,
0.0
);
path
.
relativeLineTo
(
0.0
,
-
rectBias
);
path
.
relativeQuadraticBezierTo
(
width
/
-
2.0
,
-
arcBias
,
-
width
,
0.0
);
}
break
;
case
Axis
.
horizontal
:
final
double
height
=
viewportRect
.
height
;
if
(
scrollOffset
<
_minScrollOffset
)
{
path
.
moveTo
(
viewportRect
.
left
,
viewportRect
.
top
);
path
.
relativeLineTo
(
0.0
,
height
);
path
.
relativeLineTo
(
rectBias
,
0.0
);
path
.
relativeQuadraticBezierTo
(
arcBias
,
height
/
-
2.0
,
0.0
,
-
height
);
}
else
{
path
.
moveTo
(
viewportRect
.
right
,
viewportRect
.
top
);
path
.
relativeLineTo
(
0.0
,
height
);
path
.
relativeLineTo
(-
rectBias
,
0.0
);
path
.
relativeQuadraticBezierTo
(-
arcBias
,
height
/
-
2.0
,
0.0
,
-
height
);
}
break
;
}
path
.
close
();
final
double
t
=
(
_indicatorLength
.
value
-
_kMinIndicatorLength
)
/
(
_kMaxIndicatorLength
-
_kMinIndicatorLength
);
final
Paint
paint
=
new
Paint
()
..
color
=
getIndicatorColor
().
withOpacity
(
_kIndicatorOpacity
.
lerp
(
Curves
.
easeIn
.
transform
(
t
)));
context
.
canvas
.
drawPath
(
path
,
paint
);
}
void
_hide
()
{
_indicatorTimer
?.
cancel
();
_indicatorTimer
=
null
;
_indicatorActive
=
false
;
_indicatorLength
?.
reverse
();
}
double
get
_minScrollOffset
=>
0.0
;
double
get
_maxScrollOffset
{
switch
(
scrollDirection
)
{
case
Axis
.
vertical
:
return
contentExtent
-
viewportSize
.
height
;
case
Axis
.
horizontal
:
return
contentExtent
-
viewportSize
.
width
;
}
}
@override
void
scrollStarted
()
{
_indicatorActive
=
true
;
_indicatorLength
??=
new
AnimationController
(
lowerBound:
_kMinIndicatorLength
,
upperBound:
_kMaxIndicatorLength
,
duration:
_kIndicatorVanishDuration
)
..
addListener
(()
{
renderObject
?.
markNeedsPaint
();
});
}
@override
void
set
scrollOffset
(
double
value
)
{
if
(
_indicatorActive
&&
(
value
<
_minScrollOffset
||
value
>
_maxScrollOffset
)
&&
((
value
-
scrollOffset
).
abs
()
>
kPixelScrollTolerance
.
distance
))
{
_indicatorTimer
?.
cancel
();
_indicatorTimer
=
new
Timer
(
_kIndicatorTimeoutDuration
,
_hide
);
_indicatorLength
.
value
=
value
<
_minScrollOffset
?
_minScrollOffset
-
value
:
value
-
_maxScrollOffset
;
}
super
.
scrollOffset
=
value
;
}
@override
void
scrollEnded
()
{
_hide
();
}
@override
void
detach
()
{
super
.
detach
();
_indicatorTimer
?.
cancel
();
_indicatorTimer
=
null
;
_indicatorLength
?.
stop
();
}
}
packages/flutter/lib/src/material/scrollbar_painter.dart
View file @
c058cf2e
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter/widgets.dart'
;
const
double
_kMinScrollbarThumbLength
=
18.0
;
...
...
@@ -66,7 +64,7 @@ class ScrollbarPainter extends ScrollableListPainter {
AnimationController
_fade
;
@override
Future
<
Null
>
scrollStarted
()
{
void
scrollStarted
()
{
if
(
_fade
==
null
)
{
_fade
=
new
AnimationController
(
duration:
_kScrollbarThumbFadeDuration
);
CurvedAnimation
curve
=
new
CurvedAnimation
(
parent:
_fade
,
curve:
Curves
.
ease
);
...
...
@@ -75,12 +73,12 @@ class ScrollbarPainter extends ScrollableListPainter {
renderObject
?.
markNeedsPaint
();
});
}
return
_fade
.
forward
();
_fade
.
forward
();
}
@override
Future
<
Null
>
scrollEnded
()
{
return
_fade
.
reverse
();
void
scrollEnded
()
{
_fade
.
reverse
();
}
@override
...
...
packages/flutter/lib/src/widgets/scrollable.dart
View file @
c058cf2e
...
...
@@ -786,13 +786,59 @@ abstract class ScrollableListPainter extends RenderObjectPainter {
}
/// Called when a scroll starts. Subclasses may override this method to
/// initialize some state or to play an animation. The returned Future should
/// complete when the computation triggered by this method has finished.
Future
<
Null
>
scrollStarted
()
=>
new
Future
<
Null
>.
value
();
/// initialize some state or to play an animation.
void
scrollStarted
()
{
}
/// Similar to scrollStarted(). Called when a scroll ends. For fling scrolls
/// "ended" means that the scroll animation either stopped of its own accord
/// or was canceled by the user.
Future
<
Null
>
scrollEnded
()
=>
new
Future
<
Null
>.
value
();
void
scrollEnded
()
{
}
}
class
CompoundScrollableListPainter
extends
ScrollableListPainter
{
CompoundScrollableListPainter
(
this
.
painters
);
final
List
<
ScrollableListPainter
>
painters
;
@override
void
attach
(
RenderObject
renderObject
)
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
attach
(
renderObject
);
}
@override
void
detach
()
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
detach
();
}
@override
void
set
contentExtent
(
double
value
)
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
contentExtent
=
value
;
}
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
paint
(
context
,
offset
);
}
@override
void
set
scrollOffset
(
double
value
)
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
scrollOffset
=
value
;
}
@override
void
scrollStarted
()
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
scrollStarted
();
}
@override
void
scrollEnded
()
{
for
(
ScrollableListPainter
painter
in
painters
)
painter
.
scrollEnded
();
}
}
packages/flutter/lib/src/widgets/scrollable_list.dart
View file @
c058cf2e
...
...
@@ -21,6 +21,7 @@ class ScrollableList extends Scrollable {
SnapOffsetCallback
snapOffsetCallback
,
this
.
itemExtent
,
this
.
itemsWrap
:
false
,
this
.
clampOverscrolls
:
false
,
this
.
padding
,
this
.
scrollableListPainter
,
this
.
children
...
...
@@ -37,6 +38,7 @@ class ScrollableList extends Scrollable {
final
double
itemExtent
;
final
bool
itemsWrap
;
final
bool
clampOverscrolls
;
final
EdgeInsets
padding
;
final
ScrollableListPainter
scrollableListPainter
;
final
Iterable
<
Widget
>
children
;
...
...
@@ -75,17 +77,14 @@ class _ScrollableListState extends ScrollableState<ScrollableList> {
config
.
scrollableListPainter
?.
scrollOffset
=
scrollOffset
;
}
@override
void
dispatchOnScrollEnd
()
{
super
.
dispatchOnScrollEnd
();
config
.
scrollableListPainter
?.
scrollEnded
();
}
@override
Widget
buildContent
(
BuildContext
context
)
{
final
double
listScrollOffset
=
config
.
clampOverscrolls
?
scrollOffset
.
clamp
(
scrollBehavior
.
minScrollOffset
,
scrollBehavior
.
maxScrollOffset
)
:
scrollOffset
;
return
new
ListViewport
(
onExtentsChanged:
_handleExtentsChanged
,
scrollOffset:
s
crollOffset
,
scrollOffset:
listS
crollOffset
,
mainAxis:
config
.
scrollDirection
,
anchor:
config
.
scrollAnchor
,
itemExtent:
config
.
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