最近在开发一些android原生的功能,深深体会到android原生ui的复杂度真的很高,加上熟练度比较低也不想花费很高的成本去学习,所以想把ReactRootView
嵌到进原生activity中去实现一些ui上的交互功能
首先native发送事件给js 一般只会用到NativeEventEmitter
已经足够了 写法也很简单
import React, { useEffect } from 'react';
import { NativeModules, NativeEventEmitter } from 'react-native';
import useEvent from './useEvent';
export default function useNativeEvent<T extends any>(
eventName: string,
listener: (data: T) => void
) {
const register = useEvent(() => {
const EventEmitter = new NativeEventEmitter(NativeModules.MultiBundle);
return EventEmitter.addListener(eventName, listener);
});
useEffect(() => {
const subject = register();
return subject.remove;
}, []);
}
public static void sendEvent(String eventName, Object eventData) {
ReactContext reactContext = MainApplication.mReactNativeHost.getReactInstanceManager().getCurrentReactContext();
eventData = RNConvert.convert(eventData);
if (reactContext != null) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,eventData);
}
}
但是在js上调用原生方法,一般都是通过@ReactMethod
注解去实现的,当我在原生的ui上想调用当前activity的方法就会比较恶心,我可能要先在ReactContextBaseJavaModule
业务类中实现一个方法,然后通过广播发送出去,再在当前activity中注册一个listener,诸如类的复杂通信方法,会导致代码复杂程度上升,思考了一下,原生可以通过findViewById
拿到view后绑定事件,rn应该也可以,然后搜索了一番,具体的实现方式如下:
<TouchableOpacity nativeID="testBtn">
<View
style={{
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: 'red',
}}></View>
</TouchableOpacity>
import com.facebook.react.uimanager.util.ReactFindViewUtil;
private final ReactFindViewUtil.OnViewFoundListener onTestBtnViewFound = new ReactFindViewUtil.OnViewFoundListener() {
@Override
public String getNativeId() {
return "testBtn";
}
@Override
public void onViewFound(View view) {
if (view != null) {
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
FaceDetectionActivity.this.finish();
}
return true;
}
});
}
}
};
@Override
protected void onStart() {
super.onStart();
ReactFindViewUtil.addViewListener(onTestBtnViewFound);
}
@Override
public void finish() {
super.finish();
ReactFindViewUtil.removeViewListener(onTestBtnViewFound);
}
这样一来rn中的button调用当前activity中的方法就轻松了很多