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
16ffdc67
Commit
16ffdc67
authored
Aug 11, 2015
by
Hans Muller
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #572 from HansMuller/ensure-visible
Adds ensureWidgetIsVisible() function to scrollable.dart
parents
0e2dea86
9e9d845b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
195 additions
and
24 deletions
+195
-24
ensure_visible.dart
examples/widgets/ensure_visible.dart
+118
-0
scrollable.dart
packages/flutter/lib/widgets/scrollable.dart
+72
-23
tabs.dart
packages/flutter/lib/widgets/tabs.dart
+5
-1
No files found.
examples/widgets/ensure_visible.dart
0 → 100644
View file @
16ffdc67
// 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/animated_value.dart'
;
import
'package:sky/animation/animation_performance.dart'
;
import
'package:sky/animation/curves.dart'
;
import
'package:sky/base/lerp.dart'
;
import
'package:sky/painting/box_painter.dart'
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/rendering/box.dart'
;
import
'package:sky/theme/colors.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/block_viewport.dart'
;
import
'package:sky/widgets/card.dart'
;
import
'package:sky/widgets/icon.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'
;
import
'package:sky/widgets/framework.dart'
;
import
'package:sky/widgets/task_description.dart'
;
class
CardModel
{
CardModel
(
this
.
value
,
this
.
height
,
this
.
color
);
int
value
;
double
height
;
Color
color
;
String
get
label
=>
"Card
$value
"
;
Key
get
key
=>
new
Key
.
fromObjectIdentity
(
this
);
}
class
EnsureVisibleApp
extends
App
{
static
const
TextStyle
cardLabelStyle
=
const
TextStyle
(
color:
white
,
fontSize:
18.0
,
fontWeight:
bold
);
List
<
CardModel
>
cardModels
;
BlockViewportLayoutState
layoutState
=
new
BlockViewportLayoutState
();
ScrollListener
scrollListener
;
AnimationPerformance
scrollAnimation
;
void
initState
()
{
List
<
double
>
cardHeights
=
<
double
>[
48.0
,
63.0
,
82.0
,
146.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
63.0
,
82.0
,
146.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
,
48.0
,
63.0
,
82.0
,
146.0
,
60.0
,
55.0
,
84.0
,
96.0
,
50.0
];
cardModels
=
new
List
.
generate
(
cardHeights
.
length
,
(
i
)
{
Color
color
=
lerpColor
(
Red
[
300
],
Blue
[
900
],
i
/
cardHeights
.
length
);
return
new
CardModel
(
i
,
cardHeights
[
i
],
color
);
});
scrollAnimation
=
new
AnimationPerformance
()
..
duration
=
const
Duration
(
milliseconds:
200
)
..
variable
=
new
AnimatedValue
<
double
>(
0.0
,
curve:
ease
);
super
.
initState
();
}
EventDisposition
handleTap
(
Widget
target
)
{
ensureWidgetIsVisible
(
target
,
animation:
scrollAnimation
);
return
EventDisposition
.
processed
;
}
Widget
builder
(
int
index
)
{
if
(
index
>=
cardModels
.
length
)
return
null
;
CardModel
cardModel
=
cardModels
[
index
];
Widget
card
=
new
Card
(
color:
cardModel
.
color
,
child:
new
Container
(
height:
cardModel
.
height
,
padding:
const
EdgeDims
.
all
(
8.0
),
child:
new
Center
(
child:
new
Text
(
cardModel
.
label
,
style:
cardLabelStyle
))
)
);
return
new
Listener
(
key:
cardModel
.
key
,
onGestureTap:
(
_
)
{
return
handleTap
(
card
);
},
child:
card
);
}
Widget
build
()
{
Widget
cardCollection
=
new
Container
(
padding:
const
EdgeDims
.
symmetric
(
vertical:
12.0
,
horizontal:
8.0
),
decoration:
new
BoxDecoration
(
backgroundColor:
Theme
.
of
(
this
).
primarySwatch
[
50
]),
child:
new
VariableHeightScrollable
(
builder:
builder
,
token:
cardModels
.
length
,
layoutState:
layoutState
)
);
return
new
IconTheme
(
data:
const
IconThemeData
(
color:
IconThemeColor
.
white
),
child:
new
Theme
(
data:
new
ThemeData
(
brightness:
ThemeBrightness
.
light
,
primarySwatch:
Blue
,
accentColor:
RedAccent
[
200
]
),
child:
new
TaskDescription
(
label:
'Cards'
,
child:
new
Scaffold
(
toolbar:
new
ToolBar
(
center:
new
Text
(
'Tap a Card'
)),
body:
cardCollection
)
)
)
);
}
}
void
main
(
)
{
runApp
(
new
EnsureVisibleApp
());
}
packages/flutter/lib/widgets/scrollable.dart
View file @
16ffdc67
...
...
@@ -9,8 +9,8 @@ import 'package:newton/newton.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/rendering/box.dart'
;
import
'package:sky/theme/view_configuration.dart'
as
config
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/block_viewport.dart'
;
...
...
@@ -44,15 +44,10 @@ abstract class Scrollable extends StatefulComponent {
ScrollDirection
scrollDirection
;
AnimatedSimulation
_toEndAnimation
;
// See _startToEndAnimation()
AnimationPerformance
_toOffsetAnimation
;
// Started by scrollTo(
offset, duration: d
)
AnimationPerformance
_toOffsetAnimation
;
// Started by scrollTo()
void
initState
()
{
_toEndAnimation
=
new
AnimatedSimulation
(
_tickScrollOffset
);
_toOffsetAnimation
=
new
AnimationPerformance
()
..
addListener
(()
{
AnimatedValue
<
double
>
offset
=
_toOffsetAnimation
.
variable
;
scrollTo
(
offset
.
value
);
});
}
void
syncFields
(
Scrollable
source
)
{
...
...
@@ -91,22 +86,39 @@ abstract class Scrollable extends StatefulComponent {
);
}
void
_startToOffsetAnimation
(
double
newScrollOffset
,
Duration
duration
)
{
_stopToEndAnimation
();
void
_startToOffsetAnimation
(
double
newScrollOffset
,
AnimationPerformance
animation
)
{
_stopToEndAnimation
();
_stopToOffsetAnimation
();
(
animation
.
variable
as
AnimatedValue
<
double
>)
..
begin
=
scrollOffset
..
end
=
newScrollOffset
;
_toOffsetAnimation
=
animation
..
progress
=
0.0
..
addListener
(
_updateToOffsetAnimation
)
..
addStatusListener
(
_updateToOffsetAnimationStatus
)
..
play
();
}
void
_updateToOffsetAnimation
()
{
AnimatedValue
<
double
>
offset
=
_toOffsetAnimation
.
variable
;
scrollTo
(
offset
.
value
);
}
void
_updateToOffsetAnimationStatus
(
AnimationStatus
status
)
{
if
(
status
==
AnimationStatus
.
dismissed
||
status
==
AnimationStatus
.
completed
)
_stopToOffsetAnimation
();
_toOffsetAnimation
..
variable
=
new
AnimatedValue
<
double
>(
scrollOffset
,
end:
newScrollOffset
,
curve:
ease
)
..
progress
=
0.0
..
duration
=
duration
..
play
();
}
void
_stopToOffsetAnimation
()
{
if
(
_toOffsetAnimation
.
isAnimating
)
_toOffsetAnimation
.
stop
();
if
(
_toOffsetAnimation
!=
null
)
{
_toOffsetAnimation
..
removeStatusListener
(
_updateToOffsetAnimationStatus
)
..
removeListener
(
_updateToOffsetAnimation
)
..
stop
();
_toOffsetAnimation
=
null
;
}
}
void
_startToEndAnimation
({
double
velocity:
0.0
})
{
...
...
@@ -127,16 +139,16 @@ abstract class Scrollable extends StatefulComponent {
super
.
didUnmount
();
}
bool
scrollTo
(
double
newScrollOffset
,
{
Duration
dur
ation
})
{
bool
scrollTo
(
double
newScrollOffset
,
{
AnimationPerformance
anim
ation
})
{
if
(
newScrollOffset
==
_scrollOffset
)
return
false
;
if
(
dur
ation
==
null
)
{
if
(
anim
ation
==
null
)
{
setState
(()
{
_scrollOffset
=
newScrollOffset
;
});
}
else
{
_startToOffsetAnimation
(
newScrollOffset
,
dur
ation
);
_startToOffsetAnimation
(
newScrollOffset
,
anim
ation
);
}
if
(
_listeners
.
length
>
0
)
...
...
@@ -178,7 +190,8 @@ abstract class Scrollable extends StatefulComponent {
}
void
_maybeSettleScrollOffset
()
{
if
(!
_toEndAnimation
.
isAnimating
&&
!
_toOffsetAnimation
.
isAnimating
)
if
(!
_toEndAnimation
.
isAnimating
&&
(
_toOffsetAnimation
==
null
||
!
_toOffsetAnimation
.
isAnimating
))
settleScrollOffset
();
}
...
...
@@ -220,6 +233,42 @@ Scrollable findScrollableAncestor({ Widget target }) {
return
ancestor
;
}
bool
ensureWidgetIsVisible
(
Widget
target
,
{
AnimationPerformance
animation
})
{
assert
(
target
.
mounted
);
assert
(
target
.
root
is
RenderBox
);
Scrollable
scrollable
=
findScrollableAncestor
(
target:
target
);
if
(
scrollable
==
null
)
return
false
;
Size
targetSize
=
(
target
.
root
as
RenderBox
).
size
;
Point
targetCenter
=
target
.
localToGlobal
(
scrollable
.
scrollDirection
==
ScrollDirection
.
vertical
?
new
Point
(
0.0
,
targetSize
.
height
/
2.0
)
:
new
Point
(
targetSize
.
width
/
2.0
,
0.0
)
);
Size
scrollableSize
=
(
scrollable
.
root
as
RenderBox
).
size
;
Point
scrollableCenter
=
scrollable
.
localToGlobal
(
scrollable
.
scrollDirection
==
ScrollDirection
.
vertical
?
new
Point
(
0.0
,
scrollableSize
.
height
/
2.0
)
:
new
Point
(
scrollableSize
.
width
/
2.0
,
0.0
)
);
double
scrollOffsetDelta
=
scrollable
.
scrollDirection
==
ScrollDirection
.
vertical
?
targetCenter
.
y
-
scrollableCenter
.
y
:
targetCenter
.
x
-
scrollableCenter
.
x
;
BoundedBehavior
scrollBehavior
=
scrollable
.
scrollBehavior
;
double
scrollOffset
=
(
scrollable
.
scrollOffset
+
scrollOffsetDelta
)
.
clamp
(
scrollBehavior
.
minScrollOffset
,
scrollBehavior
.
maxScrollOffset
);
if
(
scrollOffset
!=
scrollable
.
scrollOffset
)
{
scrollable
.
scrollTo
(
scrollOffset
,
animation:
animation
);
return
true
;
}
return
false
;
}
/// 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
{
...
...
packages/flutter/lib/widgets/tabs.dart
View file @
16ffdc67
...
...
@@ -407,12 +407,16 @@ class TabBar extends Scrollable {
Size
_tabBarSize
;
List
<
double
>
_tabWidths
;
AnimationPerformance
_indicatorAnimation
;
AnimationPerformance
_scrollAnimation
;
void
initState
()
{
super
.
initState
();
_indicatorAnimation
=
new
AnimationPerformance
()
..
duration
=
_kTabBarScroll
..
variable
=
new
AnimatedRect
(
null
,
curve:
ease
);
_scrollAnimation
=
new
AnimationPerformance
()
..
duration
=
_kTabBarScroll
..
variable
=
new
AnimatedValue
<
double
>(
0.0
,
curve:
ease
);
}
void
syncFields
(
TabBar
source
)
{
...
...
@@ -468,7 +472,7 @@ class TabBar extends Scrollable {
if
(
tabIndex
!=
selectedIndex
)
{
if
(
_tabWidths
!=
null
)
{
if
(
isScrollable
)
scrollTo
(
_centeredTabScrollOffset
(
tabIndex
),
duration:
_kTabBarScroll
);
scrollTo
(
_centeredTabScrollOffset
(
tabIndex
),
animation:
_scrollAnimation
);
_startIndicatorAnimation
(
selectedIndex
,
tabIndex
);
}
if
(
onChanged
!=
null
)
...
...
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