这两天主要了解了 React Native 的基本使用,以及和原生代码混编的方式,最后写了一个 demo ,主要实现了在 JavaScript 代码当中调用 UINavigationController 和自定义的 ViewController 等原生组件的功能。
原生代码混编
我们遇到的问题是:我们要在 React Native 项目当中添加原生实现的 IM 模块Leanchat-ios。
React Native 官方文档给出了使用原生代码扩展功能的方法:
Native Modules
Native UI Components
首先,IM 模块是一个完整的功能模块而不是一个简单的 UI 组件,很多的功能代码集中在各种 UIViewController 里。 React Native 目前是不支持封装 UIViewController 的 ,所以,第二种方法不行。
不过,可以使用第一种方式,为 JavaScript 代码封装一个操作 UINavigationController 的接口。除了 IM 部分以外,其他功能采用 React Native 组件实现,当需要跳转到 IM 模块的时候,调用封装的接口将 IM 模块 push 到 navigationController 上即可。
接口代码如下:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "CDLoginVC.h"
#import "SpringBoard.h"
@implementation SpringBoard
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(gotoIM:(RCTResponseSenderBlock)callback)
{
UINavigationController *controller = (UINavigationController*)[[[UIApplication sharedApplication] keyWindow] rootViewController];
CDLoginVC *loginVC = [[CDLoginVC alloc] init];
[controller pushViewController:loginVC animated:true];
callback(@[[NSNull null]]);
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
@end
JavaScript 当中调用上面的接口:
var React = require('react-native');
var {
// ...
NativeModules
} = React;
var SpringBoard = NativeModules.SpringBoard;
var DemoView = React.createClass({
gotoIM: function() {
// 跳转到 IM 模块
SpringBoard.gotoIM(function() {
console.log('goto IM');
});
},
render: function() {
...
}
});
在 android 平台上实现上述功能
上面提到的两种原生模块开发方式,在 android 上面也都是支持的。直接上代码:
package com.awesomeproject;
// imports ...
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new SpringBoardPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "AwesomeProject", null);
setContentView(mReactRootView);
}
// ...
// 实现跳转功能
private class SpringBoardPackage implements ReactPackage {
//...
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext context) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new SpringBoard(context));
return modules;
}
}
private class SpringBoard extends ReactContextBaseJavaModule {
//...
@ReactMethod
public void gotoIM(Callback callback) {
ReactApplicationContext context = getReactApplicationContext();
Intent intent = new Intent(context, LoginActivity.class);
MainActivity.this.startActivity(intent);
callback.invoke("result");
}
}
}
React Native 其他方面
对移动 App 的开发经验还不是很多,不过 React Native 提供了跨平台的 Navigator 组件,支持 flexbox 布局,总体感觉还不错。而且官方文档比较全面,和 Phonegap 相比,社区支持感觉更好。