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

时间:2016-09-13 09:11:12

标签: javascript reactjs react-native react-native-android

下面我介绍我的应用的导航方案:

单击汉堡图标后

菜单

  • 主页
  • 资料
  • 已保存的地址
  • 电子钱包
  • 注销

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

因此,要导航我正在使用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应用是最好的例子。

1 个答案:

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

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