1. 程式人生 > >React-Native 原生跳轉不同的RN介面的實現思路

React-Native 原生跳轉不同的RN介面的實現思路

最近在研究React-Native開發App,準備把RN運用到自己的畢業設計中,因為以前做過一個購物社交類的App,但是沒有做完,所以就想把它完善一下作為畢業設計,而RN可以熱更新,所以對於購物類app中的一些時常變化的商品介紹列表就準備用一下RN來試試了。
既然要使用RN和Native混合使用,就得考慮原生如何向RN跳轉的問題了,之前做過的RN專案都是直接一個Activity進入index.android.js,渲染js介面,或者RN介面向Activity跳轉,而現在需要的是從不同的Activity跳轉不同的RN介面,而不是僅僅的跳轉index.android.js。

於是檢視Activity啟動RN的程式碼,發現ReactNativeHost中如下程式碼

 protected String getJSMainModuleName() {
        return "index.android";
    }

    @Nullable
    protected String getJSBundleFile() {
        return null;
    }

    @Nullable
    protected String getBundleAssetName() {
        return "index.android.bundle";
    }

看似如果修改這兩個函式的返回值應該可以更改第一個顯示的介面(但是我沒試過。。。),由於ReactNativeHost這個類是不能更改的,所以我們複製一份程式碼出來,重新建一個ReactNativeHost2 類,然後稍微一修改一些與ReactNativeHost相關聯東西就行,不過本人不是用的這種方法,如果有興趣,大家可以試試可不可以。。。

我用的是另一種方式,由於現在是每次都跳轉index.android.js ,所以只要在index.android.js中渲染不同的佈局就可以了,類似於下面程式碼:

render() {
        if(flag =='xxx1'){
        return (
           <View1></View1>
        );
        }else if(flag=='xxx2'){
           <View2></View2>
        }
    }

View1 和 View2 是要渲染的頁面,這樣就可以類似於跳轉不同頁面了,接下來的問題就是flag的獲取問題了,如何在Native部分啟動RN時傳入不同的flag呢?

繼續在原生程式碼裡尋找,找到ReactActivityDelegate中如下程式碼:

protected void loadApp(String appKey) {
        if(this.mReactRootView != null) {
            throw new IllegalStateException("Cannot loadApp while app is already running.");
        } else {
            this.mReactRootView = this.createRootView();
            this.mReactRootView.startReactApplication(this.getReactNativeHost().getReactInstanceManager(), appKey, this.getLaunchOptions());
            this.getPlainActivity().setContentView(this.mReactRootView);
        }
    }

這是Native啟動RN的核心程式碼,startReactApplication的第三個引數 this.getLaunchOptions() 是一個Bundle 看名字像是一個啟動選項,於是嘗試一下,
原本getLaunchOptions()方法返回的是null 更改為:

 @Nullable
    protected Bundle getLaunchOptions() {
        Bundle bundle = new Bundle();
        bundle.putString("flag1","home");
        return bundle;
    }

嘗試傳入flag1

之後再js端這樣接收:

 componentWillMount() {
        console.log("----componentWillMount"+this.props.flag1);
    }

檢視結果 發現 flag1傳入了 home值,所以此方案是可行的。

接下來就可以根據flag的值 渲染不同的佈局 就可以了 。