Пользовательские события в React Собственный компонент пользовательского интерфейса Android
Я хотел бы использовать плитки OpenStreetMap в своем приложении React Native на Android, поэтому я пытаюсь обернуть собственный компонент пользовательского интерфейса OSMDroid, как описано здесь. По большей части он работает нормально, но мне трудно понять, как правильно обрабатывать события, в частности onScroll
и onZoom
.
В OSMDroid вы устанавливаете DelayedMapListener для обработки событий, что довольно просто. Я подтвердил, что события обрабатываются правильно со стороны Java вплоть до момента, когда должен запускаться JS-код. Однако они не запускают мой код JavaScript.
Основываясь на документации, я реализовал обработчики событий в Java в методе createViewInstance
моего диспетчера просмотров:
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-кода в основном идентична коду в приведенной выше документации:
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 ничего не происходит. Кто-нибудь знает, как это сделать правильно? Я чувствую, что мне, должно быть, недостает базовой концепции.
Ответы
Ответ 1
Чтобы отправить пользовательские события в Javascript, вы можете использовать RCTDeviceEventEmitter:
В родной части:
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}/>
}
}
Надеюсь, это поможет.