在本教程的开始,就曾经提到过纯Rn和原生与RN混合开发的两种概念。之前的两个Demo如果不考虑难易程度的话,则为纯Rn应用开发。但在实际生产中,毕竟Rn的组件还不是那么完善,所以,当我们需要比较炫酷的动画效果或者在使用Rn组件时遇到诡异的坑而没有进展的时候,我们可以使用Rn与原生协同开发来实现最终效果。
React Native设计为可以在其基础上编写真正的原生代码,并且可以访问平台所有的能力。这是一个相对高级的特性,我们并不认为它应当在日常开发的过程中经常出现,但具备这样的能力是很重要的。如果React Native还不支持某个你需要的原生特性,你应当可以自己实现该特性的封装。(这就麻烦了)
下面,我们来介绍我们的Demo3,照例先给出效果图(Android):
(这个是在Demo2的样式基础上改的,由于Demo2的样式在Android上根本没法看,所以我适当增加了输入框的宽度,添加了marginBottom等…)
项目git地址:https://github.com/yujiesuperman/react-native-demo3-RnandNative
Demo3总共完成了两点:
从原生开机动画跳转到Rn登陆页面,从Rn主界面调用Native的Toast方法和获取字符串数据。
(一)从Rn页面调用Native的组件方法
假设我们希望可以从Javascript发起一个Toast消息(Android中的一种会在屏幕下方弹出、保持一段时间的消息通知):
使用AS导入Android文件夹下的gradle项目。
①第一步是先添加一个原生的类(CustomToastModule),让他继承ReactContextBaseJavaModule, 在这个方法中,我们主要的目的有两个,
1)重写getName方法,比如这里return的是NativeToastAndroid
2)重写一个show方法,里面有native实现的一些功能
最终的目的就是能在JavaScript中调用
NativeToastAndroid.show('这个弹窗来自Android ', NativeToastAndroid.SHORT );
来调起一个Toast通知。
备注:一个可选的方法getContants返回了需要导出给JavaScript使用的常量。它并不一定需要实现,但在定义一些可以被JavaScript同步访问到的预定义的值时非常有用。这样的话,JavaScript写SHORT或者LONG这边就能对应替换了
②再添加一个类(NativeToastAndroidReactPackage),继承ReactPackage,
这个类要将方法暴露出去,在应用的Package类的createNativeModules方法中添加这个模块,把我们的CustomToastModule加进去,让rn调用。
③在MainApplication中
这里是第三个需要修改的类,刚才定义完ToastAndroidReactPackage方法的时候,需要在这里最终注册
添加到return列表里。
④从AS中切回Rn中,
这个方法不是必须的,为了让你的功能从JavaScript端访问起来更为方便,通常我们都会把原生模块封装成一个JavaScript模块。
这不是必须的,但省下了每次页面在使用之前,
都从NativeModules中获取对应模块( . NativeToastAndroid) 的步骤。这个JS文件也可以用于添加一些其他JavaScript端实现的功能(也就是说不必单拉出一个文件来实现这个东西,作者是为了方便阅读,才单建立的目录)。
⑤调用的时候,从上面引入
备注:从Rn调用Android的Toast组件我们已经写完了,那么有些同学可能要问了,那要从Native向Js传递数据该咋办?其实非常简单,而且又多种实现的方式,这里只列举一种:
在刚才的show方法下面再弄一个dataToJs,写法如上,然后在Rn的js中这样添加:
就完成了效果图中的Alert弹窗展示从Native端拿到的数据了,
至于其他的获取方式请参考Rn中文网链接:
http://reactnative.cn/docs/0.42/native-modules-android.html#content
注意:Rn也并没有封装全部的UI组件,只是封装了一部分,要想自己封装,提供一个ImageView之类的UI组件,则需要
①创建一个ViewManager的子类。
②实现createViewInstance方法。
③导出视图的属性设置器:使用@ReactProp(或@ReactPropGroup)注解。
④把这个视图管理类注册到应用程序包的createViewManagers里。
⑤实现JavaScript模块。
在这里就不详细介绍了,请想深入了解的朋友去Rn中文网上阅读相关内容:
http://reactnative.cn/docs/0.42/native-component-android.html#content
(二)加入原生开机动画AwesomeSplash
下面说下如何从炫酷的开机动画跳转到我们的Rn页面,其实非常简单,在GitHub上可以参看到AwesomeSplash的使用方法,
附上git链接:https://github.com/ViksaaSkool/AwesomeSplash
注意,他有一行注释,就是千万不要复写onCreate方法,所以,如果你和我一样是新建了一个activity,就要删掉你的onCreate方法。
而且还要从git-AwesomeSplash上面的Demo中把对应的缺失的文件补充进来,在下面的animationsFinished方法中创建跳转意图,跳转到RN的Activity页面。
最后从配置文件中,把我们的AnimActivity设置为启动页面即可。
备注:可能有些人要问了,你这是RN项目中集成Native页面,那如果是原有的Native项目该怎么去集成Rn页面呢?
其实我感觉原理是差不多的,类似于环境转移,比照着Rn项目生成的Native壳子里面的配置,去给我们自己之前的Native项目添加Rn支持,最后还是Native页面跳RnActivity或者RnFragment。
比如首先配置build.gradle,然后再还需添加react native的DevSettingActivity,写类继承ReactActivity,提供一个实现ReactApplication的全局Application文件等等…如果想了解具体步骤的话可以参看:http://lib.csdn.net/article/reactnative/50089
总结:
好了,Demo3也讲完了,现在我们来看下如果要进行一个Rn的项目开发大概需要进行哪些准备设计工作?
①设计组件数量,设计应用页面到底该由哪些组件构成,组件的子组件数量
组件的划分遵循单一责任原则。
②Redux的状态数的设计,(结合Demo2)
③路由的设计,页面的组合方式(结合Demo2)
④是不是需要使用Native代码配合