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
948f3db2
Commit
948f3db2
authored
Jan 09, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor AnimatedContainer to be reusable.
This will allow AnimatedPositioned to reuse all the same logic.
parent
682243ef
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
133 additions
and
144 deletions
+133
-144
animated_container.dart
packages/flutter/lib/src/widgets/animated_container.dart
+114
-131
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+14
-12
transitions.dart
packages/flutter/lib/src/widgets/transitions.dart
+5
-1
No files found.
packages/flutter/lib/src/widgets/animated_container.dart
View file @
948f3db2
...
...
@@ -56,80 +56,31 @@ class AnimatedMatrix4Value extends AnimatedValue<Matrix4> {
}
}
/// A container that gradually changes its values over a period of time.
///
/// This class is useful for generating simple implicit transitions between
/// different parameters to [Container]. For more complex animations, you'll
/// likely want to use a subclass of [Transition] or control a [Performance]
/// yourself.
class
AnimatedContainer
extends
StatefulComponent
{
AnimatedContainer
({
/// An abstract widget for building components that gradually change their
/// values over a period of time.
abstract
class
AnimatedWidgetBase
extends
StatefulComponent
{
AnimatedWidgetBase
({
Key
key
,
this
.
child
,
this
.
constraints
,
this
.
decoration
,
this
.
foregroundDecoration
,
this
.
margin
,
this
.
padding
,
this
.
transform
,
this
.
width
,
this
.
height
,
this
.
curve
:
Curves
.
linear
,
this
.
duration
})
:
super
(
key:
key
)
{
assert
(
margin
==
null
||
margin
.
isNonNegative
);
assert
(
padding
==
null
||
padding
.
isNonNegative
);
assert
(
decoration
==
null
||
decoration
.
debugAssertValid
());
assert
(
foregroundDecoration
==
null
||
foregroundDecoration
.
debugAssertValid
());
assert
(
curve
!=
null
);
assert
(
duration
!=
null
);
}
final
Widget
child
;
/// Additional constraints to apply to the child.
final
BoxConstraints
constraints
;
/// The decoration to paint behind the child.
final
Decoration
decoration
;
/// The decoration to paint in front of the child.
final
Decoration
foregroundDecoration
;
/// Empty space to surround the decoration.
final
EdgeDims
margin
;
/// Empty space to inscribe inside the decoration.
final
EdgeDims
padding
;
/// The transformation matrix to apply before painting the container.
final
Matrix4
transform
;
/// If non-null, requires the decoration to have this width.
final
double
width
;
/// If non-null, requires the decoration to have this height.
final
double
height
;
/// The curve to apply when animating the parameters of this container.
final
Curve
curve
;
/// The duration over which to animate the parameters of this container.
final
Duration
duration
;
_AnimatedContainerState
createState
()
=>
new
_AnimatedContainer
State
();
AnimatedWidgetBaseState
create
State
();
}
class
_AnimatedContainerState
extends
State
<
AnimatedContainer
>
{
AnimatedBoxConstraintsValue
_constraints
;
AnimatedDecorationValue
_decoration
;
AnimatedDecorationValue
_foregroundDecoration
;
AnimatedEdgeDimsValue
_margin
;
AnimatedEdgeDimsValue
_padding
;
AnimatedMatrix4Value
_transform
;
AnimatedValue
<
double
>
_width
;
AnimatedValue
<
double
>
_height
;
typedef
AnimatedValue
<
T
>
VariableConstructor
<
T
>(
T
targetValue
);
typedef
AnimatedValue
<
T
>
VariableVisitor
<
T
>(
AnimatedValue
<
T
>
variable
,
T
targetValue
,
VariableConstructor
<
T
>
constructor
);
abstract
class
AnimatedWidgetBaseState
<
T
extends
AnimatedWidgetBase
>
extends
State
<
T
>
{
Performance
_performanceController
;
PerformanceView
_performance
;
...
...
@@ -143,19 +94,14 @@ class _AnimatedContainerState extends State<AnimatedContainer> {
_configAllVariables
();
}
void
didUpdateConfig
(
AnimatedContainer
oldConfig
)
{
void
didUpdateConfig
(
T
oldConfig
)
{
if
(
config
.
curve
!=
oldConfig
.
curve
)
_updateCurve
();
_performanceController
.
duration
=
config
.
duration
;
if
(
_configAllVariables
())
{
_updateBeginValue
(
_constraints
);
_updateBeginValue
(
_decoration
);
_updateBeginValue
(
_foregroundDecoration
);
_updateBeginValue
(
_margin
);
_updateBeginValue
(
_padding
);
_updateBeginValue
(
_transform
);
_updateBeginValue
(
_width
);
_updateBeginValue
(
_height
);
forEachVariable
((
AnimatedValue
variable
,
dynamic
targetValue
,
VariableConstructor
<
T
>
constructor
)
{
_updateBeginValue
(
variable
);
return
variable
;
});
_performanceController
.
progress
=
0.0
;
_performanceController
.
play
();
}
...
...
@@ -182,14 +128,9 @@ class _AnimatedContainerState extends State<AnimatedContainer> {
void
_updateAllVariables
()
{
setState
(()
{
_updateVariable
(
_constraints
);
_updateVariable
(
_decoration
);
_updateVariable
(
_foregroundDecoration
);
_updateVariable
(
_margin
);
_updateVariable
(
_padding
);
_updateVariable
(
_transform
);
_updateVariable
(
_width
);
_updateVariable
(
_height
);
forEachVariable
((
AnimatedValue
variable
,
dynamic
targetValue
,
VariableConstructor
<
T
>
constructor
)
{
_updateVariable
(
variable
);
return
variable
;
});
});
}
...
...
@@ -206,71 +147,113 @@ class _AnimatedContainerState extends State<AnimatedContainer> {
bool
_configAllVariables
()
{
bool
startAnimation
=
false
;
if
(
config
.
constraints
!=
null
)
{
_constraints
??=
new
AnimatedBoxConstraintsValue
(
config
.
constraints
);
if
(
_updateEndValue
(
_constraints
,
config
.
constraints
))
startAnimation
=
true
;
}
else
{
_constraints
=
null
;
}
forEachVariable
((
AnimatedValue
variable
,
dynamic
targetValue
,
VariableConstructor
<
T
>
constructor
)
{
if
(
targetValue
!=
null
)
{
variable
??=
constructor
(
targetValue
);
if
(
_updateEndValue
(
variable
,
targetValue
))
startAnimation
=
true
;
}
else
{
variable
=
null
;
}
return
variable
;
});
return
startAnimation
;
}
if
(
config
.
decoration
!=
null
)
{
_decoration
??=
new
AnimatedDecorationValue
(
config
.
decoration
);
if
(
_updateEndValue
(
_decoration
,
config
.
decoration
))
startAnimation
=
true
;
}
else
{
_decoration
=
null
;
}
/// Subclasses must implement this function by running through the following
/// steps for for each animatable facet in the class:
///
/// 1. Call the visitor callback with three arguments, the first argument
/// being the current value of the AnimatedValue<T> object that represents the
/// variable (initially null), the second argument, of type T, being the value
/// on the Widget (config) that represents the current target value of the
/// variable, and the third being a callback that takes a value T (which will
/// be the second argument to the visitor callback), and that returns an
/// AnimatedValue<T> object for the variable, configured with the given value
/// as the begin value.
///
/// 2. Take the value returned from the callback, and store it. This is the
/// value to use as the current value the next time that the forEachVariable()
/// method is called.
void
forEachVariable
(
VariableVisitor
visitor
);
}
if
(
config
.
foregroundDecoration
!=
null
)
{
_foregroundDecoration
??=
new
AnimatedDecorationValue
(
config
.
foregroundDecoration
);
if
(
_updateEndValue
(
_foregroundDecoration
,
config
.
foregroundDecoration
))
startAnimation
=
true
;
}
else
{
_foregroundDecoration
=
null
;
}
/// A container that gradually changes its values over a period of time.
///
/// This class is useful for generating simple implicit transitions between
/// different parameters to [Container]. For more complex animations, you'll
/// likely want to use a subclass of [Transition] or control a [Performance]
/// yourself.
class
AnimatedContainer
extends
AnimatedWidgetBase
{
AnimatedContainer
({
Key
key
,
this
.
child
,
this
.
constraints
,
this
.
decoration
,
this
.
foregroundDecoration
,
this
.
margin
,
this
.
padding
,
this
.
transform
,
this
.
width
,
this
.
height
,
Curve
curve:
Curves
.
linear
,
Duration
duration
})
:
super
(
key:
key
,
curve:
curve
,
duration:
duration
)
{
assert
(
decoration
==
null
||
decoration
.
debugAssertValid
());
assert
(
foregroundDecoration
==
null
||
foregroundDecoration
.
debugAssertValid
());
assert
(
margin
==
null
||
margin
.
isNonNegative
);
assert
(
padding
==
null
||
padding
.
isNonNegative
);
}
if
(
config
.
margin
!=
null
)
{
_margin
??=
new
AnimatedEdgeDimsValue
(
config
.
margin
);
if
(
_updateEndValue
(
_margin
,
config
.
margin
))
startAnimation
=
true
;
}
else
{
_margin
=
null
;
}
final
Widget
child
;
if
(
config
.
padding
!=
null
)
{
_padding
??=
new
AnimatedEdgeDimsValue
(
config
.
padding
);
if
(
_updateEndValue
(
_padding
,
config
.
padding
))
startAnimation
=
true
;
}
else
{
_padding
=
null
;
}
/// Additional constraints to apply to the child.
final
BoxConstraints
constraints
;
if
(
config
.
transform
!=
null
)
{
_transform
??=
new
AnimatedMatrix4Value
(
config
.
transform
);
if
(
_updateEndValue
(
_transform
,
config
.
transform
))
startAnimation
=
true
;
}
else
{
_transform
=
null
;
}
/// The decoration to paint behind the child.
final
Decoration
decoration
;
if
(
config
.
width
!=
null
)
{
_width
??=
new
AnimatedValue
<
double
>(
config
.
width
);
if
(
_updateEndValue
(
_width
,
config
.
width
))
startAnimation
=
true
;
}
else
{
_width
=
null
;
}
/// The decoration to paint in front of the child.
final
Decoration
foregroundDecoration
;
if
(
config
.
height
!=
null
)
{
_height
??=
new
AnimatedValue
<
double
>(
config
.
height
);
if
(
_updateEndValue
(
_height
,
config
.
height
))
startAnimation
=
true
;
}
else
{
_height
=
null
;
}
/// Empty space to surround the decoration.
final
EdgeDims
margin
;
return
startAnimation
;
/// Empty space to inscribe inside the decoration.
final
EdgeDims
padding
;
/// The transformation matrix to apply before painting the container.
final
Matrix4
transform
;
/// If non-null, requires the decoration to have this width.
final
double
width
;
/// If non-null, requires the decoration to have this height.
final
double
height
;
_AnimatedContainerState
createState
()
=>
new
_AnimatedContainerState
();
}
class
_AnimatedContainerState
extends
AnimatedWidgetBaseState
<
AnimatedContainer
>
{
AnimatedBoxConstraintsValue
_constraints
;
AnimatedDecorationValue
_decoration
;
AnimatedDecorationValue
_foregroundDecoration
;
AnimatedEdgeDimsValue
_margin
;
AnimatedEdgeDimsValue
_padding
;
AnimatedMatrix4Value
_transform
;
AnimatedValue
<
double
>
_width
;
AnimatedValue
<
double
>
_height
;
void
forEachVariable
(
VariableVisitor
visitor
)
{
// TODO(ianh): Use constructor tear-offs when it becomes possible
_constraints
=
visitor
(
_constraints
,
config
.
constraints
,
(
dynamic
value
)
=>
new
AnimatedBoxConstraintsValue
(
value
));
_decoration
=
visitor
(
_decoration
,
config
.
decoration
,
(
dynamic
value
)
=>
new
AnimatedDecorationValue
(
value
));
_foregroundDecoration
=
visitor
(
_foregroundDecoration
,
config
.
foregroundDecoration
,
(
dynamic
value
)
=>
new
AnimatedDecorationValue
(
value
));
_margin
=
visitor
(
_margin
,
config
.
margin
,
(
dynamic
value
)
=>
new
AnimatedEdgeDimsValue
(
value
));
_padding
=
visitor
(
_padding
,
config
.
padding
,
(
dynamic
value
)
=>
new
AnimatedEdgeDimsValue
(
value
));
_transform
=
visitor
(
_transform
,
config
.
transform
,
(
dynamic
value
)
=>
new
AnimatedMatrix4Value
(
value
));
_width
=
visitor
(
_width
,
config
.
width
,
(
dynamic
value
)
=>
new
AnimatedValue
<
double
>(
value
));
_height
=
visitor
(
_height
,
config
.
height
,
(
dynamic
value
)
=>
new
AnimatedValue
<
double
>(
value
));
}
Widget
build
(
BuildContext
context
)
{
...
...
packages/flutter/lib/src/widgets/basic.dart
View file @
948f3db2
...
...
@@ -1023,15 +1023,15 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
Positioned
({
Key
key
,
Widget
child
,
this
.
left
,
this
.
top
,
this
.
right
,
this
.
bottom
,
this
.
left
,
this
.
width
,
this
.
height
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
top
==
null
||
bottom
==
null
||
height
==
null
);
assert
(
left
==
null
||
right
==
null
||
width
==
null
);
assert
(
top
==
null
||
bottom
==
null
||
height
==
null
);
}
Positioned
.
fromRect
({
...
...
@@ -1046,6 +1046,9 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
bottom
=
null
,
super
(
key:
key
,
child:
child
);
/// The offset of the child's left edge from the left of the stack.
final
double
left
;
/// The offset of the child's top edge from the top of the stack.
final
double
top
;
...
...
@@ -1055,17 +1058,16 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
/// The offset of the child's bottom edge from the bottom of the stack.
final
double
bottom
;
/// The offset of the child's left edge from the left of the stack.
final
double
left
;
/// The child's width.
///
/// Ignored if both left and right are non-null.
/// Only two out of the three horizontal values (left, right, width) can be
/// set. The third must be null.
final
double
width
;
/// The child's height.
///
/// Ignored if both top and bottom are non-null.
/// Only two out of the three vertical values (top, bottom, height) can be
/// set. The third must be null.
final
double
height
;
void
applyParentData
(
RenderObject
renderObject
)
{
...
...
@@ -1073,6 +1075,11 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
final
StackParentData
parentData
=
renderObject
.
parentData
;
bool
needsLayout
=
false
;
if
(
parentData
.
left
!=
left
)
{
parentData
.
left
=
left
;
needsLayout
=
true
;
}
if
(
parentData
.
top
!=
top
)
{
parentData
.
top
=
top
;
needsLayout
=
true
;
...
...
@@ -1088,11 +1095,6 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
needsLayout
=
true
;
}
if
(
parentData
.
left
!=
left
)
{
parentData
.
left
=
left
;
needsLayout
=
true
;
}
if
(
parentData
.
width
!=
width
)
{
parentData
.
width
=
width
;
needsLayout
=
true
;
...
...
packages/flutter/lib/src/widgets/transitions.dart
View file @
948f3db2
...
...
@@ -226,7 +226,11 @@ class AnimatedRelativeRectValue extends AnimatedValue<RelativeRect> {
RelativeRect
lerp
(
double
t
)
=>
RelativeRect
.
lerp
(
begin
,
end
,
t
);
}
/// Animated version of [Positioned].
/// Animated version of [Positioned] which takes a specific
/// [AnimatedRelativeRectValue] and a [PerformanceView] to transition the
/// child's position from a start position to and end position over the lifetime
/// of the performance.
///
/// Only works if it's the child of a [Stack].
class
PositionedTransition
extends
TransitionWithChild
{
PositionedTransition
({
...
...
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