ReactNative封装Android原生组件
本篇以封装按钮组件为例. 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> } } 最终效果 Untitled1.gif