下面我介绍我的应用的导航方案:
单击汉堡图标后菜单
以上屏幕均不依赖于上面列出的任何其他屏幕。
因此,要导航我正在使用navigate.replace()。但正如我已经知道的那样,如果我们使用替换,我们就无法弹出或返回。
我真正希望实现的是Gmail安卓应用的工作方式。如果您使用汉堡包菜单导航并点击Android上的后退硬件按钮,您将在退出应用程序之前返回主屏幕。在我的场景中,它直接退出应用程序。
到目前为止,我已经提供了一小部分工作:
app.android.js:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
BackAndroid,
Navigator
} from 'react-native';
import Drawer from 'react-native-drawer';
// Import icon for close button
import Icon from 'react-native-vector-icons/FontAwesome';
// Import route components
import Home from './customer/home/home';
import Profile from './customer/profile/profile';
import MyOrders from './customer/my_orders/my_orders';
import SavedAddresses from './customer/saved_addresses/saved_addresses';
import Wallet from './customer/wallet/wallet';
// Import nav menu
import Menu from './menu/menu';
/**
* navigationStyles={Navigator.NavigationBar.StylesIOS} props to Navigator.NavigationBar
* This will apply iOS styles to android as well. We can also apply android style on iOS devices
*
*/
// ////////////////////////////////////////////////////////////////////////
// Icons
// ///////////////////////////////////////////////////////////////////////
// Hamburger icon
const hamburgerIcon = <Icon name="bars" size={25} color={'#3d3d3d'} />;
// Cart icon
const cartIcon = <Icon name="shopping-cart" size={25} color={'#3d3d3d'} />;
// ////////////////////////////////////////////////////////////////////////
// Make routes like the one below to push your screen to the new component
// ///////////////////////////////////////////////////////////////////////
// Home screen
const homeScene = {
title: 'home',
component: Home,
passProps: {
name: 'home'
}
};
// Customer profile page
const profile = {
title: 'profile',
component: Profile,
passProps: {
name: 'profile'
}
};
// Customer's my order page
const myOrders = {
title: 'my orders',
component: MyOrders,
passProps: {
name: 'my orders'
}
};
// Customer's saved address page
const savedAddresses = {
title: 'saved addresses',
component: SavedAddresses,
passProps: {
name: 'saved addresses'
}
};
// Customer's saved address page
const wallet = {
title: 'wallet',
component: Wallet,
passProps: {
name: 'wallet'
}
};
const logout = {
title: 'Home',
component: Home,
passProps: {
name: 'logout'
}
};
const menu = [
homeScene,
profile,
myOrders,
savedAddresses,
wallet,
logout
];
// ////////////////////////////////////////////////////////////////////////
// Android hardware back button functionality
// ///////////////////////////////////////////////////////////////////////
let _navigator;
BackAndroid.addEventListener('hardwareBackPress', () => {
if (_navigator && _navigator.getCurrentRoutes().length > 1) {
_navigator.pop();
return true;
}
return false;
});
/**
* Class app from where the app bootstraps
*/
export default class App extends Component {
// This is where all your routes will be processed
renderScene(route, navigator) {
// Set a variable to get the route
let RouteComponent = route.component;
_navigator = navigator;
// With props return the components
return <RouteComponent navigator={navigator} {...route.passProps} />;
}
static navigationBarRouteMapper = openControlPanel => ({
LeftButton: function(route, navigator, index, navState) {
return (
<TouchableOpacity style={navBarStyle.left} onPress={() => openControlPanel()}>
<View>
{hamburgerIcon}
</View>
</TouchableOpacity>
);
},
RightButton: function(route, navigator, index, navState) {
return (
<View style={navBarStyle.right}>
{cartIcon}
<View style={navBarStyle.counter}>
<Text style={navBarStyle.counterText}>20</Text>
</View>
</View>
);
},
Title: function(route, navigator, index, navState) {
return <Text style={navBarStyle.title}>{route.title.toUpperCase()}</Text>;
}
})
closeControlPanel() {
this._drawer.close();
}
openControlPanel() {
this._drawer.open();
}
getNavigator(route) {
this.refs.navigator.replace(route);
this.closeControlPanel();
}
render() {
return (
<Drawer
ref={ (ref) => { this._drawer = ref; } }
type="overlay"
content={<Menu navigator={this.getNavigator.bind(this)} menuItems={menu} closeControlPanel={this.closeControlPanel.bind(this)} />}
tapToClose={true}
openDrawerOffset={0.2}
panCloseMask={0.2}
panOpenMask={20}
acceptPan={true}
closedDrawerOffset={-3}
styles={drawerStyle}
tweenHandler={(ratio) => ({
// This code will maintain the opacity for main
// Whilst the opacity for the mainOverlay on the screen will be faded.
main: { opacity: 1 },
mainOverlay: {
opacity: ratio / 2,
backgroundColor: 'black',
}
})}>
<Navigator
initialRoute={homeScene}
renderScene={this.renderScene}
ref="navigator"
navigationBar={
<Navigator.NavigationBar
routeMapper={App.navigationBarRouteMapper(this.openControlPanel.bind(this))}
style={navBarStyle.navBar}
/>
}
/>
</Drawer>
);
}
}
请注意,我只期待这种行为(如果用户使用菜单导航,则在退出前返回主页)。
例如,如果我导航到个人资料然后可能是保存地址,那么在点击返回时,主屏幕应该在退出之前出现。 Gmail Android应用是最好的例子。
答案 0 :(得分:0)
好的,我找到了一个解决方案,可以在更换路线时解决退出应用的问题。所以,这是我在app退出之前进入主页的方式:
BackAndroid.addEventListener('hardwareBackPress', () => {
if (_navigator && _navigator.getCurrentRoutes().length > 1) {
_navigator.pop();
return true;
}
// Check if current route is home on clicking back
// If not navigate to home else close the app
else if(_navigator && _navigator.navigationContext._currentRoute.title !== 'home') {
_navigator.replace(homeScene);
return true;
}
return false;
});
这可能不是确切的解决方案,但对我有用。