Navigation Back support and examples for Android

Summary:
public
- Intro new back action
- Add support in the two main reducers
- Use it in examples to support Android back button
- Disable NavigationCard gestures on Android

Reviewed By: hedgerwang

Differential Revision: D2914154

fb-gh-sync-id: d4dce6538e19613a2ffca21e2e3b2ecaded3d5dc
shipit-source-id: d4dce6538e19613a2ffca21e2e3b2ecaded3d5dc
This commit is contained in:
Eric Vicenti
2016-02-08 20:02:45 -08:00
committed by facebook-github-bot-5
parent 7b57b5c84a
commit 7b2b0c3c1c
13 changed files with 157 additions and 54 deletions

View File

@@ -44,11 +44,18 @@ class NavigationAnimatedExample extends React.Component {
return (
<NavigationRootContainer
reducer={NavigationBasicReducer}
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
persistenceKey="NavigationAnimatedExampleState"
renderNavigation={this._renderNavigated}
/>
);
}
handleBackAction() {
return (
this.navRootContainer &&
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
);
}
_renderNavigated(navigationState, onNavigate) {
if (!navigationState) {
return null;

View File

@@ -40,6 +40,7 @@ const NavigationBasicExample = React.createClass({
<NavigationRootContainer
reducer={NavigationBasicReducer}
persistenceKey="NavigationBasicExampleState"
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
renderNavigation={(navState, onNavigate) => {
if (!navState) { return null; }
return (
@@ -69,6 +70,14 @@ const NavigationBasicExample = React.createClass({
/>
);
},
handleBackAction: function() {
return (
this.navRootContainer &&
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
);
},
});
const styles = StyleSheet.create({

View File

@@ -135,18 +135,18 @@ function stateTypeTitleMap(pageState) {
}
}
let ExampleTabScreen = React.createClass({
render: function() {
class ExampleTabScreen extends React.Component {
render() {
return (
<NavigationAnimatedView
style={styles.tabContent}
navigationState={this.props.navigationState}
renderOverlay={this._renderHeader}
renderScene={this._renderScene}
renderOverlay={this._renderHeader.bind(this)}
renderScene={this._renderScene.bind(this)}
/>
);
},
_renderHeader: function(position, layout) {
}
_renderHeader(position, layout) {
return (
<NavigationHeader
navigationState={this.props.navigationState}
@@ -155,8 +155,8 @@ let ExampleTabScreen = React.createClass({
getTitle={state => stateTypeTitleMap(state)}
/>
);
},
_renderScene: function(child, index, position, layout) {
}
_renderScene(child, index, position, layout) {
return (
<NavigationCard
key={child.key}
@@ -187,21 +187,28 @@ let ExampleTabScreen = React.createClass({
</ScrollView>
</NavigationCard>
);
},
});
}
}
ExampleTabScreen = NavigationContainer.create(ExampleTabScreen);
const NavigationCompositionExample = React.createClass({
render: function() {
class NavigationCompositionExample extends React.Component {
render() {
return (
<NavigationRootContainer
reducer={ExampleAppReducer}
persistenceKey="NavigationCompositionExampleState"
renderNavigation={this.renderApp}
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
renderNavigation={this.renderApp.bind(this)}
/>
);
},
renderApp: function(navigationState, onNavigate) {
}
handleBackAction() {
return (
this.navRootContainer &&
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
);
}
renderApp(navigationState, onNavigate) {
if (!navigationState) {
return null;
}
@@ -217,11 +224,11 @@ const NavigationCompositionExample = React.createClass({
/>
</View>
);
},
});
}
}
let ExampleMainView = React.createClass({
render: function() {
class ExampleMainView extends React.Component {
render() {
return (
<NavigationView
navigationState={this.props.navigationState}
@@ -230,20 +237,20 @@ let ExampleMainView = React.createClass({
<ExampleTabScreen
key={tabState.key}
navigationState={tabState}
onNavigate={this._handleNavigation.bind(null, tabState.key)}
onNavigate={this._handleNavigation.bind(this, tabState.key)}
/>
)}
/>
);
},
_handleNavigation: function(tabKey, action) {
}
_handleNavigation(tabKey, action) {
if (ExampleExitAction.match(action)) {
this.props.onExampleExit();
return;
}
this.props.onNavigate(action);
},
});
}
}
ExampleMainView = NavigationContainer.create(ExampleMainView);
const styles = StyleSheet.create({

View File

@@ -25,7 +25,7 @@ var NavigationExampleRow = require('./NavigationExampleRow');
/*
* Heads up! This file is not the real navigation example- only a utility to switch between them.
*
* To learn how to use the Navigation API, take a look at the following exmample files:
* To learn how to use the Navigation API, take a look at the following example files:
*/
var EXAMPLES = {
'Tabs': require('./NavigationTabsExample'),
@@ -106,13 +106,34 @@ var NavigationExperimentalExample = React.createClass({
this.setExample('menu');
},
handleBackAction: function() {
const wasHandledByExample = (
this.exampleRef &&
this.exampleRef.handleBackAction &&
this.exampleRef.handleBackAction()
);
if (wasHandledByExample) {
return true;
}
if (this.state.example && this.state.example !== 'menu') {
this._exitInnerExample();
return true;
}
return false;
},
render: function() {
if (this.state.example === 'menu') {
return this._renderMenu();
}
if (EXAMPLES[this.state.example]) {
var Component = EXAMPLES[this.state.example];
return <Component onExampleExit={this._exitInnerExample} />;
return (
<Component
onExampleExit={this._exitInnerExample}
ref={exampleRef => { this.exampleRef = exampleRef; }}
/>
);
}
return null;
},

View File

@@ -64,12 +64,13 @@ const ExampleTabsReducer = NavigationReducer.TabsReducer({
],
});
const NavigationTabsExample = React.createClass({
render: function() {
class NavigationTabsExample extends React.Component {
render() {
return (
<NavigationRootContainer
reducer={ExampleTabsReducer}
persistenceKey="NAV_EXAMPLE_STATE_TABS"
ref={navRootContainer => { this.navRootContainer = navRootContainer; }}
renderNavigation={(navigationState) => {
if (!navigationState) { return null; }
return (
@@ -88,8 +89,14 @@ const NavigationTabsExample = React.createClass({
}}
/>
);
},
});
}
handleBackAction() {
return (
this.navRootContainer &&
this.navRootContainer.handleNavigation(NavigationRootContainer.getBackAction())
);
}
}
const styles = StyleSheet.create({
topView: {

View File

@@ -109,12 +109,21 @@ var UIExplorerApp = React.createClass({
style={styles.toolbar}
title={this.state.example.title}
/>
<Component />
<Component
ref={(example) => { this._exampleRef = example; }}
/>
</View>
);
},
_handleBackButtonPress: function() {
if (
this._exampleRef &&
this._exampleRef.handleBackAction &&
this._exampleRef.handleBackAction()
) {
return true;
}
if (this.state.example.title !== this._getUIExplorerHome().title) {
this.onSelectExample(this._getUIExplorerHome());
return true;

View File

@@ -54,6 +54,7 @@ var APIS = [
require('./IntentAndroidExample.android'),
require('./LayoutEventsExample'),
require('./LayoutExample'),
require('./NavigationExperimental/NavigationExperimentalExample'),
require('./NetInfoExample'),
require('./PanResponderExample'),
require('./PointerEventsExample'),