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
ecb6efa9
Commit
ecb6efa9
authored
Mar 01, 2017
by
Adam Barth
Committed by
GitHub
Mar 01, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generalize AnimatedWidget to work with any Listenable (#8469)
parent
18ad3eb5
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
65 additions
and
49 deletions
+65
-49
bottom_navigation_demo.dart
...ples/flutter_gallery/lib/demo/bottom_navigation_demo.dart
+4
-2
page.dart
packages/flutter/lib/src/material/page.dart
+4
-4
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+2
-1
modal_barrier.dart
packages/flutter/lib/src/widgets/modal_barrier.dart
+2
-2
transitions.dart
packages/flutter/lib/src/widgets/transitions.dart
+51
-38
page_forward_transitions_test.dart
...s/flutter/test/widgets/page_forward_transitions_test.dart
+2
-2
No files found.
examples/flutter_gallery/lib/demo/bottom_navigation_demo.dart
View file @
ecb6efa9
...
...
@@ -154,8 +154,10 @@ class _BottomNavigationDemoState extends State<BottomNavigationDemo>
// We want to have the newly animating (fading in) views on top.
transitions
.
sort
((
FadeTransition
a
,
FadeTransition
b
)
{
double
aValue
=
a
.
animation
.
value
;
double
bValue
=
b
.
animation
.
value
;
final
Animation
<
double
>
aAnimation
=
a
.
listenable
;
final
Animation
<
double
>
bAnimation
=
b
.
listenable
;
final
double
aValue
=
aAnimation
.
value
;
final
double
bValue
=
bAnimation
.
value
;
return
aValue
.
compareTo
(
bValue
);
});
...
...
packages/flutter/lib/src/material/page.dart
View file @
ecb6efa9
...
...
@@ -24,7 +24,7 @@ class _MountainViewPageTransition extends AnimatedWidget {
this
.
child
,
})
:
super
(
key:
key
,
animation
:
_kTween
.
animate
(
new
CurvedAnimation
(
listenable
:
_kTween
.
animate
(
new
CurvedAnimation
(
parent:
animation
,
// The route's linear 0.0 - 1.0 animation.
curve:
Curves
.
fastOutSlowIn
)
...
...
@@ -36,7 +36,7 @@ class _MountainViewPageTransition extends AnimatedWidget {
Widget
build
(
BuildContext
context
)
{
// TODO(ianh): tell the transform to be un-transformed for hit testing
return
new
SlideTransition
(
position:
animation
,
position:
listenable
,
child:
child
);
}
...
...
@@ -55,7 +55,7 @@ class _CupertinoPageTransition extends AnimatedWidget {
this
.
child
})
:
super
(
key:
key
,
animation
:
_kTween
.
animate
(
new
CurvedAnimation
(
listenable
:
_kTween
.
animate
(
new
CurvedAnimation
(
parent:
animation
,
curve:
new
_CupertinoTransitionCurve
(
null
)
)
...
...
@@ -68,7 +68,7 @@ class _CupertinoPageTransition extends AnimatedWidget {
// TODO(ianh): tell the transform to be un-transformed for hit testing
// but not while being controlled by a gesture.
return
new
SlideTransition
(
position:
animation
,
position:
listenable
,
child:
new
Material
(
elevation:
6
,
child:
child
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
ecb6efa9
...
...
@@ -112,7 +112,7 @@ class _TabStyle extends AnimatedWidget {
this
.
labelStyle
,
this
.
unselectedLabelStyle
,
@required
this
.
child
,
})
:
super
(
key:
key
,
animation
:
animation
);
})
:
super
(
key:
key
,
listenable
:
animation
);
final
TextStyle
labelStyle
;
final
TextStyle
unselectedLabelStyle
;
...
...
@@ -131,6 +131,7 @@ class _TabStyle extends AnimatedWidget {
:
defaultUnselectedStyle
;
final
Color
selectedColor
=
labelColor
??
themeData
.
primaryTextTheme
.
body2
.
color
;
final
Color
unselectedColor
=
unselectedLabelColor
??
selectedColor
.
withAlpha
(
0xB2
);
// 70% alpha
final
Animation
<
double
>
animation
=
listenable
;
final
Color
color
=
selected
?
Color
.
lerp
(
unselectedColor
,
selectedColor
,
animation
.
value
)
:
Color
.
lerp
(
selectedColor
,
unselectedColor
,
animation
.
value
);
...
...
packages/flutter/lib/src/widgets/modal_barrier.dart
View file @
ecb6efa9
...
...
@@ -54,10 +54,10 @@ class AnimatedModalBarrier extends AnimatedWidget {
Key
key
,
Animation
<
Color
>
color
,
this
.
dismissable
:
true
})
:
super
(
key:
key
,
animation
:
color
);
})
:
super
(
key:
key
,
listenable
:
color
);
/// If non-null, fill the barrier with this color.
Animation
<
Color
>
get
color
=>
animation
;
Animation
<
Color
>
get
color
=>
listenable
;
/// Whether touching the barrier will pop the current route off the [Navigator].
final
bool
dismissable
;
...
...
packages/flutter/lib/src/widgets/transitions.dart
View file @
ecb6efa9
...
...
@@ -12,29 +12,44 @@ import 'framework.dart';
export
'package:flutter/rendering.dart'
show
RelativeRect
;
/// A widget that rebuilds when the given
animation
changes value.
/// A widget that rebuilds when the given
[Listenable]
changes value.
///
/// AnimatedWidget is most useful for stateless animated widgets. To use
/// AnimatedWidget, simply subclass it and implement the build function.
/// [AnimatedWidget] is most common used with [Animation] objects, which are
/// [Listenable], but it can be used with any [Listenable], including
/// [ChangeNotifier] and [ValueNotifier].
///
/// [AnimatedWidget] is most useful for widgets widgets that are otherwise
/// stateless. To use [AnimatedWidget], simply subclass it and implement the
/// build function.
///
/// For more complex case involving additional state, consider using
/// [AnimatedBuilder].
///
/// See also:
///
/// * [AnimatedBuilder], which is useful for more complex use cases.
/// * [Animation], which is a [Listenable] object that can be used for
/// [listenable].
/// * [ChangeNotifier], which is another [Listenable] object that can be used
/// for [listenable].
abstract
class
AnimatedWidget
extends
StatefulWidget
{
/// Creates a widget that rebuilds when the given
animation changes value
.
/// Creates a widget that rebuilds when the given
listenable changes
.
///
/// The [
animation
] argument is required.
/// The [
listenable
] argument is required.
AnimatedWidget
({
Key
key
,
@required
this
.
animation
@required
this
.
listenable
})
:
super
(
key:
key
)
{
assert
(
animation
!=
null
);
assert
(
listenable
!=
null
);
}
/// The animation to which this widget is listening.
final
Animation
<
Object
>
animation
;
/// The [Listenable] to which this widget is listening.
///
/// Commonly an [Animation] or a [ChangeNotifier].
final
Listenable
listenable
;
/// Override this method to build widgets that depend on the
current valu
e
///
of the animation
.
/// Override this method to build widgets that depend on the
state of th
e
///
listenable (e.g., the current value of the animation)
.
@protected
Widget
build
(
BuildContext
context
);
...
...
@@ -45,7 +60,7 @@ abstract class AnimatedWidget extends StatefulWidget {
@override
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'animation:
$
animation
'
);
description
.
add
(
'animation:
$
listenable
'
);
}
}
...
...
@@ -53,33 +68,31 @@ class _AnimatedState extends State<AnimatedWidget> {
@override
void
initState
()
{
super
.
initState
();
config
.
animation
.
addListener
(
_handleTick
);
config
.
listenable
.
addListener
(
_handleChange
);
}
@override
void
didUpdateConfig
(
AnimatedWidget
oldConfig
)
{
if
(
config
.
animation
!=
oldConfig
.
animation
)
{
oldConfig
.
animation
.
removeListener
(
_handleTick
);
config
.
animation
.
addListener
(
_handleTick
);
if
(
config
.
listenable
!=
oldConfig
.
listenable
)
{
oldConfig
.
listenable
.
removeListener
(
_handleChange
);
config
.
listenable
.
addListener
(
_handleChange
);
}
}
@override
void
dispose
()
{
config
.
animation
.
removeListener
(
_handleTick
);
config
.
listenable
.
removeListener
(
_handleChange
);
super
.
dispose
();
}
void
_handle
Tick
()
{
void
_handle
Change
()
{
setState
(()
{
// The
animation
's state is our build state, and it changed already.
// The
listenable
's state is our build state, and it changed already.
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
config
.
build
(
context
);
}
Widget
build
(
BuildContext
context
)
=>
config
.
build
(
context
);
}
/// Animates the position of a widget relative to its normal position.
...
...
@@ -92,13 +105,13 @@ class SlideTransition extends AnimatedWidget {
Animation
<
FractionalOffset
>
position
,
this
.
transformHitTests
:
true
,
this
.
child
,
})
:
super
(
key:
key
,
animation
:
position
);
})
:
super
(
key:
key
,
listenable
:
position
);
/// The animation that controls the position of the child.
///
/// If the current value of the position animation is (dx, dy), the child will
/// be translated horizontally by width * dx and vertically by height * dy.
Animation
<
FractionalOffset
>
get
position
=>
animation
;
Animation
<
FractionalOffset
>
get
position
=>
listenable
;
/// Whether hit testing should be affected by the slide animation.
///
...
...
@@ -132,13 +145,13 @@ class ScaleTransition extends AnimatedWidget {
Animation
<
double
>
scale
,
this
.
alignment
:
FractionalOffset
.
center
,
this
.
child
,
})
:
super
(
key:
key
,
animation
:
scale
);
})
:
super
(
key:
key
,
listenable
:
scale
);
/// The animation that controls the scale of the child.
///
/// If the current value of the scale animation is v, the child will be
/// painted v times its normal size.
Animation
<
double
>
get
scale
=>
animation
;
Animation
<
double
>
get
scale
=>
listenable
;
/// The alignment of the origin of the coordainte system in which the scale
/// takes place, relative to the size of the box.
...
...
@@ -172,13 +185,13 @@ class RotationTransition extends AnimatedWidget {
Key
key
,
Animation
<
double
>
turns
,
this
.
child
,
})
:
super
(
key:
key
,
animation
:
turns
);
})
:
super
(
key:
key
,
listenable
:
turns
);
/// The animation that controls the rotation of the child.
///
/// If the current value of the turns animation is v, the child will be
/// rotated v * 2 * pi radians before being painted.
Animation
<
double
>
get
turns
=>
animation
;
Animation
<
double
>
get
turns
=>
listenable
;
/// The widget below this widget in the tree.
final
Widget
child
;
...
...
@@ -211,7 +224,7 @@ class SizeTransition extends AnimatedWidget {
Animation
<
double
>
sizeFactor
,
this
.
axisAlignment
:
0.5
,
this
.
child
,
})
:
super
(
key:
key
,
animation
:
sizeFactor
)
{
})
:
super
(
key:
key
,
listenable
:
sizeFactor
)
{
assert
(
axis
!=
null
);
}
...
...
@@ -221,7 +234,7 @@ class SizeTransition extends AnimatedWidget {
/// The animation that controls the (clipped) size of the child. If the current value
/// of sizeFactor is v then the width or height of the widget will be its intrinsic
/// width or height multiplied by v.
Animation
<
double
>
get
sizeFactor
=>
animation
;
Animation
<
double
>
get
sizeFactor
=>
listenable
;
/// How to align the child along the axis that sizeFactor is modifying.
final
double
axisAlignment
;
...
...
@@ -259,7 +272,7 @@ class FadeTransition extends AnimatedWidget {
Key
key
,
Animation
<
double
>
opacity
,
this
.
child
,
})
:
super
(
key:
key
,
animation
:
opacity
);
})
:
super
(
key:
key
,
listenable
:
opacity
);
/// The animation that controls the opacity of the child.
///
...
...
@@ -267,7 +280,7 @@ class FadeTransition extends AnimatedWidget {
/// painted with an opacity of v. For example, if v is 0.5, the child will be
/// blended 50% with its background. Similarly, if v is 0.0, the child will be
/// completely transparent.
Animation
<
double
>
get
opacity
=>
animation
;
Animation
<
double
>
get
opacity
=>
listenable
;
/// The widget below this widget in the tree.
final
Widget
child
;
...
...
@@ -311,10 +324,10 @@ class PositionedTransition extends AnimatedWidget {
Key
key
,
Animation
<
RelativeRect
>
rect
,
@required
this
.
child
,
})
:
super
(
key:
key
,
animation
:
rect
);
})
:
super
(
key:
key
,
listenable
:
rect
);
/// The animation that controls the child's size and position.
Animation
<
RelativeRect
>
get
rect
=>
animation
;
Animation
<
RelativeRect
>
get
rect
=>
listenable
;
/// The widget below this widget in the tree.
final
Widget
child
;
...
...
@@ -348,12 +361,12 @@ class RelativePositionedTransition extends AnimatedWidget {
@required
Animation
<
Rect
>
rect
,
@required
this
.
size
,
@required
this
.
child
,
})
:
super
(
key:
key
,
animation
:
rect
);
})
:
super
(
key:
key
,
listenable
:
rect
);
/// The animation that controls the child's size and position.
///
/// See also [size].
Animation
<
Rect
>
get
rect
=>
animation
;
Animation
<
Rect
>
get
rect
=>
listenable
;
/// The [Positioned] widget's offsets are relative to a box of this
/// size whose origin is 0,0.
...
...
@@ -407,10 +420,10 @@ class AnimatedBuilder extends AnimatedWidget {
/// The [animation] and [builder] arguments must not be null.
AnimatedBuilder
({
Key
key
,
@required
Animation
<
Object
>
animation
,
@required
Listenable
animation
,
@required
this
.
builder
,
this
.
child
,
})
:
super
(
key:
key
,
animation
:
animation
)
{
})
:
super
(
key:
key
,
listenable
:
animation
)
{
assert
(
builder
!=
null
);
}
...
...
packages/flutter/test/widgets/page_forward_transitions_test.dart
View file @
ecb6efa9
...
...
@@ -12,14 +12,14 @@ class TestTransition extends AnimatedWidget {
this
.
childFirstHalf
,
this
.
childSecondHalf
,
Animation
<
double
>
animation
})
:
super
(
key:
key
,
animation
:
animation
);
})
:
super
(
key:
key
,
listenable
:
animation
);
final
Widget
childFirstHalf
;
final
Widget
childSecondHalf
;
@override
Widget
build
(
BuildContext
context
)
{
final
Animation
<
double
>
animation
=
this
.
animation
;
final
Animation
<
double
>
animation
=
this
.
listenable
;
if
(
animation
.
value
>=
0.5
)
return
childSecondHalf
;
return
childFirstHalf
;
...
...
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