mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Refactor Navigator to put state in separate class, initial back button plumbing
R=abarth@chromium.org, abarth Review URL: https://codereview.chromium.org/1195493002.
This commit is contained in:
parent
d6ddfcaf99
commit
bc8ab63efd
@ -14,19 +14,24 @@ class StocksApp extends App {
|
||||
|
||||
StocksApp({ RenderView renderViewOverride }) : super(renderViewOverride: renderViewOverride);
|
||||
|
||||
NavigationState _navState = new NavigationState([
|
||||
new Route(name: '/', builder: (navigator) => new StockHome(navigator)),
|
||||
new Route(name: '/settings', builder: (navigator) => new StockSettings(navigator)),
|
||||
]);
|
||||
|
||||
void onBack() {
|
||||
if (_navState.hasPrevious()) {
|
||||
setState(() {
|
||||
_navState.pop();
|
||||
});
|
||||
return;
|
||||
}
|
||||
print ("Should exit app here");
|
||||
// TODO(jackson): Need a way to invoke default back behavior here
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return new Navigator(
|
||||
routes: [
|
||||
new Route(
|
||||
name: '/',
|
||||
builder: (navigator) => new StockHome(navigator)
|
||||
),
|
||||
new Route(
|
||||
name: '/settings',
|
||||
builder: (navigator) => new StockSettings(navigator)
|
||||
),
|
||||
]
|
||||
);
|
||||
return new Navigator(_navState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -65,8 +65,10 @@ List<Route> routes = [
|
||||
];
|
||||
|
||||
class NavigationExampleApp extends App {
|
||||
NavigationState _navState = new NavigationState(routes);
|
||||
|
||||
Widget build() {
|
||||
return new Flex([new Navigator(routes: routes)]);
|
||||
return new Flex([new Navigator(_navState)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +50,8 @@ class AppView {
|
||||
|
||||
Function onFrame;
|
||||
|
||||
List<sky.EventListener> eventListeners = new List<sky.EventListener>();
|
||||
|
||||
RenderBox get root => _renderView.child;
|
||||
void set root(RenderBox value) {
|
||||
_renderView.child = value;
|
||||
@ -68,6 +70,10 @@ class AppView {
|
||||
HitTestResult result = new HitTestResult();
|
||||
_renderView.hitTest(result, position: new Point(event.x, event.y));
|
||||
dispatchEvent(event, result);
|
||||
} else {
|
||||
for (sky.EventListener listener in eventListeners) {
|
||||
listener(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,28 +18,23 @@ class Route extends RouteBase {
|
||||
Widget build(Navigator navigator) => builder(navigator);
|
||||
}
|
||||
|
||||
class Navigator extends Component {
|
||||
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;
|
||||
}
|
||||
class NavigationState {
|
||||
|
||||
NavigationState(List<Route> routes) {
|
||||
for (Route route in routes) {
|
||||
if (route.name != null)
|
||||
namedRoutes[route.name] = route;
|
||||
}
|
||||
assert(defaultRoute != null);
|
||||
_history.add(defaultRoute);
|
||||
history.add(routes[0]);
|
||||
}
|
||||
|
||||
List<RouteBase> _history = new List<RouteBase>();
|
||||
int _historyIndex = 0;
|
||||
List<RouteBase> history = new List<RouteBase>();
|
||||
int historyIndex = 0;
|
||||
Map<String, RouteBase> namedRoutes = new Map<String, RouteBase>();
|
||||
|
||||
void syncFields(Navigator source) {
|
||||
namedRoutes = source.namedRoutes;
|
||||
}
|
||||
RouteBase get currentRoute => history[historyIndex];
|
||||
bool hasPrevious() => historyIndex > 0;
|
||||
bool hasNext() => history.length > historyIndex + 1;
|
||||
|
||||
void pushNamed(String name) {
|
||||
Route route = namedRoutes[name];
|
||||
@ -48,38 +43,67 @@ class Navigator extends Component {
|
||||
}
|
||||
|
||||
void push(RouteBase route) {
|
||||
// Discard future history
|
||||
history.removeRange(historyIndex + 1, history.length);
|
||||
historyIndex = history.length;
|
||||
history.add(route);
|
||||
}
|
||||
|
||||
void pop() {
|
||||
if (historyIndex > 0) {
|
||||
history.removeLast();
|
||||
historyIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
void back() {
|
||||
if (historyIndex > 0)
|
||||
historyIndex--;
|
||||
}
|
||||
|
||||
void forward() {
|
||||
historyIndex++;
|
||||
assert(historyIndex < history.length);
|
||||
}
|
||||
}
|
||||
|
||||
class Navigator extends Component {
|
||||
|
||||
Navigator(this.state, { String key }) : super(key: key);
|
||||
|
||||
NavigationState state;
|
||||
|
||||
void pushNamed(String name) {
|
||||
setState(() {
|
||||
// Discard future history
|
||||
_history.removeRange(_historyIndex + 1, _history.length);
|
||||
_historyIndex = _history.length;
|
||||
_history.add(route);
|
||||
state.pushNamed(name);
|
||||
});
|
||||
}
|
||||
|
||||
void push(RouteBase route) {
|
||||
setState(() {
|
||||
state.push(route);
|
||||
});
|
||||
}
|
||||
|
||||
void pop() {
|
||||
setState(() {
|
||||
if (_historyIndex > 0) {
|
||||
_history.removeLast();
|
||||
_historyIndex--;
|
||||
}
|
||||
state.pop();
|
||||
});
|
||||
}
|
||||
|
||||
void back() {
|
||||
setState(() {
|
||||
if (_historyIndex > 0)
|
||||
_historyIndex--;
|
||||
state.back();
|
||||
});
|
||||
}
|
||||
|
||||
void forward() {
|
||||
setState(() {
|
||||
_historyIndex++;
|
||||
assert(_historyIndex < _history.length);
|
||||
state.forward();
|
||||
});
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return _history[_historyIndex].build(this);
|
||||
return state.currentRoute.build(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -799,10 +799,17 @@ abstract class App extends AbstractWidgetRoot {
|
||||
if (root.parent == null) {
|
||||
// we haven't attached it yet
|
||||
WidgetAppView._appView.root = root;
|
||||
WidgetAppView._appView.eventListeners.add((event) {
|
||||
if (event.type == "back")
|
||||
onBack();
|
||||
});
|
||||
}
|
||||
assert(root.parent is RenderView);
|
||||
}
|
||||
|
||||
// Override this to handle back button behavior in your app
|
||||
void onBack() { }
|
||||
|
||||
}
|
||||
|
||||
typedef Widget Builder();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user