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
d5e71f76
Commit
d5e71f76
authored
Nov 16, 2015
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #385 from Hixie/MaterialPageRoute
Move Material page animations to Material layer.
parents
8bc9e1b8
309d25d4
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
300 additions
and
149 deletions
+300
-149
material.dart
packages/flutter/lib/material.dart
+4
-3
performance.dart
packages/flutter/lib/src/animation/performance.dart
+1
-1
dialog.dart
packages/flutter/lib/src/material/dialog.dart
+3
-1
material_app.dart
packages/flutter/lib/src/material/material_app.dart
+5
-4
page.dart
packages/flutter/lib/src/material/page.dart
+73
-0
popup_menu.dart
packages/flutter/lib/src/material/popup_menu.dart
+1
-1
hero_controller.dart
packages/flutter/lib/src/widgets/hero_controller.dart
+28
-52
modal_barrier.dart
packages/flutter/lib/src/widgets/modal_barrier.dart
+13
-70
navigator.dart
packages/flutter/lib/src/widgets/navigator.dart
+35
-8
routes.dart
packages/flutter/lib/src/widgets/routes.dart
+130
-1
status_transitions.dart
packages/flutter/lib/src/widgets/status_transitions.dart
+2
-2
widgets.dart
packages/flutter/lib/widgets.dart
+0
-1
bottom_sheet_test.dart
packages/unit/test/widget/bottom_sheet_test.dart
+2
-2
remember_scroll_position_test.dart
packages/unit/test/widget/remember_scroll_position_test.dart
+3
-3
No files found.
packages/flutter/lib/material.dart
View file @
d5e71f76
...
@@ -33,9 +33,11 @@ export 'src/material/material.dart';
...
@@ -33,9 +33,11 @@ export 'src/material/material.dart';
export
'src/material/material_app.dart'
;
export
'src/material/material_app.dart'
;
export
'src/material/material_button.dart'
;
export
'src/material/material_button.dart'
;
export
'src/material/material_list.dart'
;
export
'src/material/material_list.dart'
;
export
'src/material/p
opup_menu_item
.dart'
;
export
'src/material/p
age
.dart'
;
export
'src/material/popup_menu.dart'
;
export
'src/material/popup_menu.dart'
;
export
'src/material/popup_menu_item.dart'
;
export
'src/material/progress_indicator.dart'
;
export
'src/material/progress_indicator.dart'
;
export
'src/material/radial_reaction.dart'
;
export
'src/material/radio.dart'
;
export
'src/material/radio.dart'
;
export
'src/material/raised_button.dart'
;
export
'src/material/raised_button.dart'
;
export
'src/material/scaffold.dart'
;
export
'src/material/scaffold.dart'
;
...
@@ -44,11 +46,10 @@ export 'src/material/shadows.dart';
...
@@ -44,11 +46,10 @@ export 'src/material/shadows.dart';
export
'src/material/snack_bar.dart'
;
export
'src/material/snack_bar.dart'
;
export
'src/material/switch.dart'
;
export
'src/material/switch.dart'
;
export
'src/material/tabs.dart'
;
export
'src/material/tabs.dart'
;
export
'src/material/theme_data.dart'
;
export
'src/material/theme.dart'
;
export
'src/material/theme.dart'
;
export
'src/material/theme_data.dart'
;
export
'src/material/title.dart'
;
export
'src/material/title.dart'
;
export
'src/material/tool_bar.dart'
;
export
'src/material/tool_bar.dart'
;
export
'src/material/typography.dart'
;
export
'src/material/typography.dart'
;
export
'src/material/radial_reaction.dart'
;
export
'widgets.dart'
;
export
'widgets.dart'
;
packages/flutter/lib/src/animation/performance.dart
View file @
d5e71f76
...
@@ -168,7 +168,7 @@ class Performance extends PerformanceView {
...
@@ -168,7 +168,7 @@ class Performance extends PerformanceView {
/// Returns a [PerformanceView] for this performance,
/// Returns a [PerformanceView] for this performance,
/// so that a pointer to this object can be passed around without
/// so that a pointer to this object can be passed around without
/// allowing users of that pointer to mutate the
Animation
Performance state.
/// allowing users of that pointer to mutate the Performance state.
PerformanceView
get
view
=>
this
;
PerformanceView
get
view
=>
this
;
/// The length of time this performance should last
/// The length of time this performance should last
...
...
packages/flutter/lib/src/material/dialog.dart
View file @
d5e71f76
...
@@ -124,7 +124,9 @@ class _DialogRoute extends ModalRoute {
...
@@ -124,7 +124,9 @@ class _DialogRoute extends ModalRoute {
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
150
);
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
150
);
Color
get
barrierColor
=>
Colors
.
black54
;
Color
get
barrierColor
=>
Colors
.
black54
;
Widget
buildModalWidget
(
BuildContext
context
)
{
Widget
buildPage
(
BuildContext
context
)
=>
child
;
Widget
buildTransition
(
BuildContext
context
,
PerformanceView
performance
,
Widget
child
)
{
return
new
FadeTransition
(
return
new
FadeTransition
(
performance:
performance
,
performance:
performance
,
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
Curves
.
easeOut
),
opacity:
new
AnimatedValue
<
double
>(
0.0
,
end:
1.0
,
curve:
Curves
.
easeOut
),
...
...
packages/flutter/lib/src/material/material_app.dart
View file @
d5e71f76
...
@@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart';
...
@@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart';
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'page.dart'
;
import
'theme.dart'
;
import
'theme.dart'
;
import
'title.dart'
;
import
'title.dart'
;
...
@@ -95,13 +96,12 @@ class _MaterialAppState extends State<MaterialApp> {
...
@@ -95,13 +96,12 @@ class _MaterialAppState extends State<MaterialApp> {
final
HeroController
_heroController
=
new
HeroController
();
final
HeroController
_heroController
=
new
HeroController
();
Route
_generateRoute
(
NamedRouteSettings
settings
)
{
Route
_generateRoute
(
NamedRouteSettings
settings
)
{
return
new
Hero
PageRoute
(
return
new
Material
PageRoute
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
RouteBuilder
builder
=
config
.
routes
[
settings
.
name
]
??
config
.
onGenerateRoute
(
settings
.
name
);
RouteBuilder
builder
=
config
.
routes
[
settings
.
name
]
??
config
.
onGenerateRoute
(
settings
.
name
);
return
builder
(
new
RouteArguments
(
context:
context
));
return
builder
(
new
RouteArguments
(
context:
context
));
},
},
settings:
settings
,
settings:
settings
heroController:
_heroController
);
);
}
}
...
@@ -118,7 +118,8 @@ class _MaterialAppState extends State<MaterialApp> {
...
@@ -118,7 +118,8 @@ class _MaterialAppState extends State<MaterialApp> {
title:
config
.
title
,
title:
config
.
title
,
child:
new
Navigator
(
child:
new
Navigator
(
key:
_navigator
,
key:
_navigator
,
onGenerateRoute:
_generateRoute
onGenerateRoute:
_generateRoute
,
observer:
_heroController
)
)
)
)
)
)
...
...
packages/flutter/lib/src/
widgets
/page.dart
→
packages/flutter/lib/src/
material
/page.dart
View file @
d5e71f76
...
@@ -3,16 +3,10 @@
...
@@ -3,16 +3,10 @@
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/animation.dart'
;
import
'package:flutter/animation.dart'
;
import
'package:flutter/widgets.dart'
;
import
'basic.dart'
;
class
_MaterialPageTransition
extends
TransitionWithChild
{
import
'framework.dart'
;
_MaterialPageTransition
({
import
'modal_barrier.dart'
;
import
'navigator.dart'
;
import
'page_storage.dart'
;
import
'transitions.dart'
;
class
_PageTransition
extends
TransitionWithChild
{
_PageTransition
({
Key
key
,
Key
key
,
PerformanceView
performance
,
PerformanceView
performance
,
Widget
child
Widget
child
...
@@ -33,6 +27,7 @@ class _PageTransition extends TransitionWithChild {
...
@@ -33,6 +27,7 @@ class _PageTransition extends TransitionWithChild {
..
translate
(
_position
.
value
.
x
,
_position
.
value
.
y
);
..
translate
(
_position
.
value
.
x
,
_position
.
value
.
y
);
return
new
Transform
(
return
new
Transform
(
transform:
transform
,
transform:
transform
,
// TODO(ianh): tell the transform to be un-transformed for hit testing
child:
new
Opacity
(
child:
new
Opacity
(
opacity:
_opacity
.
value
,
opacity:
_opacity
.
value
,
child:
child
child:
child
...
@@ -41,82 +36,38 @@ class _PageTransition extends TransitionWithChild {
...
@@ -41,82 +36,38 @@ class _PageTransition extends TransitionWithChild {
}
}
}
}
class
_Page
extends
StatefulComponent
{
class
MaterialPageRoute
extends
ModalRoute
{
_Page
({
MaterialPageRoute
({
Key
key
,
this
.
builder
,
this
.
route
NamedRouteSettings
settings:
const
NamedRouteSettings
()
})
:
super
(
key:
key
);
})
:
super
(
settings:
settings
)
{
assert
(
builder
!=
null
);
final
PageRoute
route
;
assert
(
opaque
);
}
_PageState
createState
()
=>
new
_PageState
();
final
WidgetBuilder
builder
;
}
class
_PageState
extends
State
<
_Page
>
{
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
150
);
final
GlobalKey
_subtreeKey
=
new
GlobalKey
();
Widget
build
(
BuildContext
context
)
{
bool
get
opaque
=>
true
;
if
(
config
.
route
.
_offstage
)
{
return
new
OffStage
(
child:
new
PageStorage
(
key:
_subtreeKey
,
bucket:
config
.
route
.
_storageBucket
,
child:
_invokeBuilder
()
)
);
}
return
new
_PageTransition
(
performance:
config
.
route
.
performance
,
child:
new
PageStorage
(
key:
_subtreeKey
,
bucket:
config
.
route
.
_storageBucket
,
child:
_invokeBuilder
()
)
);
}
Widget
_invokeBuilder
(
)
{
Widget
buildPage
(
BuildContext
context
)
{
Widget
result
=
config
.
route
.
builder
(
context
);
Widget
result
=
builder
(
context
);
assert
(()
{
assert
(()
{
if
(
result
==
null
)
if
(
result
==
null
)
debugPrint
(
'The builder for route
\'
${
config.route
.name}
\'
returned null. Route builders must never return null.'
);
debugPrint
(
'The builder for route
\'
${
settings
.name}
\'
returned null. Route builders must never return null.'
);
assert
(
result
!=
null
&&
'A route builder returned null. See the previous log message for details.'
is
String
);
assert
(
result
!=
null
&&
'A route builder returned null. See the previous log message for details.'
is
String
);
return
true
;
return
true
;
});
});
return
result
;
return
result
;
}
}
}
class
PageRoute
extends
ModalRoute
{
Widget
buildTransition
(
BuildContext
context
,
PerformanceView
performance
,
Widget
child
)
{
PageRoute
({
return
new
_MaterialPageTransition
(
this
.
builder
,
performance:
performance
,
this
.
settings
:
const
NamedRouteSettings
()
child:
child
})
{
);
assert
(
builder
!=
null
);
assert
(
opaque
);
}
final
WidgetBuilder
builder
;
final
NamedRouteSettings
settings
;
final
GlobalKey
<
_PageState
>
pageKey
=
new
GlobalKey
<
_PageState
>();
bool
get
opaque
=>
true
;
String
get
name
=>
settings
.
name
;
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
150
);
Widget
buildModalWidget
(
BuildContext
context
)
=>
new
_Page
(
key:
pageKey
,
route:
this
);
final
PageStorageBucket
_storageBucket
=
new
PageStorageBucket
();
bool
get
offstage
=>
_offstage
;
bool
_offstage
=
false
;
void
set
offstage
(
bool
value
)
{
if
(
_offstage
==
value
)
return
;
_offstage
=
value
;
pageKey
.
currentState
?.
setState
(()
{
});
}
}
String
get
debugLabel
=>
'
${super.debugLabel}
(
$
name
)'
;
String
get
debugLabel
=>
'
${super.debugLabel}
(
$
{settings.name}
)'
;
}
}
packages/flutter/lib/src/material/popup_menu.dart
View file @
d5e71f76
...
@@ -110,7 +110,7 @@ class _MenuRoute extends ModalRoute {
...
@@ -110,7 +110,7 @@ class _MenuRoute extends ModalRoute {
bool
get
opaque
=>
false
;
bool
get
opaque
=>
false
;
Duration
get
transitionDuration
=>
_kMenuDuration
;
Duration
get
transitionDuration
=>
_kMenuDuration
;
Widget
build
ModalWidget
(
BuildContext
context
)
=>
new
_PopupMenu
(
route:
this
);
Widget
build
Page
(
BuildContext
context
)
=>
new
_PopupMenu
(
route:
this
);
}
}
Future
showMenu
(
{
BuildContext
context
,
ModalPosition
position
,
List
<
PopupMenuItem
>
items
,
int
level:
4
})
{
Future
showMenu
(
{
BuildContext
context
,
ModalPosition
position
,
List
<
PopupMenuItem
>
items
,
int
level:
4
})
{
...
...
packages/flutter/lib/src/widgets/hero_controller.dart
View file @
d5e71f76
...
@@ -10,68 +10,46 @@ import 'framework.dart';
...
@@ -10,68 +10,46 @@ import 'framework.dart';
import
'heroes.dart'
;
import
'heroes.dart'
;
import
'navigator.dart'
;
import
'navigator.dart'
;
import
'overlay.dart'
;
import
'overlay.dart'
;
import
'page.dart'
;
import
'routes.dart'
;
class
HeroPageRoute
extends
PageRoute
{
HeroPageRoute
({
WidgetBuilder
builder
,
NamedRouteSettings
settings:
const
NamedRouteSettings
(),
this
.
heroController
})
:
super
(
builder:
builder
,
settings:
settings
);
final
HeroController
heroController
;
NavigatorState
_navigator
;
void
didPush
(
OverlayState
overlay
,
OverlayEntry
insertionPoint
)
{
super
.
didPush
(
overlay
,
insertionPoint
);
// TODO(abarth): Pass the NavigatorState explicitly.
if
(
overlay
!=
null
)
{
_navigator
=
Navigator
.
of
(
overlay
.
context
);
heroController
?.
didPush
(
_navigator
,
this
);
}
}
void
didPop
(
dynamic
result
)
{
super
.
didPop
(
result
);
if
(
_navigator
!=
null
)
{
heroController
?.
didPop
(
_navigator
,
this
);
_navigator
=
null
;
}
}
}
class
HeroController
{
class
HeroController
extends
NavigatorObserver
{
HeroController
()
{
HeroController
()
{
_party
=
new
HeroParty
(
onQuestFinished:
_handleQuestFinished
);
_party
=
new
HeroParty
(
onQuestFinished:
_handleQuestFinished
);
}
}
HeroParty
_party
;
HeroParty
_party
;
PerformanceView
_performance
;
PerformanceView
_performance
;
HeroPage
Route
_from
;
Modal
Route
_from
;
HeroPage
Route
_to
;
Modal
Route
_to
;
final
List
<
OverlayEntry
>
_overlayEntries
=
new
List
<
OverlayEntry
>();
final
List
<
OverlayEntry
>
_overlayEntries
=
new
List
<
OverlayEntry
>();
void
didPush
(
NavigatorState
navigator
,
HeroPageRoute
route
)
{
void
didPushModal
(
Route
route
)
{
assert
(
navigator
!=
null
);
assert
(
route
!=
null
);
assert
(
route
!=
null
);
assert
(
route
.
performance
!=
null
);
if
(
route
is
ModalRoute
)
{
// as opposed to StateRoute, say
Route
from
=
navigator
.
currentRoute
;
assert
(
route
.
performance
!=
null
);
if
(
from
is
HeroPageRoute
)
Route
from
=
navigator
.
currentRoute
;
_from
=
from
;
if
(
from
is
ModalRoute
)
// as opposed to the many other types of routes, or null
_to
=
route
;
_from
=
from
;
_performance
=
route
.
performance
;
_to
=
route
;
_checkForHeroQuest
();
_performance
=
route
.
performance
;
_checkForHeroQuest
();
}
}
}
void
didPop
(
NavigatorState
navigator
,
HeroPageRoute
route
)
{
void
didPopModal
(
Route
route
)
{
assert
(
navigator
!=
null
);
assert
(
route
!=
null
);
assert
(
route
!=
null
);
assert
(
route
.
performance
!=
null
);
if
(
route
is
ModalRoute
)
{
// as opposed to StateRoute, say
Route
to
=
navigator
.
currentRoute
;
assert
(
route
.
performance
!=
null
);
if
(
to
is
HeroPageRoute
)
{
Route
to
=
navigator
.
currentRoute
;
_to
=
to
;
if
(
to
is
ModalRoute
)
{
// as opposed to the many other types of routes
_from
=
route
;
_to
=
to
;
_performance
=
route
.
performance
;
_from
=
route
;
_checkForHeroQuest
();
_performance
=
route
.
performance
;
_checkForHeroQuest
();
}
}
}
}
}
...
@@ -123,10 +101,9 @@ class HeroController {
...
@@ -123,10 +101,9 @@ class HeroController {
Set
<
Key
>
mostValuableKeys
=
_getMostValuableKeys
();
Set
<
Key
>
mostValuableKeys
=
_getMostValuableKeys
();
Map
<
Object
,
HeroHandle
>
heroesFrom
=
_party
.
isEmpty
?
Map
<
Object
,
HeroHandle
>
heroesFrom
=
_party
.
isEmpty
?
Hero
.
of
(
_from
.
pageKey
.
current
Context
,
mostValuableKeys
)
:
_party
.
getHeroesToAnimate
();
Hero
.
of
(
_from
.
subtree
Context
,
mostValuableKeys
)
:
_party
.
getHeroesToAnimate
();
BuildContext
context
=
_to
.
pageKey
.
currentContext
;
Map
<
Object
,
HeroHandle
>
heroesTo
=
Hero
.
of
(
_to
.
subtreeContext
,
mostValuableKeys
);
Map
<
Object
,
HeroHandle
>
heroesTo
=
Hero
.
of
(
context
,
mostValuableKeys
);
_to
.
offstage
=
false
;
_to
.
offstage
=
false
;
PerformanceView
performance
=
_performance
;
PerformanceView
performance
=
_performance
;
...
@@ -136,7 +113,6 @@ class HeroController {
...
@@ -136,7 +113,6 @@ class HeroController {
curve
=
new
Interval
(
performance
.
progress
,
1.0
,
curve:
curve
);
curve
=
new
Interval
(
performance
.
progress
,
1.0
,
curve:
curve
);
}
}
NavigatorState
navigator
=
Navigator
.
of
(
context
);
_party
.
animate
(
heroesFrom
,
heroesTo
,
_getAnimationArea
(
navigator
.
context
),
curve
);
_party
.
animate
(
heroesFrom
,
heroesTo
,
_getAnimationArea
(
navigator
.
context
),
curve
);
_removeHeroesFromOverlay
();
_removeHeroesFromOverlay
();
Iterable
<
Widget
>
heroes
=
_party
.
getWidgets
(
navigator
.
context
,
performance
);
Iterable
<
Widget
>
heroes
=
_party
.
getWidgets
(
navigator
.
context
,
performance
);
...
...
packages/flutter/lib/src/widgets/modal_barrier.dart
View file @
d5e71f76
...
@@ -2,32 +2,30 @@
...
@@ -2,32 +2,30 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:async'
;
import
'package:flutter/animation.dart'
;
import
'package:flutter/animation.dart'
;
import
'basic.dart'
;
import
'basic.dart'
;
import
'focus.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
import
'navigator.dart'
;
import
'navigator.dart'
;
import
'routes.dart'
;
import
'status_transitions.dart'
;
import
'transitions.dart'
;
import
'transitions.dart'
;
const
Color
_
kTransparent
=
const
Color
(
0x00000000
);
const
Color
kTransparent
=
const
Color
(
0x00000000
);
class
ModalBarrier
extends
StatelessComponent
{
class
ModalBarrier
extends
StatelessComponent
{
ModalBarrier
({
ModalBarrier
({
Key
key
,
Key
key
,
this
.
color
:
_kTransparent
this
.
color
:
kTransparent
,
this
.
dismissable
:
true
})
:
super
(
key:
key
);
})
:
super
(
key:
key
);
final
Color
color
;
final
Color
color
;
final
bool
dismissable
;
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
new
Listener
(
return
new
Listener
(
onPointerDown:
(
_
)
{
onPointerDown:
(
_
)
{
Navigator
.
of
(
context
).
pop
();
if
(
dismissable
)
Navigator
.
of
(
context
).
pop
();
},
},
child:
new
ConstrainedBox
(
child:
new
ConstrainedBox
(
constraints:
const
BoxConstraints
.
expand
(),
constraints:
const
BoxConstraints
.
expand
(),
...
@@ -45,11 +43,13 @@ class AnimatedModalBarrier extends StatelessComponent {
...
@@ -45,11 +43,13 @@ class AnimatedModalBarrier extends StatelessComponent {
AnimatedModalBarrier
({
AnimatedModalBarrier
({
Key
key
,
Key
key
,
this
.
color
,
this
.
color
,
this
.
performance
this
.
performance
,
this
.
dismissable
:
true
})
:
super
(
key:
key
);
})
:
super
(
key:
key
);
final
AnimatedColorValue
color
;
final
AnimatedColorValue
color
;
final
PerformanceView
performance
;
final
PerformanceView
performance
;
final
bool
dismissable
;
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
new
BuilderTransition
(
return
new
BuilderTransition
(
...
@@ -58,69 +58,12 @@ class AnimatedModalBarrier extends StatelessComponent {
...
@@ -58,69 +58,12 @@ class AnimatedModalBarrier extends StatelessComponent {
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
return
new
IgnorePointer
(
return
new
IgnorePointer
(
ignoring:
performance
.
status
==
PerformanceStatus
.
reverse
,
ignoring:
performance
.
status
==
PerformanceStatus
.
reverse
,
child:
new
ModalBarrier
(
color:
color
.
value
)
child:
new
ModalBarrier
(
color:
color
.
value
,
dismissable:
dismissable
)
);
);
}
}
);
);
}
}
}
}
class
_ModalScope
extends
StatusTransitionComponent
{
_ModalScope
({
Key
key
,
ModalRoute
route
,
this
.
child
})
:
route
=
route
,
super
(
key:
key
,
performance:
route
.
performance
);
final
ModalRoute
route
;
final
Widget
child
;
Widget
build
(
BuildContext
context
)
{
Widget
focus
=
new
Focus
(
key:
new
GlobalObjectKey
(
route
),
child:
new
IgnorePointer
(
ignoring:
route
.
performance
.
status
==
PerformanceStatus
.
reverse
,
child:
child
)
);
ModalPosition
position
=
route
.
position
;
if
(
position
==
null
)
return
focus
;
return
new
Positioned
(
top:
position
.
top
,
right:
position
.
right
,
bottom:
position
.
bottom
,
left:
position
.
left
,
child:
focus
);
}
}
class
ModalPosition
{
const
ModalPosition
({
this
.
top
,
this
.
right
,
this
.
bottom
,
this
.
left
});
final
double
top
;
final
double
right
;
final
double
bottom
;
final
double
left
;
}
abstract
class
ModalRoute
extends
TransitionRoute
{
ModalRoute
({
Completer
completer
})
:
super
(
completer:
completer
);
ModalPosition
get
position
=>
null
;
Color
get
barrierColor
=>
_kTransparent
;
Widget
buildModalWidget
(
BuildContext
context
);
Widget
_buildModalBarrier
(
BuildContext
context
)
{
return
new
AnimatedModalBarrier
(
color:
new
AnimatedColorValue
(
_kTransparent
,
end:
barrierColor
,
curve:
Curves
.
ease
),
performance:
performance
);
}
Widget
_buildModalScope
(
BuildContext
context
)
{
return
new
_ModalScope
(
route:
this
,
child:
buildModalWidget
(
context
));
}
List
<
WidgetBuilder
>
get
builders
=>
<
WidgetBuilder
>[
_buildModalBarrier
,
_buildModalScope
];
}
packages/flutter/lib/src/widgets/navigator.dart
View file @
d5e71f76
...
@@ -21,17 +21,26 @@ class NamedRouteSettings {
...
@@ -21,17 +21,26 @@ class NamedRouteSettings {
typedef
Route
RouteFactory
(
NamedRouteSettings
settings
);
typedef
Route
RouteFactory
(
NamedRouteSettings
settings
);
class
NavigatorObserver
{
NavigatorState
_navigator
;
NavigatorState
get
navigator
=>
_navigator
;
void
didPopModal
(
Route
route
)
{
}
void
didPushModal
(
Route
route
)
{
}
}
class
Navigator
extends
StatefulComponent
{
class
Navigator
extends
StatefulComponent
{
Navigator
({
Navigator
({
Key
key
,
Key
key
,
this
.
onGenerateRoute
,
this
.
onGenerateRoute
,
this
.
onUnknownRoute
this
.
onUnknownRoute
,
this
.
observer
})
:
super
(
key:
key
)
{
})
:
super
(
key:
key
)
{
assert
(
onGenerateRoute
!=
null
);
assert
(
onGenerateRoute
!=
null
);
}
}
final
RouteFactory
onGenerateRoute
;
final
RouteFactory
onGenerateRoute
;
final
RouteFactory
onUnknownRoute
;
final
RouteFactory
onUnknownRoute
;
final
NavigatorObserver
observer
;
static
const
String
defaultRouteName
=
'/'
;
static
const
String
defaultRouteName
=
'/'
;
...
@@ -57,9 +66,24 @@ class NavigatorState extends State<Navigator> {
...
@@ -57,9 +66,24 @@ class NavigatorState extends State<Navigator> {
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
assert
(
config
.
observer
==
null
||
config
.
observer
.
navigator
==
null
);
config
.
observer
?.
_navigator
=
this
;
push
(
config
.
onGenerateRoute
(
new
NamedRouteSettings
(
name:
Navigator
.
defaultRouteName
)));
push
(
config
.
onGenerateRoute
(
new
NamedRouteSettings
(
name:
Navigator
.
defaultRouteName
)));
}
}
void
didUpdateConfig
(
Navigator
oldConfig
)
{
if
(
oldConfig
.
observer
!=
config
.
observer
)
{
oldConfig
.
observer
?.
_navigator
=
null
;
assert
(
config
.
observer
==
null
||
config
.
observer
.
navigator
==
null
);
config
.
observer
?.
_navigator
=
this
;
}
}
void
dispose
()
{
config
.
observer
?.
_navigator
=
null
;
super
.
dispose
();
}
bool
get
hasPreviousRoute
=>
_modal
.
length
>
1
;
bool
get
hasPreviousRoute
=>
_modal
.
length
>
1
;
OverlayState
get
overlay
=>
_overlayKey
.
currentState
;
OverlayState
get
overlay
=>
_overlayKey
.
currentState
;
...
@@ -75,11 +99,7 @@ class NavigatorState extends State<Navigator> {
...
@@ -75,11 +99,7 @@ class NavigatorState extends State<Navigator> {
return
null
;
return
null
;
}
}
Route
get
currentRoute
=>
_ephemeral
.
isNotEmpty
?
_ephemeral
.
last
:
_modal
.
last
;
Route
get
currentRoute
=>
_ephemeral
.
isNotEmpty
?
_ephemeral
.
last
:
_modal
.
isNotEmpty
?
_modal
.
last
:
null
;
Route
_removeCurrentRoute
()
{
return
_ephemeral
.
isNotEmpty
?
_ephemeral
.
removeLast
()
:
_modal
.
removeLast
();
}
void
pushNamed
(
String
name
,
{
Set
<
Key
>
mostValuableKeys
})
{
void
pushNamed
(
String
name
,
{
Set
<
Key
>
mostValuableKeys
})
{
assert
(
name
!=
null
);
assert
(
name
!=
null
);
...
@@ -90,9 +110,10 @@ class NavigatorState extends State<Navigator> {
...
@@ -90,9 +110,10 @@ class NavigatorState extends State<Navigator> {
push
(
config
.
onGenerateRoute
(
settings
)
??
config
.
onUnknownRoute
(
settings
));
push
(
config
.
onGenerateRoute
(
settings
)
??
config
.
onUnknownRoute
(
settings
));
}
}
void
push
(
Route
route
)
{
void
push
(
Route
route
,
{
Set
<
Key
>
mostValuableKeys
}
)
{
_popAllEphemeralRoutes
();
_popAllEphemeralRoutes
();
route
.
didPush
(
overlay
,
_currentOverlay
);
route
.
didPush
(
overlay
,
_currentOverlay
);
config
.
observer
?.
didPushModal
(
route
);
_modal
.
add
(
route
);
_modal
.
add
(
route
);
}
}
...
@@ -110,7 +131,13 @@ class NavigatorState extends State<Navigator> {
...
@@ -110,7 +131,13 @@ class NavigatorState extends State<Navigator> {
}
}
void
pop
([
dynamic
result
])
{
void
pop
([
dynamic
result
])
{
_removeCurrentRoute
().
didPop
(
result
);
if
(
_ephemeral
.
isNotEmpty
)
{
_ephemeral
.
removeLast
().
didPop
(
result
);
}
else
{
Route
route
=
_modal
.
removeLast
();
route
.
didPop
(
result
);
config
.
observer
?.
didPopModal
(
route
);
}
}
}
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
...
...
packages/flutter/lib/src/widgets/routes.dart
View file @
d5e71f76
...
@@ -7,9 +7,13 @@ import 'dart:async';
...
@@ -7,9 +7,13 @@ import 'dart:async';
import
'package:flutter/animation.dart'
;
import
'package:flutter/animation.dart'
;
import
'basic.dart'
;
import
'basic.dart'
;
import
'focus.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
import
'modal_barrier.dart'
;
import
'navigator.dart'
;
import
'navigator.dart'
;
import
'overlay.dart'
;
import
'overlay.dart'
;
import
'page_storage.dart'
;
import
'status_transitions.dart'
;
class
StateRoute
extends
Route
{
class
StateRoute
extends
Route
{
StateRoute
({
this
.
onPop
});
StateRoute
({
this
.
onPop
});
...
@@ -29,7 +33,7 @@ class OverlayRoute extends Route {
...
@@ -29,7 +33,7 @@ class OverlayRoute extends Route {
List
<
WidgetBuilder
>
get
builders
=>
const
<
WidgetBuilder
>[];
List
<
WidgetBuilder
>
get
builders
=>
const
<
WidgetBuilder
>[];
List
<
OverlayEntry
>
get
overlayEntries
=>
_overlayEntries
;
List
<
OverlayEntry
>
get
overlayEntries
=>
_overlayEntries
;
final
List
<
OverlayEntry
>
_overlayEntries
=
new
List
<
OverlayEntry
>()
;
final
List
<
OverlayEntry
>
_overlayEntries
=
<
OverlayEntry
>[]
;
void
didPush
(
OverlayState
overlay
,
OverlayEntry
insertionPoint
)
{
void
didPush
(
OverlayState
overlay
,
OverlayEntry
insertionPoint
)
{
for
(
WidgetBuilder
builder
in
builders
)
{
for
(
WidgetBuilder
builder
in
builders
)
{
...
@@ -99,3 +103,128 @@ abstract class TransitionRoute extends OverlayRoute {
...
@@ -99,3 +103,128 @@ abstract class TransitionRoute extends OverlayRoute {
String
get
debugLabel
=>
'
$runtimeType
'
;
String
get
debugLabel
=>
'
$runtimeType
'
;
String
toString
()
=>
'
$runtimeType
(performance:
$_performance
)'
;
String
toString
()
=>
'
$runtimeType
(performance:
$_performance
)'
;
}
}
class
_ModalScope
extends
StatusTransitionComponent
{
_ModalScope
({
Key
key
,
this
.
subtreeKey
,
this
.
storageBucket
,
PerformanceView
performance
,
this
.
route
})
:
super
(
key:
key
,
performance:
performance
);
final
GlobalKey
subtreeKey
;
final
PageStorageBucket
storageBucket
;
final
ModalRoute
route
;
Widget
build
(
BuildContext
context
)
{
Widget
contents
=
new
PageStorage
(
key:
subtreeKey
,
bucket:
storageBucket
,
child:
route
.
buildPage
(
context
)
);
if
(
route
.
offstage
)
{
contents
=
new
OffStage
(
child:
contents
);
}
else
{
contents
=
new
Focus
(
key:
new
GlobalObjectKey
(
route
),
child:
new
IgnorePointer
(
ignoring:
performance
.
status
==
PerformanceStatus
.
reverse
,
child:
route
.
buildTransition
(
context
,
performance
,
contents
)
)
);
}
ModalPosition
position
=
route
.
position
;
if
(
position
==
null
)
return
contents
;
return
new
Positioned
(
top:
position
.
top
,
right:
position
.
right
,
bottom:
position
.
bottom
,
left:
position
.
left
,
child:
contents
);
}
}
class
ModalPosition
{
const
ModalPosition
({
this
.
top
,
this
.
right
,
this
.
bottom
,
this
.
left
});
final
double
top
;
final
double
right
;
final
double
bottom
;
final
double
left
;
}
abstract
class
ModalRoute
extends
TransitionRoute
{
ModalRoute
({
Completer
completer
,
this
.
settings
:
const
NamedRouteSettings
()
})
:
super
(
completer:
completer
);
final
NamedRouteSettings
settings
;
// The API for subclasses to override - used by _ModalScope
ModalPosition
get
position
=>
null
;
Widget
buildPage
(
BuildContext
context
);
Widget
buildTransition
(
BuildContext
context
,
PerformanceView
performance
,
Widget
child
)
{
return
child
;
}
// The API for subclasses to override - used by this class
Color
get
barrierColor
=>
kTransparent
;
// The API for _ModalScope and HeroController
bool
get
offstage
=>
_offstage
;
bool
_offstage
=
false
;
void
set
offstage
(
bool
value
)
{
if
(
_offstage
==
value
)
return
;
_offstage
=
value
;
_scopeKey
.
currentState
?.
setState
(()
{
// _offstage is the value we're setting, but since there might not be a
// state, we set it outside of this callback (which will only be called if
// there's a state currently built).
// _scopeKey is the key for the _ModalScope built in _buildModalScope().
// When we mark that state dirty, it'll rebuild itself, and use our
// offstage (via their config.route.offstage) when building.
});
}
BuildContext
get
subtreeContext
=>
_subtreeKey
.
currentContext
;
// Internals
final
GlobalKey
<
StatusTransitionState
>
_scopeKey
=
new
GlobalKey
<
StatusTransitionState
>();
final
GlobalKey
_subtreeKey
=
new
GlobalKey
();
final
PageStorageBucket
_storageBucket
=
new
PageStorageBucket
();
Widget
_buildModalBarrier
(
BuildContext
context
)
{
return
new
AnimatedModalBarrier
(
color:
new
AnimatedColorValue
(
kTransparent
,
end:
barrierColor
,
curve:
Curves
.
ease
),
performance:
performance
,
dismissable:
false
);
}
Widget
_buildModalScope
(
BuildContext
context
)
{
return
new
_ModalScope
(
key:
_scopeKey
,
subtreeKey:
_subtreeKey
,
storageBucket:
_storageBucket
,
performance:
performance
,
route:
this
);
}
List
<
WidgetBuilder
>
get
builders
=>
<
WidgetBuilder
>[
_buildModalBarrier
,
_buildModalScope
];
}
packages/flutter/lib/src/widgets/status_transitions.dart
View file @
d5e71f76
...
@@ -18,10 +18,10 @@ abstract class StatusTransitionComponent extends StatefulComponent {
...
@@ -18,10 +18,10 @@ abstract class StatusTransitionComponent extends StatefulComponent {
Widget
build
(
BuildContext
context
);
Widget
build
(
BuildContext
context
);
_StatusTransitionState
createState
()
=>
new
_
StatusTransitionState
();
StatusTransitionState
createState
()
=>
new
StatusTransitionState
();
}
}
class
_
StatusTransitionState
extends
State
<
StatusTransitionComponent
>
{
class
StatusTransitionState
extends
State
<
StatusTransitionComponent
>
{
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
config
.
performance
.
addStatusListener
(
_performanceStatusChanged
);
config
.
performance
.
addStatusListener
(
_performanceStatusChanged
);
...
...
packages/flutter/lib/widgets.dart
View file @
d5e71f76
...
@@ -27,7 +27,6 @@ export 'src/widgets/modal_barrier.dart';
...
@@ -27,7 +27,6 @@ export 'src/widgets/modal_barrier.dart';
export
'src/widgets/navigator.dart'
;
export
'src/widgets/navigator.dart'
;
export
'src/widgets/overlay.dart'
;
export
'src/widgets/overlay.dart'
;
export
'src/widgets/page_storage.dart'
;
export
'src/widgets/page_storage.dart'
;
export
'src/widgets/page.dart'
;
export
'src/widgets/placeholder.dart'
;
export
'src/widgets/placeholder.dart'
;
export
'src/widgets/routes.dart'
;
export
'src/widgets/routes.dart'
;
export
'src/widgets/scrollable.dart'
;
export
'src/widgets/scrollable.dart'
;
...
...
packages/unit/test/widget/bottom_sheet_test.dart
View file @
d5e71f76
...
@@ -37,8 +37,8 @@ void main() {
...
@@ -37,8 +37,8 @@ void main() {
// Tap on the the bottom sheet itself to dismiss it
// Tap on the the bottom sheet itself to dismiss it
tester
.
tap
(
tester
.
findText
(
'BottomSheet'
));
tester
.
tap
(
tester
.
findText
(
'BottomSheet'
));
tester
.
pump
();
// bottom sheet dismiss animation starts
tester
.
pump
();
// bottom sheet dismiss animation starts
tester
.
pump
(
new
Duration
(
seconds:
1
));
//
animation done
tester
.
pump
(
new
Duration
(
seconds:
1
));
//
last frame of animation (sheet is entirely off-screen, but still present)
tester
.
pump
(
new
Duration
(
seconds:
1
));
//
rebuild frame
tester
.
pump
(
new
Duration
(
seconds:
1
));
//
frame after the animation (sheet has been removed)
expect
(
showBottomSheetThenCalled
,
isTrue
);
expect
(
showBottomSheetThenCalled
,
isTrue
);
expect
(
tester
.
findText
(
'BottomSheet'
),
isNull
);
expect
(
tester
.
findText
(
'BottomSheet'
),
isNull
);
...
...
packages/unit/test/widget/remember_scroll_position_test.dart
View file @
d5e71f76
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// found in the LICENSE file.
import
'package:flutter/animation.dart'
;
import
'package:flutter/animation.dart'
;
import
'package:flutter/
widgets
.dart'
;
import
'package:flutter/
material
.dart'
;
import
'package:test/test.dart'
;
import
'package:test/test.dart'
;
import
'widget_tester.dart'
;
import
'widget_tester.dart'
;
...
@@ -36,9 +36,9 @@ void main() {
...
@@ -36,9 +36,9 @@ void main() {
key:
navigatorKey
,
key:
navigatorKey
,
onGenerateRoute:
(
NamedRouteSettings
settings
)
{
onGenerateRoute:
(
NamedRouteSettings
settings
)
{
if
(
settings
.
name
==
'/'
)
if
(
settings
.
name
==
'/'
)
return
new
PageRoute
(
builder:
(
_
)
=>
new
Container
(
child:
new
ThePositiveNumbers
()));
return
new
Material
PageRoute
(
builder:
(
_
)
=>
new
Container
(
child:
new
ThePositiveNumbers
()));
else
if
(
settings
.
name
==
'/second'
)
else
if
(
settings
.
name
==
'/second'
)
return
new
PageRoute
(
builder:
(
_
)
=>
new
Container
(
child:
new
ThePositiveNumbers
()));
return
new
Material
PageRoute
(
builder:
(
_
)
=>
new
Container
(
child:
new
ThePositiveNumbers
()));
return
null
;
return
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