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
0c05666e
Commit
0c05666e
authored
Feb 25, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2178 from Hixie/size-obs-4
SizeObserver crusade: Dismissable
parents
28c0d4f4
a78d2c9e
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
127 additions
and
129 deletions
+127
-129
animation_controller.dart
packages/flutter/lib/src/animation/animation_controller.dart
+6
-1
dismissable.dart
packages/flutter/lib/src/widgets/dismissable.dart
+118
-126
transitions.dart
packages/flutter/lib/src/widgets/transitions.dart
+3
-2
No files found.
packages/flutter/lib/src/animation/animation_controller.dart
View file @
0c05666e
...
...
@@ -87,7 +87,12 @@ class AnimationController extends Animation<double>
/// The current value of the animation.
///
/// Setting this value stops the current animation.
/// Setting this value notifies all the listeners that the value
/// changed.
///
/// Setting this value also stops the controller if it is currently
/// running; if this happens, it also notifies all the status
/// listeners.
double
get
value
=>
_value
;
double
_value
;
void
set
value
(
double
newValue
)
{
...
...
packages/flutter/lib/src/widgets/dismissable.dart
View file @
0c05666e
...
...
@@ -68,86 +68,59 @@ class Dismissable extends StatefulComponent {
class
_DismissableState
extends
State
<
Dismissable
>
{
void
initState
()
{
super
.
initState
();
_dismissController
=
new
AnimationController
(
duration:
_kCardDismissDuration
);
_dismissController
.
addStatusListener
((
AnimationStatus
status
)
{
if
(
status
==
AnimationStatus
.
completed
)
_handleDismissCompleted
();
});
_moveController
=
new
AnimationController
(
duration:
_kCardDismissDuration
)
..
addStatusListener
(
_handleDismissStatusChanged
);
_updateMoveAnimation
();
}
AnimationController
_dismissController
;
AnimationController
_moveController
;
Animation
<
FractionalOffset
>
_moveAnimation
;
AnimationController
_resizeController
;
Animation
<
double
>
_resizeAnimation
;
Size
_size
;
double
_dragExtent
=
0.0
;
bool
_dragUnderway
=
false
;
void
dispose
()
{
_
dismiss
Controller
?.
stop
();
_
move
Controller
?.
stop
();
_resizeController
?.
stop
();
super
.
dispose
();
}
bool
get
_directionIsYAxis
{
return
config
.
direction
==
DismissDirection
.
vertical
||
config
.
direction
==
DismissDirection
.
up
||
config
.
direction
==
DismissDirection
.
down
;
}
void
_handleDismissCompleted
()
{
if
(!
_dragUnderway
)
_startResizeAnimation
();
bool
get
_directionIsXAxis
{
return
config
.
direction
==
DismissDirection
.
horizontal
||
config
.
direction
==
DismissDirection
.
left
||
config
.
direction
==
DismissDirection
.
right
;
}
bool
get
_isActive
{
return
_size
!=
null
&&
(
_dragUnderway
||
_dismissController
.
isAnimating
);
}
void
_maybeCallOnResized
()
{
if
(
config
.
onResized
!=
null
)
config
.
onResized
();
}
void
_maybeCallOnDismissed
()
{
if
(
config
.
onDismissed
!=
null
)
config
.
onDismissed
();
}
void
_startResizeAnimation
()
{
assert
(
_size
!=
null
);
assert
(
_dismissController
!=
null
);
assert
(
_dismissController
.
isCompleted
);
assert
(
_resizeController
==
null
);
setState
(()
{
_resizeController
=
new
AnimationController
(
duration:
_kCardResizeDuration
)
..
addListener
(
_handleResizeProgressChanged
);
_resizeController
.
forward
();
});
return
_dragUnderway
||
_moveController
.
isAnimating
;
}
void
_handleResizeProgressChanged
()
{
if
(
_resizeController
.
isCompleted
)
_maybeCallOnDismissed
(
);
else
_maybeCallOnResized
()
;
Size
_findSize
()
{
RenderBox
box
=
context
.
findRenderObject
();
assert
(
box
!=
null
);
assert
(
box
.
hasSize
);
return
box
.
size
;
}
void
_handleDragStart
(
_
)
{
setState
(()
{
_dragUnderway
=
true
;
if
(
_dismiss
Controller
.
isAnimating
)
{
_dragExtent
=
_dismissController
.
value
*
_size
.
width
*
_dragExtent
.
sign
;
_dismiss
Controller
.
stop
();
if
(
_move
Controller
.
isAnimating
)
{
_dragExtent
=
_moveController
.
value
*
_findSize
()
.
width
*
_dragExtent
.
sign
;
_move
Controller
.
stop
();
}
else
{
_dragExtent
=
0.0
;
_dismiss
Controller
.
value
=
0.0
;
_move
Controller
.
value
=
0.0
;
}
setState
(()
{
_updateMoveAnimation
();
});
}
void
_handleDragUpdate
(
double
delta
)
{
if
(!
_isActive
||
_
dismiss
Controller
.
isAnimating
)
if
(!
_isActive
||
_
move
Controller
.
isAnimating
)
return
;
double
oldDragExtent
=
_dragExtent
;
...
...
@@ -169,34 +142,29 @@ class _DismissableState extends State<Dismissable> {
_dragExtent
+=
delta
;
break
;
}
if
(
oldDragExtent
.
sign
!=
_dragExtent
.
sign
)
{
setState
(()
{
// Rebuild to update the new drag endpoint.
// The sign of _dragExtent is part of our build state;
// the actual value is not, it's just used to configure
// the animations.
_updateMoveAnimation
();
});
}
if
(!
_dismissController
.
isAnimating
)
_dismissController
.
value
=
_dragExtent
.
abs
()
/
_size
.
width
;
if
(!
_moveController
.
isAnimating
)
{
_moveController
.
value
=
_dragExtent
.
abs
()
/
(
_directionIsXAxis
?
_findSize
().
width
:
_findSize
().
height
);
}
}
void
_updateMoveAnimation
()
{
_moveAnimation
=
new
Tween
<
FractionalOffset
>(
begin:
FractionalOffset
.
zero
,
end:
_directionIsXAxis
?
new
FractionalOffset
(
_dragExtent
.
sign
,
0.0
)
:
new
FractionalOffset
(
0.0
,
_dragExtent
.
sign
)
).
animate
(
_moveController
);
}
bool
_isFlingGesture
(
Velocity
velocity
)
{
double
vx
=
velocity
.
pixelsPerSecond
.
dx
;
double
vy
=
velocity
.
pixelsPerSecond
.
dy
;
if
(
_directionIsYAxis
)
{
if
(
vy
.
abs
()
-
vx
.
abs
()
<
_kMinFlingVelocityDelta
)
return
false
;
switch
(
config
.
direction
)
{
case
DismissDirection
.
vertical
:
return
vy
.
abs
()
>
_kMinFlingVelocity
;
case
DismissDirection
.
up
:
return
-
vy
>
_kMinFlingVelocity
;
default
:
return
vy
>
_kMinFlingVelocity
;
}
}
else
{
if
(
_directionIsXAxis
)
{
if
(
vx
.
abs
()
-
vy
.
abs
()
<
_kMinFlingVelocityDelta
)
return
false
;
switch
(
config
.
direction
)
{
...
...
@@ -207,85 +175,109 @@ class _DismissableState extends State<Dismissable> {
default
:
return
vx
>
_kMinFlingVelocity
;
}
}
else
{
if
(
vy
.
abs
()
-
vx
.
abs
()
<
_kMinFlingVelocityDelta
)
return
false
;
switch
(
config
.
direction
)
{
case
DismissDirection
.
vertical
:
return
vy
.
abs
()
>
_kMinFlingVelocity
;
case
DismissDirection
.
up
:
return
-
vy
>
_kMinFlingVelocity
;
default
:
return
vy
>
_kMinFlingVelocity
;
}
}
return
false
;
}
void
_handleDragEnd
(
Velocity
velocity
)
{
if
(!
_isActive
||
_
dismiss
Controller
.
isAnimating
)
if
(!
_isActive
||
_
move
Controller
.
isAnimating
)
return
;
setState
(()
{
_dragUnderway
=
false
;
if
(
_dismiss
Controller
.
isCompleted
)
{
if
(
_move
Controller
.
isCompleted
)
{
_startResizeAnimation
();
}
else
if
(
_isFlingGesture
(
velocity
))
{
double
flingVelocity
=
_directionIsYAxis
?
velocity
.
pixelsPerSecond
.
dy
:
velocity
.
pixelsPerSecond
.
dx
;
double
flingVelocity
=
_directionIsXAxis
?
velocity
.
pixelsPerSecond
.
dx
:
velocity
.
pixelsPerSecond
.
dy
;
_dragExtent
=
flingVelocity
.
sign
;
_dismiss
Controller
.
fling
(
velocity:
flingVelocity
.
abs
()
*
_kFlingVelocityScale
);
}
else
if
(
_dismiss
Controller
.
value
>
_kDismissCardThreshold
)
{
_dismiss
Controller
.
forward
();
_move
Controller
.
fling
(
velocity:
flingVelocity
.
abs
()
*
_kFlingVelocityScale
);
}
else
if
(
_move
Controller
.
value
>
_kDismissCardThreshold
)
{
_move
Controller
.
forward
();
}
else
{
_dismiss
Controller
.
reverse
();
_move
Controller
.
reverse
();
}
});
}
void
_handleSizeChanged
(
Size
newSize
)
{
setState
(()
{
_size
=
new
Size
.
copy
(
newSize
);
});
}
FractionalOffset
get
_activeCardDragEndPoint
{
if
(!
_isActive
)
return
FractionalOffset
.
zero
;
if
(
_directionIsYAxis
)
return
new
FractionalOffset
(
0.0
,
_dragExtent
.
sign
);
return
new
FractionalOffset
(
_dragExtent
.
sign
,
0.0
);
void
_handleDismissStatusChanged
(
AnimationStatus
status
)
{
if
(
status
==
AnimationStatus
.
completed
&&
!
_dragUnderway
)
_startResizeAnimation
();
}
Widget
build
(
BuildContext
context
)
{
if
(
_resizeController
!=
null
)
{
// make sure you remove this widget once it's been dismissed!
assert
(
_resizeController
.
status
==
AnimationStatus
.
forward
);
Animation
<
double
>
squashAxisExtent
=
new
Tween
<
double
>(
begin:
_directionIsYAxis
?
_size
.
width
:
_size
.
height
,
void
_startResizeAnimation
()
{
assert
(
_moveController
!=
null
);
assert
(
_moveController
.
isCompleted
);
assert
(
_resizeController
==
null
);
_resizeController
=
new
AnimationController
(
duration:
_kCardResizeDuration
)
..
addListener
(
_handleResizeProgressChanged
);
_resizeController
.
forward
();
setState
(()
{
_resizeAnimation
=
new
Tween
<
double
>(
begin:
_directionIsXAxis
?
_findSize
().
height
:
_findSize
().
width
,
end:
0.0
).
animate
(
new
CurvedAnimation
(
parent:
_resizeController
,
curve:
_kCardResizeTimeCurve
));
});
}
void
_handleResizeProgressChanged
()
{
if
(
_resizeController
.
isCompleted
)
{
if
(
config
.
onDismissed
!=
null
)
config
.
onDismissed
();
}
else
{
if
(
config
.
onResized
!=
null
)
config
.
onResized
();
}
}
Widget
build
(
BuildContext
context
)
{
if
(
_resizeAnimation
!=
null
)
{
// we've been dragged aside, and are now resizing.
assert
(()
{
if
(
_resizeAnimation
.
status
!=
AnimationStatus
.
forward
)
{
assert
(
_resizeAnimation
.
status
==
AnimationStatus
.
completed
);
throw
new
WidgetError
(
'Dismissable widget completed its resize animation without being removed from the tree.
\n
'
'Make sure to implement the onDismissed handler and to immediately remove the Dismissable
\n
'
'widget from the application once that handler has fired.'
);
}
return
true
;
});
return
new
AnimatedBuilder
(
animation:
squashAxisExtent
,
animation:
_resizeAnimation
,
builder:
(
BuildContext
context
,
Widget
child
)
{
return
new
SizedBox
(
width:
_directionIsYAxis
?
squashAxisExtent
.
value
:
null
,
height:
!
_directionIsYAxis
?
squashAxisExtent
.
value
:
null
width:
!
_directionIsXAxis
?
_resizeAnimation
.
value
:
null
,
height:
_directionIsXAxis
?
_resizeAnimation
.
value
:
null
);
}
);
}
// we are not resizing. (we may be being dragged aside.)
return
new
GestureDetector
(
onHorizontalDragStart:
_directionIs
YAxis
?
null
:
_handleDragStart
,
onHorizontalDragUpdate:
_directionIs
YAxis
?
null
:
_handleDragUpdate
,
onHorizontalDragEnd:
_directionIs
YAxis
?
null
:
_handleDragEnd
,
onVerticalDragStart:
_directionIs
YAxis
?
_handleDragStart
:
null
,
onVerticalDragUpdate:
_directionIs
YAxis
?
_handleDragUpdate
:
null
,
onVerticalDragEnd:
_directionIs
YAxis
?
_handleDragEnd
:
null
,
onHorizontalDragStart:
_directionIs
XAxis
?
_handleDragStart
:
null
,
onHorizontalDragUpdate:
_directionIs
XAxis
?
_handleDragUpdate
:
null
,
onHorizontalDragEnd:
_directionIs
XAxis
?
_handleDragEnd
:
null
,
onVerticalDragStart:
_directionIs
XAxis
?
null
:
_handleDragStart
,
onVerticalDragUpdate:
_directionIs
XAxis
?
null
:
_handleDragUpdate
,
onVerticalDragEnd:
_directionIs
XAxis
?
null
:
_handleDragEnd
,
behavior:
HitTestBehavior
.
opaque
,
child:
new
SizeObserver
(
onSizeChanged:
_handleSizeChanged
,
child:
new
SlideTransition
(
position:
new
Tween
<
FractionalOffset
>(
begin:
FractionalOffset
.
zero
,
end:
_activeCardDragEndPoint
).
animate
(
_dismissController
),
position:
_moveAnimation
,
child:
config
.
child
)
)
);
}
}
packages/flutter/lib/src/widgets/transitions.dart
View file @
0c05666e
...
...
@@ -79,7 +79,9 @@ class SlideTransition extends AnimatedComponent {
Animation
<
FractionalOffset
>
position
,
this
.
transformHitTests
:
true
,
this
.
child
})
:
position
=
position
,
super
(
key:
key
,
animation:
position
);
})
:
position
=
position
,
super
(
key:
key
,
animation:
position
)
{
assert
(
position
!=
null
);
}
/// The animation that controls the position of the child.
///
...
...
@@ -87,7 +89,6 @@ class SlideTransition extends AnimatedComponent {
/// be translated horizontally by width * dx and vertically by height * dy.
final
Animation
<
FractionalOffset
>
position
;
/// Whether hit testing should be affected by the slide animation.
///
/// If false, hit testing will proceed as if the child was not translated at
...
...
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