1. 程式人生 > >react native 之雙向通訊小tips

react native 之雙向通訊小tips

react natvie 與android 之間的通訊

在上述沒講全一些常見需求的實現。

  • 例如 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);
        }
    }
}