在React Native上为android创建自定义UI组件。如何将数据发送给JS?

时间:2016-01-12 09:20:35

标签: android react-native

我创建了UI。它运作良好。但我不知道如何将数据从Java发送到JS?在本机模块中,我可以使用回调并激活这个onClick事件。但在UI我不知道。

更多关于我需要的东西。 我有android组件。以这种方式发送给JS createViewInstance(ThemedReactContext reactContext)

用户在组件内部发生了变化。我在java类中看到了这些变化。当JS要求时,我需要将这些更改发送给JS。

您知道如何将数据从UI组件发送到JS吗?请举个例子。 谢谢。

2 个答案:

答案 0 :(得分:16)

gre's answer that put me on the right track, but still left me with a lot of work to do的基础上,我将尝试解释一些遗漏的细节。

有两种基本方法可以做到这一点:

  1. 使用现有的事件类型
  2. 创造&使用自定义事件类型
  3. 现有活动

    正如gre所提到的,React Native文档在Native UI Components section of Events中解释了这一点。

    他们展示了如何使用以下代码发送事件:

      WritableMap event = Arguments.createMap();
      event.putString("message", "MyMessage");
      ReactContext reactContext = (ReactContext)getContext();
      reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
          getId(), "topChange", event);
    

    有了这个解释:

      

    事件名称topChange映射到onChange回调道具   JavaScript(映射在UIManagerModuleConstants.java)。

    UIManagerModuleConstants.java的实际定义如下:

    "topChange",
        MapBuilder.of(
            "phasedRegistrationNames",
                MapBuilder.of(
                    "bubbled", "onChange", 
                    "captured", "onChangeCapture")))
    

    即。通过在Android代码中使用事件topChange,由于此映射,您可以使用onChangeonChangeCapture在JS中拦截它。

    你可以在那里找到许多其他现有的事件来捎带。

    也有宣称的“直接”事件可能更有用:

    "topLayout", 
        MapBuilder.of("registrationName", "onLayout")
    

    即。 Android事件topLayout映射到JS事件回调onLayout

    I do not understand the difference between the "bubbled" vs "captured" vs "direct" event types

    要在JS中接收活动,请注意文档中引用的3个地点_onChange()

    1. 创建回调方法:_onChange(event: Event) {}

    2. 在构造函数中绑定它:this._onChange = this._onChange.bind(this);

    3. 在创建自定义视图时传递它:return <RCTMyCustomView {...this.props} onChange={this._onChange} />;

    4. 自定义事件

      自定义事件需要在使用之前声明到系统,将Android事件映射到JS事件的方式与上面的React Native完成它们的方式类似。

      这是通过覆盖ViewManager中的以下方法之一来完成的:

      • getExportedCustomBubblingEventTypeConstants()
      • getExportedCustomDirectEventTypeConstants()

      javadoc非常有助于展示映射应该如何工作,但我发现在上面提到的UIManagerModuleConstants中引用React Native代码很有用。

      在那里宣布它之后,就像使用任何其他“现有”事件一样使用它。

      自定义事件实现示例

      我想将点击事件从Android发送到JS,并将其称为onClick。我选择使用“直接”事件。我还选择在Android和JS中使用相同的名称 - 这不是必需的。

      需要修改3个文件:

      ViewManager类

      此代码将Android事件名称“onClick”映射到JS函数“onClick”。

      /**
       * This method maps the sending of the "onClick" event to the JS "onClick" function.
       */
      @Nullable @Override
      public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
          return MapBuilder.<String, Object>builder()
                  .put("onClick",
                          MapBuilder.of("registrationName", "onClick"))
                  .build();
      }
      

      查看课程

      此视图在单击视图时向JS发送事件。这里使用的名称是Android事件名称,它将映射到您在ViewManager类中设置的任何内容。

          // trigger the onPress JS callback
          super.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
                  final Context context = getContext();
                  if (context instanceof ReactContext) {
                      ((ReactContext) context).getJSModule(RCTEventEmitter.class)
                              .receiveEvent(getId(),
                                      "onClick", null);
                  }
              }
          });
      

      instanceof检查是因为这个视图有时会从React上下文之外的本机代码中引用。

      React Native JS组件

      在构造函数中绑定:

        constructor(props) {
          super(props);
          this.onClick = this.onClick.bind(this);
        }
      

      声明实际的回调函数:

        onClick(event: Event) {
          // do something
        }
      

      确保set the callback when rendering your view

        render() {
          return <NativeView onClick={this.onClick} />;
        }
      

      如果这样布局,一切都非常简单,但更精细细节的文档散布在网络上。

答案 1 :(得分:14)

http://facebook.github.io/react-native/docs/native-components-android.html#events

^这显示了如何在UI组件上触发从Java端到JS的事件。

但是对于&#34;自定义事件&#34; (非预定义的事件喜欢onLoad,onScroll等。)您还需要覆盖getExportedCustomDirectEventTypeConstants

这是一个示例,为gl-react-native触发onGLProgress:

(1)定义自定义事件映射:https://github.com/ProjectSeptemberInc/gl-react-native/blob/7d6e83de5a8280d06d47234fe756aa3050e9b9a1/android/src/main/java/com/projectseptember/RNGL/GLCanvasManager.java#L115-L116

(2)将事件从Java发送到JS:https://github.com/ProjectSeptemberInc/gl-react-native/blob/0f64a63fec2281e9d6d3641b9061b771a44fcac8/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java#L839-L849

(3)在JS方面,您可以提供onGLProgress道具回调。