提交 bc8ab63e 编写于 作者: C Collin Jackson

Refactor Navigator to put state in separate class, initial back button plumbing

R=abarth@chromium.org, abarth

Review URL: https://codereview.chromium.org/1195493002.
上级 d6ddfcaf
......@@ -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];
......@@ -47,39 +42,68 @@ class Navigator extends Component {
push(route);
}
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(() {
state.pushNamed(name);
});
}
void push(RouteBase route) {
setState(() {
// Discard future history
_history.removeRange(_historyIndex + 1, _history.length);
_historyIndex = _history.length;
_history.add(route);
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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册