在学习官网上的Toast 的过程中 出现很多的坑
废话就不说了 官网上都有 官网讲解
实现思路 :
我们之前已经将react-native 嵌入原生了 那么 我们就在之前的基础上进行修改就好了
创建ToastUtils.java 继承ReactContextBaseJavaModule 我们要明确自己的目的 就是使用js调用 Toast 就像android 原生一样 能够在屏幕底端进行输出 那么我们需要自己封装方法 供js调用 我们希望调用的形式为ToastShow.show('des',ToastShow.LONG) 那么我们就要自定义 show方法 以及常量 来提供给js
所以具体代码的实现如下:
import android.widget.Toast; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import java.util.HashMap; import java.util.Map; import javax.annotation.Nullable; /** * Created by zhangyanjiao on 17/9/19. * * 功能:在js中写Toast.show('toast text',Toast.SHORT) 可以像原生的toast一样输出东西 * 注:RN已经内置了一个名为ToastAndroid的模块 */ public class ToastUtils extends ReactContextBaseJavaModule{ private static final String DURATION_SHORT_KEY="SHORT"; private static final String DURATION_LONG_KEY="LONG"; public ToastUtils(ReactApplicationContext reactContext) { super(reactContext); } /** *该方法的返回值 的RCT前缀可以自动被移除 所以 即使返回值是RCTToast 在js中也会编译通过 * 在js中会根据这个方法返回的字符串来查找对应的类 * @return */ @Override public String getName() { return "ToastShow"; } /** * 该方法 不一定需要实现 所以可能返回值为空 一般用来返回一些可以被js同步访问的常量 或者是预定义的值 * 在本类中 我们需要给js两个常量 * @return */ @Nullable @Override public Map<String, Object> getConstants() { final HashMap<String, Object> constants = new HashMap<>(); constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG); constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT); return constants; } /** * 要导出一个方法给JavaScript使用,Java方法需要使用注解@ReactMethod。方法的返回类型必须为void。 * React Native的跨语言访问是异步进行的,所以想要给JavaScript返回一个值的唯一办法是使用回调函数或者发送事件 * 下面的参数类型在@ReactMethod注明的方法中,会被直接映射到它们对应的JavaScript类型。 Boolean -> Bool Integer -> Number Double -> Number Float -> Number String -> String Callback -> function ReadableMap -> Object ReadableArray -> Array * @param msg 弹出的提示信息 * @param duration 显示事件长短 */ @ReactMethod public void show(String msg,int duration){ Toast.makeText(getReactApplicationContext(),msg,duration).show(); } }
然后要进行注册 否则的话 js将无法找到该类
创建 RegistPackage.java 实现ReactPackage接口
import com.facebook.react.ReactPackage; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Created by zhangyanjiao on 16/9/20. */ public class RegistPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new ToastUtils(reactContext)); return modules; } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
别忘了在mainActivity中添加 addPackage
.addPackage(new RegistPackage())
最后为了在js文件中更方便的使用 我们对调用进行封装
创建ToastShow.js文件 具体实现如下
'use strict' /** * This exposes the native ToastAndroid module as a JS module. This has a function 'show' * which takes the following parameters: * * 1. String message: A string with the text to toast * 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG */ import { NativeModules } from 'react-native'; // 下一句中的ToastAndroid即对应上文 // public String getName()中返回的字符串 // 练习时请务必选择另外的名字! export default NativeModules.ToastShow;
此时我们就可以安心引用了
在index.android.js文件中
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, } from 'react-native'; import ToastShow from './ToastShow' var { NativeModules } = require('react-native'); class MyApp extends Component { constructor(props) { super(props); } render() { ToastShow.show('我是弹窗',ToastShow.LONG); return( <View > <Text>{'hahahhahhahah'}</Text> </View> ) } } AppRegistry.registerComponent('MyApp', () => MyApp);
记住修改完 要进行重新的编译 运行 直接使用热更新的话 会报错