RN BackHandler ——Android回退键自定义

【RN中自定义Android回退行为】

在React-Native项目中为Android的返回键定义自定义的行为,BackAndroid控件已被禁用,所以使用BackHandler控件进行。

简单使用

BackHandler API 用于监听设备上的后退按钮事件,可以调用你自己的函数来处理后退行为。此 API 仅能在 Android 上使用。一般说来,我们为android键添加自定义的响应函数(例如,返回的时候弹出一个警示框告诉你要返回),只要在类中的注册对回退键的监听即可,如下面的代码段所示:

class BaseComponent extends Component<> {
    //……
    componentDidMount() {
        /**
         * addEventListener 返回一个 NativeEventSubscription ,可以使用一个参数引用它,然后使用remove去除
         * this.back = BackHandler.addEventListener("hardwareBackPress", this.backAction);
         * */
        BackHandler.addEventListener("hardwareBackPress", this.backAction);
    }
    componentWillUnmount() {
        /* this.back.remove(); */
        BackHandler.removeEventListener("hardwareBackPress", this.backAction);
    }
    //……
}

在函数式组件(即无状态组件中,Hooks)中,定义的代码如下所示:

const App = () => {
    //……
    useEffect(() => {
        BackHandler.addEventListener("hardwareBackPress", backAction);
        return () => {
            BackHandler.removeEventListener("hardwareBackPress", backAction);
        }}, []);
  return (
    <View></View>
  );
};

然后,只要在组件重写backAction方法即可完成自定义的android回退事件响应。

继承

我们在写代码时,不能每一个界面都注册和销毁BackHandler的Listener,所以一般写在BaseComponent中,然后我们实现的界面继承这个Component。
当我们在子控件中重写backAction时,发现它还是使用默认的返回事件,这是为什么呢?

  1. 原因1:阅读第一节普通调用可以发现:回退键的响应是在componentDidMount中进行的,所以我们必须重写这个注册了监听的生命周期函数并且让它调用super.componentDidMount() 这样,在父组件中注册的监听才能注册在子界面中。同时,别忘了注销监听。
  2. 原因2:backAciton的事件的监听是通过冒泡的机制进行捕获,返回true时会阻止事件冒泡传递,因而不会执行默认的后退行为,返回false时会使事件继续传递,触发其他注册的监听函数,或是系统默认的后退行为。
  3. 原因3:如果你打开的界面是一个Modal窗口,那么 BackHandler 不会触发事件。

主界面返回

App是存在返回栈的,所以它在执行的时候不能无限制的执行。
//TODO: 当我们无限制的执行回退会产生什么情况?
在一般的APP中,当我们位于起始界面的时候,点击一下就会弹出“再按一次回退键退出APP”,再快速按一下就会退出app,这是如何操作的呢,如下代码段:

backAction = () => {
        const routers = this.props.navigation.getCurrentRoutes();
        if (routers.length > 1) {
            this.props.navigation.goback();
            //this.props.navigation.pop(); 与上一行等价
            return true;
        }else{
            let time = new Date();
            this.lastBackPressed = this.thisBackPressed;
            this.thisBackPressed = time.getTime();if (this.lastBackPressed && this.lastBackPressed + 2000 >= this.thisBackPressed) {
                //最近2秒内按过back键,可以退出应用。
                 return false;
            }
            ToastAndroid.show('再按一次退出应用', ToastAndroid.SHORT);
            return true;
        }
    };

其中,使用getCurrentRoutes().length 只是判断是否是主界面的一种情况,只要你可以判断当前界面到底是不是主界面,任何方法都可以。

参考文档

react-native docs: https://reactnative.cn/docs/backhandler
react native Android返回键监听BackHandler: https://www.cnblogs.com/yulian/p/8676577.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值