原文链接:https://blog.csdn.net/qq_22329521/article/details/80402657
react natvie 与android 之间的通信
- 原生模块 https://reactnative.cn/docs/0.51/native-modules-android.html#content
- 原生视图 https://reactnative.cn/docs/0.51/native-component-android.html#content
在上述没讲全一些常见需求的实现。
- 例如 js与native 自定义事件的通信等 由于 暴露给js的视图 是继承SimpleViewManager 只提供了暴露了属性给js 设置
- 又比如js的视图 渲染给native 的加载
js调用native 视图的方法 实现
public abstract class XXXManager<T extends XXXView> extends ViewGroupManager<T> {
private static final String CLEAR = "clear";
private static final int CLEARTAG = 1;
private static final String REFRESH="refresh";
private static final int REFRESHTAG=2;
public T mView;
@ReactProp(name = "data")
public abstract void setData(T view, ReadableArray array);
//自定义了四个事件,native 发送给js的
@Nullable
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
builder.put("onTranslate", MapBuilder.of("registrationName", "onTranslate"));
builder.put("onScale", MapBuilder.of("registrationName", "onScale"));
builder.put("onValueSelect", MapBuilder.of("registrationName", "onValueSelect"));
builder.put("onNothingSelect", MapBuilder.of("registrationName", "onNothingSelect"));
return builder.build();
}
public void clear() {
if (mView==null)return;
mView.clear();
}
public void refesh(){
if (mView==null)return;
mView.invalidate();
}
@Nullable
@Override
public Map<String, Integer> getCommandsMap() {
Map<String, Integer> map = new HashMap<>();
map.put(CLEAR, CLEARTAG);
map.put(REFRESH,REFRESHTAG);
return map;
}
//收到js发送给native的信息
@Override
public void receiveCommand(T root, int commandId, @Nullable ReadableArray args) {
switch (commandId) {
case CLEARTAG:
clear();
break;
case REFRESHTAG:
refesh();
break;
}
}
}
native 发送消息 例如发送onScale 在上面注册了
private void test(){
WritableMap event = Arguments.createMap();
event.putDouble("scaleX", scaleX);
event.putDouble("scaleY", scaleY);
setJSMEssage("onScale", event);
}
private void setJSMEssage(String funName, WritableMap event) {
ReactContext reactContext = (ReactContext) getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
getId(),
funName,
event);
}
js端 接受事件
<XXXView
....
onScale={(event)=>console.log('onTranslated',event.nativeEvent)}
/>
js发送事件
refresh(){
let r = this.ref.getRef()
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(r),
//refresh 就是getCommandsMap 和receiveCommand 注册的信息
UIManager.XXXX.Commands.refresh,
null
)
}
react 的视图给native 渲染
常见需求,例如 原生暴露的事件给js 端,但是 又部分 视图不需要本地些死 而是暴露接口给上层,例如 地图的mark 自定义mark是js端根据需求自定义 给native 地图组件渲染,又例如 下拉刷新 控件的头部等
实现
我们先封装一个自定义View给js
public class MarkView extends ReactViewGroup{
public MarkView(Context context) {
super(context);
}
public int width;
public int height;
}
将这个视图暴露给js
public class MarkManager extends ViewGroupManager<MarkView> {
public static final String REACT_CLASS = "MarkView";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected MarkView createViewInstance(ThemedReactContext reactContext) {
return new MarkView(reactContext);
}
}
//js调用 这里是view是native 封装好的视图给js 然后在里面添加自定义的markView 给native 渲染
<XXXView
...
onScale={(scaleX, scaleY) => {
console.log(scaleX, scaleY, '=========== onScale BarChartView.js')
}}
>
{this.renderMarkView()}
</XXXView>
)
}
renderMarkView () {
return (
<MarkView style={{ width: 50, height: 50, backgroundColor: '#0f0' ,justifyContent:'center',alignItems:'center'}} offset={{posx:0,posy:-100}}>
<Text>ssss</Text>
</MarkView>
)
}
//在我们刚才的xxxManager做处理
public abstract class XXXManager<T extends XXXView> extends ViewGroupManager<T> {
private static final String CLEAR = "clear";
private static final int CLEARTAG = 1;
private static final String REFRESH="refresh";
private static final int REFRESHTAG=2;
public T mView;
@Override
public void addView(T parent, View child, int index) {
if (child instanceof MarkView) {
//这里已经接受了这个child 然后 你想干嘛就干嘛 注意这里的addView 并没有添加到里面 需要自己逻辑处理是否addView
parent.setMark((MarkView) child,index);
}
}
}