2016-02-22 20 views
16

私はAndroidのリアクションネイティブアプリでOpenStreetMapタイルを使用したいので、OSMDroidのネイティブUIコンポーネントをラップしようとしていますhere.ほとんどの場合、うまくいきますしかし、イベントを正しく処理する方法、具体的にはonScrollonZoomを調べることに問題があります。リアクションネイティブAndroidネイティブUIコンポーネントのカスタムイベント

OSMDroidでは、イベントを処理するためにDelayedMapListenerを設定します。これはかなり簡単です。 JSコードがトリガーされるべきポイントまでイベントが正しくJava側で処理されていることを確認しました。ただし、JavaScriptコードをトリガーしていません。

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)); 

私のJSコードの関連部分がリンクドキュメント内のコードと基本的には同じである:

the documentationに基づいて、私は私のビューマネージャのcreateViewInstance方法でJavaでのイベントハンドラを実装しました上:

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}/> 
    } 
} 

エラーか何かが間違っているという兆候はありません。 Javaイベントハンドラコードが正しく呼び出されます。イベントが発生したときにJSコードに何も起こっているという兆候はありません。誰でもこれを正しく行う方法を知っていますか?私はここでいくつかの基本コンセプトを欠いているように感じる。

ネイティブ側では:あなたがRCTDeviceEventEmitterを使用することができますJavaScriptにカスタムイベントを送信するために

+2

「React NativeでandroidのカスタムUIコンポーネントを作成する」の可能な複製。どのようにJSにデータを送信する?](http://stackoverflow.com/questions/34739670/creating-custom-ui-component-for-android-on-react-native-how-to-send-data-to-js ) –

+0

私は[関連する投稿に包括的なAndroid - > RNイベントソリューション](https://stackoverflow.com/a/44207488/383414)をまとめようとしました。 –

答えて

9

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; 
} 

あなたのJSモジュール内部であなただけの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}/> 
    } 
} 

希望します。

+1

これは、特定のインスタンスのコールバックを呼び出さずに、リッスンしているすべてのユーザーに対してイベントをトリガーします。 – seemann

+1

'(ReactContext)map.getContext();'これは何ですか? AndroidStudioがこの行にエラーを投げます – Thibaut

+0

地図はあなたのカスタムAndroid UIコンポーネントです – Reyske

関連する問題