Creación de componente de interfaz de usuario personalizado para android en React Native. ¿Cómo enviar datos a JS?

Creo la interfaz de usuario. Funciona bien. ¿Pero no sé enviar los datos de Java a JS? En reaccionar modulos nativos puedo usar la devolución de llamada y activar este onClick eventos. Pero en UI no lo sé.

Más sobre lo que necesito. Tengo el componente androide. Envíelo a JS de esta manera createViewInstance(ThemedReactContext reactContext)

Y los usuarios algo cambian dentro del componente. Y estos cambios que veo en la clase java. Necesito enviar estos cambios a JS cuando JS los solicite.

¿Sabes cómo enviar datos desde el componente de la interfaz de usuario a JS? Por favor, dame un ejemplo. Gracias.

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

^ Esto muestra cómo puede activar eventos desde Java a JS en un componente de interfaz de usuario.

Pero para "eventos personalizados" (eventos que no son predefinidos como onLoad, onScroll, etc.), también tendrá que anular getExportedCustomDirectEventTypeConstants .

Aquí hay un ejemplo, activando onGLProgress para gl-react-native:

(1) define la asignación de eventos personalizados: https://github.com/ProjectSeptemberInc/gl-react-native/blob/7d6e83de5a8280d06d47234fe756aa3050e9b9a1/android/src/main/java/com/projectseptember/RNGL/GLCanvasManager.java#L115-L116

(2) envía el evento desde Java a JS: https://github.com/ProjectSeptemberInc/gl-react-native/blob/0f64a63fec2281e9d6d3641b9061b771a44fcac8/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java#L839 -L849

(3) y en el lado JS, puede dar una devolución de llamada de prop de onGLProgress .

Sobre la base de la respuesta de gre que me puso en el camino correcto, pero todavía me dejó con mucho trabajo por hacer , voy a tratar de explicar algunos de los detalles que faltan.

Hay dos formas básicas de hacerlo:

  1. Utilizar un tipo de evento existente
  2. Crear y utilizar un tipo de evento personalizado

Eventos existentes

Como se mencionó anteriormente, los documentos React Native explican esto en la sección de Eventos Nativos de la UI .

Muestran cómo enviar el evento utilizando el siguiente código:

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

Con esta explicación:

El nombre del evento topChange corresponde al objeto de onChange llamada onChange en JavaScript (las asignaciones están en UIManagerModuleConstants.java ).

La definición actual de UIManagerModuleConstants.java parece a esto:

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

Es decir, utilizando el evento topChange en el código de Android, puede interceptarlo en JS con onChange o onChangeCapture debido a esta asignación.

Usted puede encontrar muchos otros eventos existentes declarados allí para piggy-back.

También hay eventos "directos" declarados en que pueden ser más útiles:

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

Es decir, el evento de Android topLayout asigna a JS evento de devolución de llamada onLayout

( No entiendo la diferencia entre los tipos de eventos "burbujeados" vs "capturados" vs "directos" )

Para recibir el evento en JS, tome nota de los 3 lugares _onChange() se hace referencia en los documentos:

  1. Cree el método de devolución de llamada: _onChange(event: Event) {}

  2. this._onChange = this._onChange.bind(this); en el constructor: this._onChange = this._onChange.bind(this);

  3. return <RCTMyCustomView {...this.props} onChange={this._onChange} />; al crear su vista personalizada: return <RCTMyCustomView {...this.props} onChange={this._onChange} />;


Eventos personalizados

Los eventos personalizados deben declararse al sistema antes de que puedan utilizarse, asignando eventos de Android a eventos de JS de manera similar a cómo se realizan mediante React Native anterior.

Esto se hace reemplazando uno de los siguientes métodos en su ViewManager :

  • getExportedCustomBubblingEventTypeConstants()
  • getExportedCustomDirectEventTypeConstants()

El javadoc es muy útil para mostrar cómo debería funcionar el mapeo, pero me pareció útil hacer referencia al código React Native en UIManagerModuleConstants mencionado anteriormente.

Una vez que se declara allí, se utiliza como lo haría con cualquier otro evento "existente".


Ejemplo de implementación de eventos personalizados

Quería enviar el evento de clic de Android hasta JS, y llamarlo onClick . Elegí usar un evento "directo" para esto. También opté por usar el mismo nombre en Android y en JS – esto no es necesario.

3 archivos necesitan ser modificados:

Clase ViewManager

Este código asigna el nombre del evento de Android "onClick" a la función 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(); } 

Ver clase

Este código envía un evento al JS cuando se hace clic en la vista. El nombre utilizado aquí es el nombre del evento de Android, que se asignará a lo que haya establecido anteriormente en la clase 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); } } }); 

La comprobación de instanceof está allí porque a veces esta vista se hace referencia desde el código nativo, fuera del contexto React.

Reaccionar componente JS nativo

Vincular en constructor:

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

Declare la función de devolución de llamada real:

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

Asegúrese de configurar la devolución de llamada al procesar su vista :

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

Todo muy simple cuando se presenta como este, pero la documentación de los detalles más finos se dispersa alrededor de la web.

  • Uso de sensores en Android con React Native
  • WebStorm reactiva-depuración nativa no funciona
  • Reaccionar nativo TextInput borde no funciona
  • Cómo configurar la pantalla de bienvenida para reaccionar con Android nativo
  • Reaccionar-nativo personalizar la barra de herramientas de Android
  • Servicio de fondo en el reactivo-androide nativo
  • Com.android.ddmlib.InstallException: No se pudo instalar todo
  • Ble-obtener el código de error - 128 al escribir a caracteres
  • Grueso borde / borde negro alrededor de una aplicación React Native en Android
  • React Native - java.lang.RuntimeException: ubicación del SDK no encontrada. Defina la ubicación con sdk.dir en local.properties
  • ¿Reactiva Nativo Realmente Soporta Fragmentos Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.