本篇以封装按钮组件为例.
Ready
在开始封装之前,希望你已经在本机搭建好React Native的Android运行环境.
Go
Android部分
- 创建一个原生的按钮,并为其添加映射事件以及按钮属性
package com.RCTButton;
import android.view.View;
import android.widget.Button;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import java.util.Map;
import javax.annotation.Nullable;
public class RCTButton extends SimpleViewManager<Button> {
private ThemedReactContext mContext;
// private static final String EVENT_NAME_ONCLICK_NATIVE = "onClick";
private static final String EVENT_NAME_ONCLICK_NATIVE = "nativeClick";
private static final String EVENT_NAME_ONCLICK_JS = "jsClick";
@Override
public String getName() {
return "RCTButton";
}
@Override
protected Button createViewInstance(ThemedReactContext reactContext) {
this.mContext = reactContext;
Button button = new Button(reactContext);
return button;
}
@Override
protected void addEventEmitters(final ThemedReactContext reactContext, Button view) {
super.addEventEmitters(reactContext, view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
WritableMap data = Arguments.createMap();
data.putString("msg", "点击按钮");
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
v.getId(),
EVENT_NAME_ONCLICK_NATIVE,
data
);
}
});
}
/*
name="text" : name对应的值是在js代码中使用该封装组件时的属性名。
*/
@ReactProp(name = "text")
public void setText(Button button, String text) {
button.setText(text);
}
@Nullable
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
return MapBuilder.<String, Object>builder()
.put(
EVENT_NAME_ONCLICK_NATIVE,
MapBuilder.of(
"registrationName",
EVENT_NAME_ONCLICK_JS))
.build();
}
}
- 注册该UI组件
package com.RCTButton;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RCTViewPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(new RCTButton());
}
}
- 在MainApplication中注册
package com.batsoftapp;
import android.app.Application;
import com.RCTButton.RCTViewPackage;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RCTViewPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
React Native JS部分
'use strict';
import React, {PureComponent} from 'react';
import {
View,
Image,
FlatList,
StyleSheet,
TouchableOpacity,
requireNativeComponent
} from 'react-native';
import PropTypes from 'prop-types';
let rctButton = {
name: 'RCTButton',
propTypes: {
text: PropTypes.string,
...View.propTypes
}
}
let RCTButton = requireNativeComponent('RCTButton', rctButton);
export default class Example extends PureComponent {
jsClick(event) {
alert(event.nativeEvent.msg)
}
render(){
<View style={[ThemeStyle.container}]}>
<RCTButton style={{height: 50, width: 200}} text={'点击'} jsClick={(event) => this.jsClick(event)}/>
</View>
}
}