微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React Native之hardwareBackPress

1  hardwareBackPress

我们用hardwareBackPress来监听手机物理返回键

 

 

 

 

2 js那边常用写法

BackHandler.addEventListener('hardwareBackPress',this._back);

 

 

 

3  我们看下Android源代码分析是怎么触发到这里来的

1) ReactActivity.java里面的部分代码如下

  @Override
  public void onBackpressed() {
    if (!mDelegate.onBackpressed()) {
      super.onBackpressed();
    }
  }

2 ) 进入onBackpressed()函数看看,在ReactActivityDelegate.java文件里面

  public boolean onBackpressed() {
    if (getReactNativeHost().hasInstance()) {
      getReactNativeHost().getReactInstanceManager().onBackpressed();
      return true;
    }
    return false;
  }

3)再次点击onBackpressed函数进去看下

  public void onBackpressed() {
    UiThreadUtil.assertOnUiThread();
    ReactContext reactContext = mCurrentReactContext;
    if (reactContext == null) {
      // Invoke without round trip to JS.
      FLog.w(ReactConstants.TAG,"Instance detached from instance manager");
      invokeDefaultOnBackpressed();
    } else {
      DeviceEventManagerModule deviceEventManagerModule =
        reactContext.getNativeModule(DeviceEventManagerModule.class);
      deviceEventManagerModule.emitHardwareBackpressed();
    }
  }

4) 进到emitHardwareBackpressed函数里面看下

  /**
   * Sends an event to the JS instance that the hardware back has been pressed.
   */
  public void emitHardwareBackpressed() {
    getReactApplicationContext()
        .getJSModule(RCTdeviceeventemitter.class)
        .emit("hardwareBackPress",null);
  }

这里发现了Android原生向js发送了消息,所以我们监听hardwareBackPress就有反映

 

 

 

 

 

 

4 测试代码如下

App.js文件如下

import React from 'react';
import { View,Text,Button,NativeModules,BackHandler} from 'react-native';
import { createStackNavigator } from 'react-navigation';

var toast = NativeModules.MyToast;
class HomeScreen extends React.Component {


   constructor(props) {
	super(props);
	console.log("HomeScreen constructor start");
    }

    static navigationoptions = {
        title : 'HomeScreen',}

	
    componentDidMount = () => {
        this.didFocusListener = this.props.navigation.addListener(
		'didFocus',(obj) => {
			console.log("HomeScreen didFocus start");
			BackHandler.addEventListener('hardwareBackPress',this._back);
			
		}
	);
	this.didBlurListener = this.props.navigation.addListener(
		'didBlur',(obj) => {console.log('HomeScreen didBlur start')}
		);
                console.log("HomeScreen componentDidMount start")
    }

    componentwillUnmount() {
		console.log("HomeScreen componentwillUnmount start")
		this.didFocusListener.remove();
		this.didBlurListener.remove();
    }
    
    

    render() {

		var testID = 'chenyu';
        return (
            <View style={{flex: 1,alignItems: 'center',justifyContent: 'center'}}>
               <Text testID = {testID} onPress = {() => this._goto()}>Home Screen</Text>

               <Button onPress={() => this.props.navigation.navigate('Details',{
                   itemId:100,otherParam:'chenyu',})} title = "go to Details"/>
  
               <Button
        	title="Go back"
       		onPress={() => this.props.navigation.goBack()}
              />
        </View>
    );
    }

	_show(value) {
		console.log(value);	
	}

	_goto = () => {
	    toast.show();	
	}

	_back = () => {
		console.log("home back");	
	}
}

class DetailsScreen extends React.Component {


   constructor(props) {
	super(props);
	console.log("DetailsScreen constructor start");
        this.didFocusListener = this.props.navigation.addListener(
		'didFocus',(obj) => {
			console.log("DetailsScreen didFocus start");
            BackHandler.addEventListener('hardwareBackPress',this._back);
		
		
	    }
	);
	this.didBlurListener = this.props.navigation.addListener(
		'didBlur',(obj) => {console.log('DetailsScreen didBlur start')}
	);
    }

	_back = () => {
		console.log("detail back");	
	}

    static navigationoptions = ({navigation}) => {
        return {
            title : navigation.getParam('otherParam','no-values'),};
    };
    componentDidMount = () => {
        console.log("DetailsScreen componentDidMount start")
    }

    componentwillUnmount() {
	console.log("DetailsScreen componentwillUnmount start")
        this.didFocusListener.remove();
	this.didBlurListener.remove();
    }

    render() {
        const {navigation} = this.props;
        const itemId = navigation.getParam('itemId','no-values');
        const otherParam = navigation.getParam('otherParam','no-values');

        return (
            <View style={{ flex: 1,justifyContent: 'center' }}>
	    	<Text>Details Screen</Text>
		<Text>itemId:{JSON.stringify(itemId)}</Text>
		<Text>otherParam:{JSON.stringify(otherParam)}</Text>
		<Button
			title="Go to Details... again"
			onPress={() => this.props.navigation.push('Details',{
		    	itemId: Math.floor(Math.random() * 100),})}
		/>
		<Button
			title="Go to Home"
			onPress={() => this.props.navigation.navigate('Home')}
		/> 
		<Button
			title="Go back"
			onPress={() => this.props.navigation.goBack()}
		/>
		<Button
			title="Go popToTop"
			onPress={() => this.props.navigation.popToTop()}
		/>
           </View>
       );
    }
}


const RootStack = createStackNavigator(
    {
        Home: HomeScreen,Details: DetailsScreen,},{
        initialRouteName: 'Home',}
);


export default class App extends React.Component {

    constructor(props) {
	super(props);
    }
    render() {
        return <RootStack/>;
    }


}

 

 

 

 

 

 

5 运行结果

点击主界面的GO TO DETAILS,进入详细页面,然后分别按下2次back键,日志如下

10-27 23:39:32.498   917  1031 I ReactNativeJS: detail back
10-27 23:39:32.498   917  1031 I ReactNativeJS: home back
10-27 23:39:32.784   917  1031 I ReactNativeJS: DetailsScreen componentwillUnmount start
10-27 23:39:32.790   917  1031 I ReactNativeJS: HomeScreen didFocus start








10-27 23:39:51.164   917  1031 I ReactNativeJS: detail back
10-27 23:39:51.165   917  1031 I ReactNativeJS: home back
10-27 23:39:51.165   917  1031 I ReactNativeJS: detail back
10-27 23:39:51.165   917  1031 I ReactNativeJS: home back
10-27 23:39:51.165   917  1031 I ReactNativeJS: detail back
10-27 23:39:51.165   917  1031 I ReactNativeJS: home back
10-27 23:39:51.165   917  1031 I ReactNativeJS: home back
10-27 23:39:51.165   917  1031 I ReactNativeJS: detail back
10-27 23:39:51.166   917  1031 I ReactNativeJS: detail back
10-27 23:39:51.166   917  1031 I ReactNativeJS: home back
10-27 23:39:51.166   917  1031 I ReactNativeJS: detail back
10-27 23:39:51.166   917  1031 I ReactNativeJS: home back
10-27 23:39:51.166   917  1031 I ReactNativeJS: home back
10-27 23:39:51.621   917  1031 I ReactNativeJS: HomeScreen componentwillUnmount start

我们点击标题栏的返回按钮,和点击GO BACK,执行this.props.navigation.goBack()方法,都不会触发hardwareBackPress监听所执行的函数

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐