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)
- Reaccionar La compilación androide nativa falló. SDK ubicación no encontrada
- Com.android.ddmlib.InstallException: No se pudo establecer la sesión reaccionar-nativa
- Reaccionar Nativo Android Pantalla de bienvenida
- Error: <identifier> esperado usando y
- Android reaccionar nativo no pudo obtener lotes puente
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.
- Eventos personalizados en React Native Componente nativo de la interfaz de usuario de Android
- React-Native El nivel de API Android más bajo
- ¿Es posible crear un widget de escritorio con react-native?
- ¿Cuál es el equivalente de ActionSheetIOS en Android?
- Utilizando RxJava para la validación de inicio de sesión de correo electrónico, un observable está emitiendo dos veces
- ¿Cuál es la forma correcta de agregar una sola vista React Native a una aplicación Android existente?
- "Obtener el paquete JS" Monstruosamente lento
- Running React Proyectos nativos presentes en github en dispositivos Android
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:
- Utilizar un tipo de evento existente
- 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 deonChange
llamadaonChange
en JavaScript (las asignaciones están enUIManagerModuleConstants.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:
-
Cree el método de devolución de llamada:
_onChange(event: Event) {}
-
this._onChange = this._onChange.bind(this);
en el constructor:this._onChange = this._onChange.bind(this);
-
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.
- Android.support.v4.app.FragmentPagerAdapter no se puede aplicar a android.app.FragmentManager
- ¿Es posible en Android para findView por id de cadena?