React Native学习安卓手机上的返回键BackAndroid

来源:互联网 发布:edge网络是什么 编辑:程序博客网 时间:2024/05/19 18:38
使用 React Native开发,iOS搞完,开始适配安卓,由于木有接触过安卓,所以碰到了很多问题,第一个问题,安卓的返回键BackAndroid问题,

我写了一个工具类,来搞定,其中用到了Java原生代码与js交互;好吧,上代码:

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //  BackAndroidTool  
  2. //  功能: "安卓手机上的返回键"  
  3. //  Created by 小广 on 2016-05-10 下午.  
  4. //  Copyright © 2016年  All rights reserved.  
  5. /* 
  6. 使用: 参考链接:http://reactnative.cn/post/480 
  7.  1.在首页/homepage页(只需要在全局都存在的页面调用一次监听即可) 
  8.  componentDidMount(){ 
  9.     // 添加返回键监听 
  10.     BackAndroidTool.addBackAndroidListener(this.props.navigator); 
  11.  } 
  12.  
  13.  componentWillUnmount(){ 
  14.     // 移除返回键监听 
  15.     BackAndroidTool.removeBackAndroidListener(); 
  16.  } 
  17.   说明:BackAndroid在iOS平台下是一个空实现, 
  18.   所以理论上不做这个Platform.OS === 'android'判断也是安全的。 
  19.  
  20.   2. 某些类自定义返回键操作(即点击返回键弹出一个alert之类的操作) 
  21.   在所需类的初始化方法里调用BackAndroidTool.customHandleBack 
  22.   栗子: 
  23.   constructor(props) { 
  24.     super(props); 
  25.         BackAndroidTool.customHandleBack(this.props.navigator,() => { 
  26.             Alert.alert('提示','您还未保存记录,确定要返回么?', 
  27.                         [{text:'取消',onPress:() => {}}, 
  28.                          {text:'确定',onPress:() => { this.props.navigator.pop(); }} 
  29.                         ]); 
  30.                     // 一定要 return true; 原因上面的参考链接里有 
  31.               return true; 
  32.         }); 
  33.   } 
  34.  
  35.   3.某些页面需要禁用返回键 
  36.   在nav进行push的时候,设置属性ignoreBack为true 即可 
  37.   this.props.navigator.push({ 
  38.     component: 所需要禁用的类, 
  39.     ignoreBack:true, 
  40.   }); 
  41.  
  42. */  
  43.   
  44. 'use strict';  
  45. import React,{  
  46.   Platform,  
  47.   Navigator,  
  48.   BackAndroid,  
  49.   ToastAndroid,  
  50.   NativeModules,  
  51. } from 'react-native';  
  52.   
  53. // 类  
  54. var NativeCommonTools = NativeModules.CommonTools;  
  55.   
  56. export default {  
  57.   // 监听返回键事件  
  58.   addBackAndroidListener(navigator) {  
  59.     if (Platform.OS === 'android') {  
  60.       BackAndroid.addEventListener('hardwareBackPress',() => {  
  61.          return this.onBackAndroid(navigator);  
  62.       });  
  63.     }  
  64.   },  
  65.   
  66.   // 移除监听  
  67.   removeBackAndroidListener() {  
  68.     if (Platform.OS === 'android') {  
  69.       BackAndroid.removeEventListener('hardwareBackPress', () => {  
  70.       });  
  71.     }  
  72.   },  
  73.   
  74.   // 判断是返回上一页还是退出程序  
  75.   onBackAndroid(navigator) {  
  76.     if (!navigator) return false;  
  77.     const routers = navigator.getCurrentRoutes();  
  78.     // 当前页面不为root页面时的处理  
  79.     if (routers.length > 1) {  
  80.       const top = routers[routers.length - 1];  
  81.       if (top.ignoreBack || top.component.ignoreBack) {  
  82.           // 路由或组件上决定这个界面忽略back键  
  83.           return true;  
  84.       }  
  85.       const handleBack = top.handleBack || top.component.handleBack;  
  86.       if (handleBack) {  
  87.           // 路由或组件上决定这个界面自行处理back键  
  88.           return handleBack();  
  89.       }  
  90.   // 默认行为: 退出当前界面。  
  91.       navigator.pop();  
  92.       return true;  
  93.      }  
  94.     // 当前页面为root页面时的处理  
  95.     if (this.lastBackPressed && (this.lastBackPressed + 2000 >= Date.now())) {  
  96.          //最近2秒内按过back键,可以退出应用。  
  97.          NativeCommonTools.onBackPressed();  
  98.          return true;  
  99.         }  
  100.       this.lastBackPressed = Date.now();  
  101.       ToastAndroid.show('再按一次退出应用',ToastAndroid.SHORT);  
  102.       return true;  
  103.   },  
  104.   
  105.   // 自定义返回按钮事件  
  106.   customHandleBack(navigator, handleBack) {  
  107.     if (navigator) {  
  108.       let routes = navigator.getCurrentRoutes(); //nav是导航器对象  
  109.       let lastRoute = routes[routes.length - 1]; // 当前页面对应的route对象  
  110.         lastRoute.handleBack = handleBack;  
  111.     }  
  112.     },  
  113.   
  114. }  

其中的java原生代码如下:

管理类:RCTCommonToolsPackage (ps:如是不明白,可以去这里 React Native学习:http://reactnative.cn/docs/0.25/native-modules-android.html#content);

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.commonTools;  
  2.   
  3. import com.facebook.react.ReactPackage;  
  4. import com.facebook.react.bridge.JavaScriptModule;  
  5. import com.facebook.react.bridge.NativeModule;  
  6. import com.facebook.react.bridge.ReactApplicationContext;  
  7. import com.facebook.react.uimanager.ViewManager;  
  8.   
  9. import java.util.Arrays;  
  10. import java.util.Collections;  
  11. import java.util.List;  
  12.   
  13. public class RCTCommonToolsPackage implements ReactPackage {  
  14.   @Override  
  15.   public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {  
  16.     return Arrays.<NativeModule>asList(new RCTCommonTools(reactContext));  
  17.   }  
  18.     
  19.   @Override  
  20.   public List<Class<? extends JavaScriptModule>> createJSModules() {  
  21.     return Collections.emptyList();  
  22.   }  
  23.     
  24.   @Override  
  25.   public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {  
  26.     return Collections.emptyList();  
  27.   }  
  28. }  

自定义方法的类:RCTCommonTools

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.commonTools;  
  2.   
  3. import android.content.Intent;  
  4.   
  5. import com.facebook.react.bridge.Callback;  
  6. import com.facebook.react.bridge.ReactApplicationContext;  
  7. import com.facebook.react.bridge.ReactContextBaseJavaModule;  
  8. import com.facebook.react.bridge.ReactMethod;  
  9.   
  10. import com.tcpaydls.BuildConfig;  
  11.   
  12. public class RCTCommonTools extends ReactContextBaseJavaModule {  
  13.     
  14.   public RCTCommonTools(ReactApplicationContext reactContext) {  
  15.     super(reactContext);  
  16.   }  
  17.     
  18.   @Override  
  19.   public String getName() {  
  20.     return "RCTCommonTools";  
  21.   }  
  22.     
  23.   /** 
  24.    * 此方法是为了解决返回键退出程序后,ToastAndroid不会消失的bug 
  25.    */  
  26.   @ReactMethod  
  27.   public void onBackPressed() {  
  28.     Intent setIntent = new Intent(Intent.ACTION_MAIN);  
  29.     setIntent.addCategory(Intent.CATEGORY_HOME);  
  30.     setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  31.     getCurrentActivity().startActivity(setIntent);  
  32.       
  33.   }  
  34. }  
0 0
原创粉丝点击