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
db08afd0
Commit
db08afd0
authored
Jan 10, 2020
by
Shi-Hao Hong
Committed by
Flutter GitHub Bot
Jan 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow for customizable ModalRoute barrierTween (#48345)
parent
1613a62e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
203 additions
and
12 deletions
+203
-12
routes.dart
packages/flutter/lib/src/widgets/routes.dart
+36
-12
routes_test.dart
packages/flutter/test/widgets/routes_test.dart
+167
-0
No files found.
packages/flutter/lib/src/widgets/routes.dart
View file @
db08afd0
...
...
@@ -998,7 +998,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
///
/// If [barrierDismissible] is false, then tapping the barrier has no effect.
///
/// If this getter would ever start returning a different
color
,
/// If this getter would ever start returning a different
value
,
/// [changedInternalState] should be invoked so that the change can take
/// effect.
///
...
...
@@ -1062,7 +1062,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// For example, when a dialog is on the screen, the page below the dialog is
/// usually darkened by the modal barrier.
///
/// If this getter would ever start returning a different
color
,
/// If this getter would ever start returning a different
label
,
/// [changedInternalState] should be invoked so that the change can take
/// effect.
///
...
...
@@ -1073,6 +1073,32 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
/// * [ModalBarrier], the widget that implements this feature.
String
get
barrierLabel
;
/// The curve that is used for animating the modal barrier in and out.
///
/// The modal barrier is the scrim that is rendered behind each route, which
/// generally prevents the user from interacting with the route below the
/// current route, and normally partially obscures such routes.
///
/// For example, when a dialog is on the screen, the page below the dialog is
/// usually darkened by the modal barrier.
///
/// While the route is animating into position, the color is animated from
/// transparent to the specified [barrierColor].
///
/// If this getter would ever start returning a different curve,
/// [changedInternalState] should be invoked so that the change can take
/// effect.
///
/// It defaults to [Curves.ease].
///
/// See also:
///
/// * [barrierColor], which determines the color that the modal transitions
/// to.
/// * [Curves] for a collection of common curves.
/// * [AnimatedModalBarrier], the widget that implements this feature.
Curve
get
barrierCurve
=>
Curves
.
ease
;
/// Whether the route should remain in memory when it is inactive.
///
/// If this is true, then the route is maintained, so that any futures it is
...
...
@@ -1282,30 +1308,28 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
final
GlobalKey
_subtreeKey
=
GlobalKey
();
final
PageStorageBucket
_storageBucket
=
PageStorageBucket
();
static
final
Animatable
<
double
>
_easeCurveTween
=
CurveTween
(
curve:
Curves
.
ease
);
// one of the builders
OverlayEntry
_modalBarrier
;
Widget
_buildModalBarrier
(
BuildContext
context
)
{
Widget
barrier
;
if
(
barrierColor
!=
null
&&
!
offstage
)
{
// changedInternalState is called if
these update
if
(
barrierColor
!=
null
&&
!
offstage
)
{
// changedInternalState is called if
barrierColor or offstage updates
assert
(
barrierColor
!=
_kTransparent
);
final
Animation
<
Color
>
color
=
animation
.
drive
(
ColorTween
(
begin:
_kTransparent
,
end:
barrierColor
,
// changedInternalState is called if
this
updates
).
chain
(
_easeCurveTween
),
end:
barrierColor
,
// changedInternalState is called if
barrierColor
updates
).
chain
(
CurveTween
(
curve:
barrierCurve
)),
// changedInternalState is called if barrierCurve updates
);
barrier
=
AnimatedModalBarrier
(
color:
color
,
dismissible:
barrierDismissible
,
// changedInternalState is called if
this
updates
semanticsLabel:
barrierLabel
,
// changedInternalState is called if
this
updates
dismissible:
barrierDismissible
,
// changedInternalState is called if
barrierDismissible
updates
semanticsLabel:
barrierLabel
,
// changedInternalState is called if
barrierLabel
updates
barrierSemanticsDismissible:
semanticsDismissible
,
);
}
else
{
barrier
=
ModalBarrier
(
dismissible:
barrierDismissible
,
// changedInternalState is called if
this
updates
semanticsLabel:
barrierLabel
,
// changedInternalState is called if
this
updates
dismissible:
barrierDismissible
,
// changedInternalState is called if
barrierDismissible
updates
semanticsLabel:
barrierLabel
,
// changedInternalState is called if
barrierLabel
updates
barrierSemanticsDismissible:
semanticsDismissible
,
);
}
...
...
@@ -1316,7 +1340,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
);
}
return
IgnorePointer
(
ignoring:
animation
.
status
==
AnimationStatus
.
reverse
||
// changedInternalState is called when
thi
s updates
ignoring:
animation
.
status
==
AnimationStatus
.
reverse
||
// changedInternalState is called when
animation.statu
s updates
animation
.
status
==
AnimationStatus
.
dismissed
,
// dismissed is possible when doing a manual pop gesture
child:
barrier
,
);
...
...
packages/flutter/test/widgets/routes_test.dart
View file @
db08afd0
...
...
@@ -1034,6 +1034,133 @@ void main() {
expect
(
find
.
byKey
(
containerKey
),
findsNothing
);
});
});
group
(
'ModalRoute'
,
()
{
testWidgets
(
'default barrierCurve'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
return
Center
(
child:
RaisedButton
(
child:
const
Text
(
'X'
),
onPressed:
()
{
Navigator
.
of
(
context
).
push
<
void
>(
_TestDialogRouteWithCustomBarrierCurve
<
void
>(
child:
const
Text
(
'Hello World'
),
)
);
},
),
);
}
),
),
));
final
CurveTween
_defaultBarrierTween
=
CurveTween
(
curve:
Curves
.
ease
);
int
_getExpectedBarrierTweenAlphaValue
(
double
t
)
{
return
Color
.
getAlphaFromOpacity
(
_defaultBarrierTween
.
transform
(
t
));
}
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
final
Finder
animatedModalBarrier
=
find
.
byType
(
AnimatedModalBarrier
);
expect
(
animatedModalBarrier
,
findsOneWidget
);
Animation
<
Color
>
modalBarrierAnimation
;
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
,
Colors
.
transparent
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
.
alpha
,
closeTo
(
_getExpectedBarrierTweenAlphaValue
(
0.25
),
1.0
),
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
.
alpha
,
closeTo
(
_getExpectedBarrierTweenAlphaValue
(
0.50
),
1.0
),
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
.
alpha
,
closeTo
(
_getExpectedBarrierTweenAlphaValue
(
0.75
),
1.0
),
);
await
tester
.
pumpAndSettle
();
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
,
Colors
.
black
);
});
testWidgets
(
'custom barrierCurve'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
return
Center
(
child:
RaisedButton
(
child:
const
Text
(
'X'
),
onPressed:
()
{
Navigator
.
of
(
context
).
push
<
void
>(
_TestDialogRouteWithCustomBarrierCurve
<
void
>(
child:
const
Text
(
'Hello World'
),
barrierCurve:
Curves
.
linear
,
),
);
},
),
);
},
),
),
));
final
CurveTween
_customBarrierTween
=
CurveTween
(
curve:
Curves
.
linear
);
int
_getExpectedBarrierTweenAlphaValue
(
double
t
)
{
return
Color
.
getAlphaFromOpacity
(
_customBarrierTween
.
transform
(
t
));
}
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pump
();
final
Finder
animatedModalBarrier
=
find
.
byType
(
AnimatedModalBarrier
);
expect
(
animatedModalBarrier
,
findsOneWidget
);
Animation
<
Color
>
modalBarrierAnimation
;
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
,
Colors
.
transparent
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
.
alpha
,
closeTo
(
_getExpectedBarrierTweenAlphaValue
(
0.25
),
1.0
),
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
.
alpha
,
closeTo
(
_getExpectedBarrierTweenAlphaValue
(
0.50
),
1.0
),
);
await
tester
.
pump
(
const
Duration
(
milliseconds:
25
));
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
.
alpha
,
closeTo
(
_getExpectedBarrierTweenAlphaValue
(
0.75
),
1.0
),
);
await
tester
.
pumpAndSettle
();
modalBarrierAnimation
=
tester
.
widget
<
AnimatedModalBarrier
>(
animatedModalBarrier
).
color
;
expect
(
modalBarrierAnimation
.
value
,
Colors
.
black
);
});
});
}
double
_getOpacity
(
GlobalKey
key
,
WidgetTester
tester
)
{
...
...
@@ -1089,3 +1216,43 @@ class DialogObserver extends NavigatorObserver {
super
.
didPush
(
route
,
previousRoute
);
}
}
class
_TestDialogRouteWithCustomBarrierCurve
<
T
>
extends
PopupRoute
<
T
>
{
_TestDialogRouteWithCustomBarrierCurve
({
@required
Widget
child
,
Curve
barrierCurve
,
})
:
_barrierCurve
=
barrierCurve
,
_child
=
child
;
final
Widget
_child
;
@override
bool
get
barrierDismissible
=>
true
;
@override
String
get
barrierLabel
=>
null
;
@override
Color
get
barrierColor
=>
Colors
.
black
;
// easier value to test against
@override
Curve
get
barrierCurve
{
if
(
_barrierCurve
==
null
)
{
return
super
.
barrierCurve
;
}
return
_barrierCurve
;
}
final
Curve
_barrierCurve
;
@override
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
100
);
// easier value to test against
@override
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
)
{
return
Semantics
(
child:
_child
,
scopesRoute:
true
,
explicitChildNodes:
true
,
);
}
}
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