- ReactNative?
- 是Facebook开源的跨平台移动应用开发框架
- ReactNative的导入
- iOS使用CocoaPods
- android使用Gradle
- 在原生应用中嵌入RN
- iOS:从RN中加载的view添加到viewcontroller
- RNViewController封装:
// RNViewController.h
@interface RNViewController : UIViewController
@property (nonatomic, copy) NSString *jsBundleURLForBundleRoot;
@property (nonatomic, copy) NSString *moduleName;
@property (nonatomic, copy) NSDictionary *props;
// RNViewController.m
@implementation RNViewController
-(void)viewDidLoad {
[super viewDidLoad];
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:self.jsBundleURLForBundleRoot fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:self.moduleName
initialProperties:self.props
launchOptions:nil];
self.view = rootView;
}
@end
- RNViewController调用:
RNViewController *rnViewController = [[RNViewController alloc] init];
rnViewController.jsBundleURLForBundleRoot = @"reactNative/pages/IndexPage";
rnViewController.moduleName = @"IndexPage";
rnViewController.props = props;
[UIApplication sharedApplication].keyWindow.rootViewController = rnViewController;
-
文件目录:
- android:从RN中加载的view添加到activity
- RNActivity封装
//RNActivity
public class RNActivity extends BaseActivity implements DefaultHardwareBackBtnHandler {
public static final String MODULE_NAME_KEY = "module_name_key";
public static final String PARAM_KEY = "param_key";
public static final String TITLE_KEY = "title_key";
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rn);
String moduleName = getIntent().getStringExtra(MODULE_NAME_KEY);
Bundle param = getIntent().getBundleExtra(PARAM_KEY);
mReactInstanceManager = MyApplication.reactInstanceManager();
mReactRootView = new ReactRootView(this);
mReactRootView.startReactApplication(mReactInstanceManager,
moduleName, param);
mContainer.addView(mReactRootView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
}
//MyApplication
public class MyApplication extends Application {
private static ReactInstanceManager mReactInstanceManager;
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(this)
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("reactNative/pages/IndexPage")
.addPackage(new MainReactPackage())
.addPackage(new MyReactPackage())//用于导出包
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
}
public static ReactInstanceManager reactInstanceManager() {
return mReactInstanceManager;
}
}
- RNActivity调用:
Intent intent = new Intent(this, RNActivity.class);
intent.putExtra(RNActivity.MODULE_NAME_KEY, "IndexPage");
intent.putExtra(RNActivity.PARAM_KEY, bundle);
startActivity(intent);
- RN中使用原生控件:
- iOS:
// TopologyView.h
@interface TopologyView : UIView
@property (nonatomic, strong) NSArray *dataResource;
@property (nonatomic, copy) RCTBubblingEventBlock onItemClick;
@end
// TopologyView.m
//数据源
-(void)setDataResource:(NSArray *)machineArr{
//添加子view
}
//RN传递来的事件
-(void)onItemClickInRN{
self.onItemClick(@{@"index":@(_selectedMachineView.tag)});
}
//TopologyViewManager.h
@interface TopologyViewManager : RCTViewManager
@end
//TopologyViewManager.m
@implementation TopologyViewManager
RCT_EXPORT_MODULE()
RCT_EXPORT_VIEW_PROPERTY(dataResource, NSArray)
RCT_EXPORT_VIEW_PROPERTY(onItemClick, RCTBubblingEventBlock)
-(UIView *)view
{
TopologyView *view = [[TopologyView alloc] init];
return view;
}
@end
- android:
//TopologyLayout
public class TopologyLayout extends RelativeLayout{
public void setMachineList(ArrayList<OrgTreeNode> machineList){
//添加子view
}
private void onReceiveNativeEvent(int index){
WritableMap event = Arguments.createMap();
event.putInt("index", index);
ReactContext reactContext = (ReactContext)getContext();
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("onItemClick", event);
}
}
//TopologyLayoutManager
public class TopologyLayoutManager extends SimpleViewManager<TopologyLayout> {
@Override
public String getName() {
return "TopologyView";
}
@Override
protected TopologyLayout createViewInstance(ThemedReactContext themedReactContext) {
return new TopologyLayout(themedReactContext);
}
@ReactProp(name = "dataResource")
public void setDataResource(TopologyLayout layout, ReadableArray dataResource){
if (dataResource!=null){
Gson gson = new GsonBuilder().create();
ArrayList<OrgTreeNode> nodes =gson.fromJson(dataResource.toString(), new TypeToken<ArrayList<OrgTreeNode>>() {}.getType());
layout.setMachineList(nodes);
}
}
}
//MyReactPackage
public class MyReactPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new TopologyLayoutManager()
);
}
}
注意:android导出需要在ReactInstanceManager初始化的时候addPackage(new MyReactPackage())
- RN中调用:
//TopologyView.js
import { requireNativeComponent, View } from 'react-native';
module.exports = requireNativeComponent('TopologyView', null);
//TopologyPage.js
import TopologyView from '../nativeModules/TopologyView'
export default class TopologyPage extends React.Component {
componentDidMount() {
this.onTopologyViewItemClickListener = DeviceEventEmitter.addListener('onItemClick',(event) => {
//android点击事件
})
}
componentWillUnmount() {
this.onTopologyViewItemClickListener.remove();
}
render(){
return(
<View style={styles.fullScreen}>
<TopologyView
style={styles.fullScreen}
dataResource={this.props.dataResource}
onItemClick={this.onItemClick.bind(this)}
/>
</View>
)
}
onItemClick(event: Event) {
//iOS点击事件
}
}
- 总结:
- iOS和android嵌入RN都是指定文件URL和参数即可,android稍微复杂一点,需要用ReactInstanceManager初始化。
- iOS导出原生模块需要创建Manager继承RCTViewManager,然后在Manager.m中用RCT_EXPORT_MODULE宏即可导出。
android还需要新建ReactPackage子类,在createViewManagers中添加Manager,然后在ReactInstanceManager初始化的时候添加该ReactPackage子类才可供RN调用。 - iOS的事件传递通过props以block代码块形式传入。
android以消息通知机制发送事件。