mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add back/forward history to navigation
R=abarth@chromium.org, abarth, hixie Review URL: https://codereview.chromium.org/1181773006.
This commit is contained in:
parent
9b74ec026c
commit
a7aa951329
@ -4,28 +4,69 @@
|
||||
|
||||
import 'package:sky/widgets/basic.dart';
|
||||
import 'package:sky/widgets/navigator.dart';
|
||||
import 'package:sky/widgets/transition.dart';
|
||||
import 'package:sky/widgets/raised_button.dart';
|
||||
|
||||
List<Route> routes = [
|
||||
new Route(
|
||||
name: 'safety',
|
||||
builder: (navigator) => new RaisedButton(
|
||||
child: new Text('PRESS FORWARD'),
|
||||
onPressed: () => navigator.pushNamedRoute('adventure')
|
||||
name: 'home',
|
||||
builder: (navigator) => new Container(
|
||||
padding: const EdgeDims.all(20.0),
|
||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)),
|
||||
child: new Block([
|
||||
new Text("You are at home"),
|
||||
new RaisedButton(
|
||||
key: 'b',
|
||||
child: new Text('GO SHOPPING'),
|
||||
onPressed: () => navigator.pushNamed('shopping')
|
||||
),
|
||||
new RaisedButton(
|
||||
key: 'a',
|
||||
child: new Text('START ADVENTURE'),
|
||||
onPressed: () => navigator.pushNamed('adventure')
|
||||
)
|
||||
])
|
||||
)
|
||||
),
|
||||
new Route(
|
||||
name: 'shopping',
|
||||
builder: (navigator) => new Container(
|
||||
padding: const EdgeDims.all(20.0),
|
||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFFBF5FFF)),
|
||||
child: new Block([
|
||||
new Text("Village Shop"),
|
||||
new RaisedButton(
|
||||
key: 'a',
|
||||
child: new Text('RETURN HOME'),
|
||||
onPressed: () => navigator.back()
|
||||
),
|
||||
new RaisedButton(
|
||||
key: 'b',
|
||||
child: new Text('GO TO DUNGEON'),
|
||||
onPressed: () => navigator.push(routes[2])
|
||||
)
|
||||
])
|
||||
)
|
||||
),
|
||||
new Route(
|
||||
name: 'adventure',
|
||||
builder: (navigator) => new RaisedButton(
|
||||
child: new Text('NO WAIT! GO BACK!'),
|
||||
onPressed: () => navigator.pushRoute(routes[0])
|
||||
builder: (navigator) => new Container(
|
||||
padding: const EdgeDims.all(20.0),
|
||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFFDC143C)),
|
||||
child: new Block([
|
||||
new Text("Monster's Lair"),
|
||||
new RaisedButton(
|
||||
child: new Text('NO WAIT! GO BACK!'),
|
||||
onPressed: () => navigator.pop()
|
||||
)
|
||||
])
|
||||
)
|
||||
)
|
||||
];
|
||||
|
||||
class NavigationExampleApp extends App {
|
||||
UINode build() {
|
||||
return new Navigator(routes: routes);
|
||||
Widget build() {
|
||||
return new Flex([new Navigator(routes: routes)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,51 +7,79 @@ import 'basic.dart';
|
||||
typedef Widget Builder(Navigator navigator);
|
||||
|
||||
abstract class RouteBase {
|
||||
RouteBase({this.name});
|
||||
RouteBase({ this.name });
|
||||
final String name;
|
||||
Widget build(Navigator navigator);
|
||||
}
|
||||
|
||||
class Route extends RouteBase {
|
||||
Route({String name, this.builder}) : super(name: name);
|
||||
Route({ String name, this.builder }) : super(name: name);
|
||||
final Builder builder;
|
||||
Widget build(Navigator navigator) => builder(navigator);
|
||||
}
|
||||
|
||||
class Navigator extends Component {
|
||||
Navigator({Object key, this.currentRoute, this.routes})
|
||||
: super(key: key, stateful: true);
|
||||
|
||||
RouteBase currentRoute;
|
||||
List<RouteBase> routes;
|
||||
|
||||
void syncFields(Navigator source) {
|
||||
currentRoute = source.currentRoute;
|
||||
routes = source.routes;
|
||||
}
|
||||
|
||||
void pushNamedRoute(String name) {
|
||||
assert(routes != null);
|
||||
for (RouteBase route in routes) {
|
||||
if (route.name == name) {
|
||||
setState(() {
|
||||
currentRoute = route;
|
||||
});
|
||||
return;
|
||||
Navigator({ Object key, RouteBase defaultRoute, List<RouteBase> routes })
|
||||
: super(key: key, stateful: true) {
|
||||
if (routes != null) {
|
||||
if (defaultRoute == null)
|
||||
defaultRoute = routes[0];
|
||||
for (Route route in routes) {
|
||||
if (route.name != null)
|
||||
namedRoutes[route.name] = route;
|
||||
}
|
||||
}
|
||||
assert(false); // route not found
|
||||
assert(defaultRoute != null);
|
||||
_history.add(defaultRoute);
|
||||
}
|
||||
|
||||
void pushRoute(RouteBase route) {
|
||||
List<RouteBase> _history = new List<RouteBase>();
|
||||
int _historyIndex = 0;
|
||||
Map<String, RouteBase> namedRoutes = new Map<String, RouteBase>();
|
||||
|
||||
void syncFields(Navigator source) {
|
||||
namedRoutes = source.namedRoutes;
|
||||
}
|
||||
|
||||
void pushNamed(String name) {
|
||||
Route route = namedRoutes[name];
|
||||
assert(route != null);
|
||||
push(route);
|
||||
}
|
||||
|
||||
void push(RouteBase route) {
|
||||
setState(() {
|
||||
currentRoute = route;
|
||||
// Discard future history
|
||||
_history.removeRange(_historyIndex + 1, _history.length);
|
||||
_historyIndex = _history.length;
|
||||
_history.add(route);
|
||||
});
|
||||
}
|
||||
|
||||
void pop() {
|
||||
setState(() {
|
||||
if (_historyIndex > 0) {
|
||||
_history.removeLast();
|
||||
_historyIndex--;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void back() {
|
||||
setState(() {
|
||||
if (_historyIndex > 0)
|
||||
_historyIndex--;
|
||||
});
|
||||
}
|
||||
|
||||
void forward() {
|
||||
setState(() {
|
||||
_historyIndex++;
|
||||
assert(_historyIndex < _history.length);
|
||||
});
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
Route route = currentRoute == null ? routes[0] : currentRoute;
|
||||
assert(route != null);
|
||||
return route.build(this);
|
||||
return _history[_historyIndex].build(this);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user