1. 程式人生 > >React Native 學習筆記十三(原生模組之Toast)

React Native 學習筆記十三(原生模組之Toast)

 在學習官網上的Toast 的過程中 出現很多的坑 

廢話就不說了 官網上都有 官網講解

實現思路 :

我們之前已經將react-native 嵌入原生了 那麼 我們就在之前的基礎上進行修改就好了   

建立ToastUtils.java 繼承ReactContextBaseJavaModule 我們要明確自己的目的 就是使用js呼叫 Toast 就像android 原生一樣 能夠在螢幕底端進行輸出  那麼我們需要自己封裝方法 供js呼叫  我們希望呼叫的形式為ToastShow.show('des',ToastShow.LONG) 那麼我們就要自定義 show方法 以及常量 來提供給js

所以具體程式碼的實現如下:

importandroid.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);

記住修改完 要進行重新的編譯  執行 直接使用熱更新的話 會報錯