【React Native源码分析】Fragment中使用RN

效果图

jjj.gif

这里的“时空”页面除了上面的tab栏,其余完全是RN写的,然后嵌入Fragment使用,刚开始接到这个需求的时候,心里十万个不情愿,由于之前项目里面都是在Activity里面使用,而且React Native并没有提供直接在Fragment使用的基类,那么我们要怎么实现呢?

思考

了解React Native基本原理,应该知道,React Native无非是把js文件解析出来,然后映射成Android原始的组件,然后加入到布局里面,只要明白这一点,那么我们模仿React Native中使用Activity加载RN的流程。

Activity加载View流程

我们在使用Activity加载RN的时候,需要让Activity继承ReactFragmentActivity(这是RN框架提供类,里面封装了加载RN相关逻辑),代码请自行查看,在Activity各个生命周期里委托给ReactActivityDelegate类。那接下来第一步就是模仿ReactFragmentActivity的实现。

  • 模仿ReactFragmentActivity的实现
    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);
      }
    
      ...
    }
    
    1. 创建ReactActivityDelegate实例
      protected ReactActivityDelegate createReactActivityDelegate() {
         return new ReactActivityDelegate(this, getMainComponentName());
      }
      
      需要传入两个参数,第一个就是当前“Activity”,第二个是个String对象,代表当前要加载的RN组件名。
    2. onCreate生命周期重要函数
      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);
      }
      
      • 创建RN根View —— mReactRootView = createRootView()
      • 调用ReactRootView的startReactApplication方法
      • 调用getPlainActivity().setContentView(mReactRootView)
        将创建好的ReactRootView 设置给Activity,这样Acitity显示的就是设置的View了,既然是这样,那么只要我们能拿到这个View对象,那么就可以做很多事情了。

其它请自行查看源码,包括怎么获取参数,路径,在哪里把js解析成Android原生组件的。

完整代码

你可能感兴趣的:(【React Native源码分析】Fragment中使用RN)