单击后退按钮,如果浏览汉堡菜单,则转到主页

On clicking back button, go to home page if navigating through hamburger menu

所以下面我展示了我的应用程序的导航场景:

点击汉堡图标后的菜单

None 以上屏幕依赖于上面列出的任何其他屏幕。

因此,我使用 navigate.replace() 进行导航。但是我已经知道,如果我们使用 replace,我们就不能弹出或返回。

我真正想要实现的是 Gmail android 应用程序的工作方式。如果您使用汉堡菜单导航并点击 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 应用就是最好的例子。

好的,我找到了一个解决方案来解决在替换路由时单击返回退出应用程序的问题。所以,这就是我在应用程序退出前进入主页的方式:

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;
});

这可能不是确切的解决方案,但对我有用。