2016-02-22 26 views
16

Tôi muốn sử dụng các ô OpenStreetMap trong ứng dụng React Native trên Android, vì vậy tôi đang cố gắng bọc thành phần giao diện người dùng gốc OSMDroid như được mô tả here.. , nhưng tôi đang gặp khó khăn trong việc tìm ra cách xử lý đúng sự kiện, cụ thể là onScrollonZoom.Sự kiện tùy chỉnh trong thành phần giao diện người dùng gốc Native React Native

Với OSMDroid, bạn đặt DelayedMapListener để xử lý các sự kiện, điều này khá đơn giản. Tôi đã xác nhận rằng các sự kiện đang được xử lý một cách chính xác bên Java cho đến khi mã JS được kích hoạt. Tuy nhiên, chúng không kích hoạt mã JavaScript của tôi.

Dựa trên the documentation, tôi đã thực hiện các xử lý sự kiện trong Java trong phương pháp createViewInstance của người quản lý điểm của tôi:

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

Phần liên quan của mã JS của tôi về cơ bản là giống với mã trong tài liệu liên quan ở trên:

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

Không có lỗi hoặc bất kỳ dấu hiệu nào sai. Mã trình xử lý sự kiện Java được gọi chính xác. Không có dấu hiệu của bất cứ điều gì xảy ra trong mã JS khi một sự kiện xảy ra. Có ai biết làm thế nào để làm điều này một cách chính xác? Tôi cảm thấy như tôi phải bỏ lỡ một số khái niệm cơ bản ở đây.

+2

Bản sao có thể có của [Tạo thành phần giao diện người dùng tùy chỉnh cho android trên React Native. Cách gửi dữ liệu đến JS?] (Http://stackoverflow.com/questions/34739670/creating-custom-ui-component-for-android-on-react-native-how-to-send-data-to-js) –

+0

Tôi đã cố gắng để cùng nhau [một giải pháp toàn diện Android -> RN sự kiện trên bài liên quan đó] (https://stackoverflow.com/a/44207488/383414). –

Trả lời

9

Để gửi các sự kiện tùy chỉnh để javascript bạn có thể sử dụng RCTDeviceEventEmitter:

Ở phía bên Quê quán:

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

Bên trong mô-đun JS của bạn, bạn chỉ cần đăng ký một người biết lắng nghe bằng 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}/> 
    } 
} 

Hy vọng điều đó sẽ hữu ích.

+1

Điều này sẽ kích hoạt sự kiện cho tất cả mọi người mà os nghe nó, không gọi một cuộc gọi lại của một trường hợp cụ thể. – seemann

+1

'(ReactContext) map.getContext(); 'đây là gì? AndroidStudio ném lỗi trên dòng này – Thibaut

+0

bản đồ là thành phần giao diện người dùng Android tùy chỉnh của bạn tại đây – Reyske

Các vấn đề liên quan