Android上React Native Navigator中的返回按钮

Android上React Native Navigator中的返回按钮,android,react-native,Android,React Native,我在Android react本机应用程序中有一个导航器 我正在使用navigator.push()导航到其他页面。“后退”按钮会弹出导航器并返回一页,这似乎很自然,但实际情况并非如此(它会退出应用程序) react nativeNavigator是否真的没有后退按钮支持,我是否需要自己将其插入后退Android?是的,您必须自己处理后退按钮。我认为这主要是因为你可能想用后退按钮做不同的事情,而不是仅仅在堆栈中向后移动。我不知道将来是否有计划加入后退按钮功能。除了上面的答案,处理代码应该是这样的

我在Android react本机应用程序中有一个
导航器

我正在使用
navigator.push()
导航到其他页面。“后退”按钮会弹出导航器并返回一页,这似乎很自然,但实际情况并非如此(它会退出应用程序)


react native
Navigator
是否真的没有后退按钮支持,我是否需要自己将其插入
后退Android

是的,您必须自己处理后退按钮。我认为这主要是因为你可能想用后退按钮做不同的事情,而不是仅仅在堆栈中向后移动。我不知道将来是否有计划加入后退按钮功能。

除了上面的答案,处理代码应该是这样的

var navigator; 

React.BackAndroid.addEventListener('hardwareBackPress', () => {
    if (navigator && navigator.getCurrentRoutes().length > 1) {
        navigator.pop();
        return true;
    }
    return false;
});
在渲染代码中:

<Navigator ref={(nav) => { navigator = nav; }} />
{navigator=nav;}}/>

不确定API何时更改,但从react-native 0.31(也可能是早期版本)起,BackAndroid是一个必须从react-native导入的组件:

从“react native”导入{…,BackAndroid}

还要确保删除componentWillUnmount上的侦听器:

componentWillUnmount(){
    BackAndroid.removeEventListener('hardwareBackPress', () => {
        if (this.navigator && this.navigator.getCurrentRoutes().length > 1) {
            this.navigator.pop();
            return true;
        }
        return false;
    });
}
*更新:在react native 0.44中,此模块已重命名为
BackHandler
<代码>导航器
也已被正式弃用,但仍可以在此处找到:


为了使用我的知识和以前的答案清理代码,下面是代码的外观:

从'react native'导入{…,Navigator,BackAndroid};
componentDidMount(){
BackAndroid.addEventListener('hardwareBackPress',this.handleBack);
}
组件将卸载(){
//忘记删除侦听器将导致pop执行多次
BackAndroid.removeEventListener('hardwareBackPress',this.handleBack);
}
车把{
if(this.navigator&&this.navigator.getCurrentRoutes().length>1){
this.navigator.pop();
返回true;//避免关闭应用程序
}
返回false;//关闭应用程序
}

别忘了绑定[这个]

正确答案应该是:

export default class MyPage extends Component {
  constructor(props) {
    super(props)
    this.navigator = null;

    this.handleBack = (() => {
      if (this.navigator && this.navigator.getCurrentRoutes().length > 1){
        this.navigator.pop();
        return true; //avoid closing the app
      }

      return false; //close the app
    }).bind(this) //don't forget bind this, you will remember anyway.
  }

  componentDidMount() {
    BackAndroid.addEventListener('hardwareBackPress', this.handleBack);
  }

  componentWillUnmount() {
    BackAndroid.removeEventListener('hardwareBackPress', this.handleBack);
  }

  render() {
    return (
      <Navigator
        ref={navigator => {this.navigator = navigator}}
  ...
导出默认类MyPage扩展组件{
建造师(道具){
超级(道具)
this.navigator=null;
这个.把手=(()=>{
if(this.navigator&&this.navigator.getCurrentRoutes().length>1){
this.navigator.pop();
返回true;//避免关闭应用程序
}
返回false;//关闭应用程序
}).bind(这个)//别忘了绑定这个,反正你会记得的。
}
componentDidMount(){
BackAndroid.addEventListener('hardwareBackPress',this.handleBack);
}
组件将卸载(){
BackAndroid.removeEventListener('hardwareBackPress',this.handleBack);
}
render(){
返回(
{this.navigator=navigator}
...

我创建了一个GitHub repo,它将为您提供一个如何处理Android后退按钮的示例项目

您可以在以下位置克隆/下载回购协议:

但这里有一些关于如何处理android后退按钮的示例代码

以下代码用于用户启动我的应用程序时的初始屏幕。按下此处的“后退”按钮将显示一个警报,提示用户是否要离开应用程序

import React, {Component} from 'react';
import {View,Text,Button,BackHandler,Alert} from 'react-native';
import {NavigationActions} from 'react-navigation';

export default class InitScreen extends Component {
    _focusDoneSubscribe;//declaring variable that will be listener for the back button when in focus 
    _blurGoingSubscribe;//declaring variable that will be listener for the back button when blur 

    //the following will remove the navigation bar at the top
    static navigationOptions = {
        header: null,
        title: 'Welcome',
    };

    constructor(props)
    {
        super(props);
        this._focusDoneSubscribe = props.navigation.addListener('didFocus', payload =>
            BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
        );//this assigns the listener
    }
    //functions to handle back button events
    componentDidMount()
    {
        this._blurGoingSubscribe = this.props.navigation.addListener('willBlur', payload =>
                BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
            );
    }

    onBackButtonPressAndroid = () => {
        Alert.alert(
            'Exiting App',
            'Confirm quitting the app?',
            [
                {text: 'CANCEL', style: 'cancel'},
                {text: 'STOP ASKING AND QUIT', onPress: () => BackHandler.exitApp()}
            ],
            {cancelable: false},
        );
        return true;
    };

    componentWillUnmount()
    {
        this._focusDoneSubscribe && this._focusDoneSubscribe.remove();
        this._blurGoingSubscribe && this._blurGoingSubscribe.remove();
    }
    //actual render
    render(){
        const { navigate } = this.props.navigation;
        return (
            <View style={{alignItems: 'center'}}>
                <View style={{height: 100,justifyContent: 'center',alignItems: 'center'}}>
                    <Text style={{fontSize: 20}}>Navigation BackHandler Tutorial</Text>
                    <Text style={{fontSize: 20}}>Initial Screen</Text>
                </View>
                <View style={{flexDirection: 'column', justifyContent: 'space-between', height: 100}}>
                    <Button
                    title="SCREEN ONE"
                    onPress={() => {this.props.navigation.push('One')}}
                    />
                    <Button
                    title="SCREEN TWO"
                    onPress={() => {this.props.navigation.push('Two')}}
                    />
                </View>
            </View>
        );
    }
}
import React,{Component}来自'React';
从“react native”导入{View、Text、Button、BackHandler、Alert};
从“react navigation”导入{NavigationActions};
导出默认类InitScreen扩展组件{
_focusDoneSubscribe;//声明变量,当处于焦点时,该变量将作为后退按钮的侦听器
_blurGoingSubscribe;//声明在模糊时将作为后退按钮的侦听器的变量
//下面将删除顶部的导航栏
静态导航选项={
标题:null,
标题:"欢迎",,
};
建造师(道具)
{
超级(道具);
这是._focusDoneSubscribe=props.navigation.addListener('didFocus',payload=>
BackHandler.addEventListener('hardwareBackPress',this.onBackButtonPressAndroid)
);//这将分配侦听器
}
//处理后退按钮事件的函数
componentDidMount()
{
this.\u blurGoingSubscribe=this.props.navigation.addListener('willBlur',payload=>
BackHandler.removeEventListener('hardwareBackPress',this.onBackButtonPressAndroid)
);
}
onBackButtonPressAndroid=()=>{
警惕,警惕(
“正在退出应用程序”,
“确认退出应用程序吗?”,
[
{文本:“取消”,样式:“取消”},
{text:'停止询问并退出',onPress:()=>BackHandler.exitApp()}
],
{可取消:false},
);
返回true;
};
组件将卸载()
{
this._focusDoneSubscribe&&this._focusDoneSubscribe.remove();
this.\u blurGoingSubscribe&&this.\u blurGoingSubscribe.remove();
}
//实际渲染
render(){
const{navigate}=this.props.navigation;
返回(
导航后台处理程序教程
初始屏幕
{this.props.navigation.push('One')}
/>
{this.props.navigation.push('Two')}
/>
);
}
}
以下代码是一个屏幕,当用户按下后退按钮时,它会返回上一个屏幕:

import React, {Component} from 'react';
import {View,Text,Button,BackHandler} from 'react-native';//declaring variable that will be listener for the back button when in focus 
import {NavigationActions} from 'react-navigation';//declaring variable that will be listener for the back button when blur 

export default class ScreenOne extends Component {
    _focusDoneSubscribe;
    _blurGoingSubscribe;

    //the following will remove the navigation bar at the top
    static navigationOptions = {
        header: null,
        title: 'ONE',
    };

    constructor(props)
    {
        super(props);
        this._focusDoneSubscribe = props.navigation.addListener('didFocus', payload =>
            BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
        );//this assigns the listener
    }
    //functions to handle back button events
    componentDidMount()
    {
        this._blurGoingSubscribe = this.props.navigation.addListener('willBlur', payload =>
                BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
            );
    }

    onBackButtonPressAndroid = () => {
        this.props.navigation.goBack();
        return true;
    };

    componentWillUnmount()
    {
        this._focusDoneSubscribe && this._focusDoneSubscribe.remove();
        this._blurGoingSubscribe && this._blurGoingSubscribe.remove();
    }
    //actual render
    render(){
        const { navigate } = this.props.navigation;
        return (
            <View style={{alignItems: 'center'}}>
                <View style={{height: 100,justifyContent: 'center',alignItems: 'center'}}>
                    <Text style={{fontSize: 20}}>Navigation BackHandler Tutorial</Text>
                    <Text style={{fontSize: 20}}>SCREEN ONE</Text>
                </View>
            </View>
        );
    }
}
import React,{Component}来自'React';
从“react native”导入{View,Text,Button,BackHandler};//声明变量,该变量在焦点中时将作为back按钮的侦听器
从“react navigation”导入{NavigationActions};//声明在模糊时将作为back按钮侦听器的变量
导出默认类ScreenOne扩展组件{
_focusDoneSubscribe;
_模糊订阅;
//以下将是r
import React, {Component} from 'react';
import {View,Text,Button,BackHandler} from 'react-native';//declaring variable that will be listener for the back button when in focus 
import {NavigationActions} from 'react-navigation';//declaring variable that will be listener for the back button when blur 

export default class ScreenOne extends Component {
    _focusDoneSubscribe;
    _blurGoingSubscribe;

    //the following will remove the navigation bar at the top
    static navigationOptions = {
        header: null,
        title: 'ONE',
    };

    constructor(props)
    {
        super(props);
        this._focusDoneSubscribe = props.navigation.addListener('didFocus', payload =>
            BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
        );//this assigns the listener
    }
    //functions to handle back button events
    componentDidMount()
    {
        this._blurGoingSubscribe = this.props.navigation.addListener('willBlur', payload =>
                BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
            );
    }

    onBackButtonPressAndroid = () => {
        this.props.navigation.goBack();
        return true;
    };

    componentWillUnmount()
    {
        this._focusDoneSubscribe && this._focusDoneSubscribe.remove();
        this._blurGoingSubscribe && this._blurGoingSubscribe.remove();
    }
    //actual render
    render(){
        const { navigate } = this.props.navigation;
        return (
            <View style={{alignItems: 'center'}}>
                <View style={{height: 100,justifyContent: 'center',alignItems: 'center'}}>
                    <Text style={{fontSize: 20}}>Navigation BackHandler Tutorial</Text>
                    <Text style={{fontSize: 20}}>SCREEN ONE</Text>
                </View>
            </View>
        );
    }
}