2016-02-22 13 views
16

Ich möchte OpenStreetMap-Kacheln in meiner React Native App auf Android verwenden, also versuche ich die native OSMDroid-UI-Komponente wie beschrieben here. zu wickeln Zum größten Teil funktioniert es gut , aber ich habe Probleme herauszufinden, wie man Ereignisse richtig behandelt, speziell onScroll und onZoom.Benutzerdefinierte Ereignisse in React Native Android native UI-Komponente

Mit OSMDroid haben Sie einen DelayedMapListener eingestellt, um die Ereignisse zu behandeln, was ziemlich einfach ist. Ich habe bestätigt, dass Ereignisse bis zum Punkt, an dem der JS-Code ausgelöst werden sollte, Java-seitig korrekt behandelt werden. Sie lösen jedoch nicht meinen JavaScript-Code aus.

Basierend auf the documentation habe ich die Event-Handler in Java in der createViewInstance Methode meiner Ansicht Manager implementiert:

map.setMapListener(new DelayedMapListener(new MapListener() { 
    public boolean onScroll(ScrollEvent event) { 
     WritableMap eventData = Arguments.createMap(); 

     // Fill in eventData; details not important 

     ReactContext reactContext = (ReactContext)map.getContext(); 
     reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
      map.getId(), 
      "topChange", 
      eventData); 

     return true; 
    } 

    public boolean onZoom(ZoomEvent event) { 
     // Basically the same as above 
    } 
}, 100)); 

Der relevante Teil meines JS-Code ist im Grunde identisch mit dem Code in der Dokumentation verknüpft oben:

class OSMDroidMapView extends Component { 
    constructor(props) { 
     super(props); 
     this._onChange = this._onChange.bind(this); 
    } 

    _onChange(event: Event) { 
     console.log(event); 
     // Handle event data 
    } 

    render() { 
     return <OSMDroidMapView {...this.props} onChange={this._onChange}/> 
    } 
} 

Es gibt keine Fehler oder Zeichen, dass irgendetwas nicht stimmt. Der Java-Event-Handler-Code wird korrekt aufgerufen. Es gibt einfach keine Anzeichen dafür, dass im JS-Code etwas passiert, wenn ein Ereignis eintritt. Weiß jemand, wie man das richtig macht? Ich habe das Gefühl, dass mir hier ein Grundkonzept fehlen muss.

+2

Mögliches Duplikat von [Erstellen einer benutzerdefinierten UI-Komponente für android auf React Native. Wie sende ich Daten an JS?] (Http://stackoverflow.com/questions/34739670/creating-custom-ui-component-for-android-on-react-native-how-to-send-data-to-js) –

+0

Ich habe versucht, [eine umfassende Android -> RN-Event-Lösung zu diesem verwandten Post] (https://stackoverflow.com/a/44207488/383414) zusammenzustellen. –

Antwort

9

Um benutzerdefinierte Ereignisse Javascript senden Sie RCTDeviceEventEmitter verwenden können:

In der Mutterseite:

import com.facebook.react.modules.core.DeviceEventManagerModule; 

... 

public boolean onScroll(ScrollEvent event) { 
    WritableMap eventData = Arguments.createMap(); 

    // Fill in eventData; details not important 

    ReactContext reactContext = (ReactContext)map.getContext(); 
    reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 
       .emit("YouCustomEventName", eventData); 

    return true; 
} 

In Ihrem JS-Modul müssen Sie nur einen Listener registrieren mit DeviceEventEmitter:

class OSMDroidMapView extends Component { 
    constructor(props) { 
     super(props); 
     this._onChange = this._onChange.bind(this); 
    } 

    componentWillMount() { 
     DeviceEventEmitter.addListener('YouCustomEventName', this._onChange); 
    } 

    componentWillUnmount() { 
     DeviceEventEmitter.removeListener('YouCustomEventName', this._onChange); 
    } 

    _onChange(event: Event) { 
     console.log(event); 
     // Handle event data 
    } 

    render() { 
     return <OSMDroidMapView {...this.props} onChange={this._onChange}/> 
    } 
} 

Hoffe es hilft.

+1

Dies löst das Ereignis für jeden aus, der es hört, und ruft keinen Rückruf einer bestimmten Instanz auf. – seemann

+1

'(ReactContext) map.getContext();' was ist das? AndroidStudio wirft einen Fehler in dieser Zeile – Thibaut

+0

Karte ist Ihre benutzerdefinierte Android UI-Komponente hier – Reyske