效果圖
jjj.gif
這里的“時(shí)空”頁面除了上面的tab欄,其余完全是RN寫的,然后嵌入Fragment使用,剛開始接到這個(gè)需求的時(shí)候,心里十萬個(gè)不情愿,由于之前項(xiàng)目里面都是在Activity里面使用,而且React Native并沒有提供直接在Fragment使用的基類,那么我們要怎么實(shí)現(xiàn)呢?
思考
了解React Native基本原理,應(yīng)該知道,React Native無非是把js文件解析出來,然后映射成Android原始的組件,然后加入到布局里面,只要明白這一點(diǎn),那么我們模仿React Native中使用Activity加載RN的流程。
Activity加載View流程
我們在使用Activity加載RN的時(shí)候,需要讓Activity繼承ReactFragmentActivity(這是RN框架提供類,里面封裝了加載RN相關(guān)邏輯),代碼請自行查看,在Activity各個(gè)生命周期里委托給ReactActivityDelegate類。那接下來第一步就是模仿ReactFragmentActivity的實(shí)現(xiàn)。
- 模仿ReactFragmentActivity的實(shí)現(xiàn)
public abstract class BaseReactFragment extends Fragment implements PermissionAwareActivity { private ReactFragmentDelegate mDelegate; private Activity mActivity; ... protected ReactFragmentDelegate createReactFragmentDelegate() { return new ReactFragmentDelegate(this, getMainComponentName()); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDelegate = createReactFragmentDelegate(); mActivity = getActivity(); mDelegate.onCreate(savedInstanceState); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return mDelegate.onCreateView(inflater, container, savedInstanceState); } @Override public void onViewCreated(View view, @android.support.annotation.Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); } ... }
- 創(chuàng)建ReactActivityDelegate實(shí)例
需要傳入兩個(gè)參數(shù),第一個(gè)就是當(dāng)前“Activity”,第二個(gè)是個(gè)String對象,代表當(dāng)前要加載的RN組件名。protected ReactActivityDelegate createReactActivityDelegate() { return new ReactActivityDelegate(this, getMainComponentName()); }
- onCreate生命周期重要函數(shù)
protected void loadApp(String appKey) { if (mReactRootView != null) { throw new IllegalStateException("Cannot loadApp while app is already running."); } mReactRootView = createRootView(); mReactRootView.startReactApplication( getReactNativeHost().getReactInstanceManager(), appKey, getLaunchOptions()); getPlainActivity().setContentView(mReactRootView); }
- 創(chuàng)建RN根View —— mReactRootView = createRootView()
- 調(diào)用ReactRootView的startReactApplication方法
- 調(diào)用getPlainActivity().setContentView(mReactRootView)
將創(chuàng)建好的ReactRootView 設(shè)置給Activity,這樣Acitity顯示的就是設(shè)置的View了,既然是這樣,那么只要我們能拿到這個(gè)View對象,那么就可以做很多事情了。
- 創(chuàng)建ReactActivityDelegate實(shí)例
其它請自行查看源碼,包括怎么獲取參數(shù),路徑,在哪里把js解析成Android原生組件的。