doc
doc copied to clipboard
如何开发一个react-native android组件
首先按照官网文档的步骤来做: 1. Create the ViewManager subclass 2. Implement method createViewInstance 3. Expose view property setters using @ReactProp (or @ReactPropGroup) annotation 4. Register the ViewManager 5. Implement the JavaScript module 在native组件只有设置属性的时很按照上面的来做很容易就搞定了,但是实际开发中既然是组件,肯定会有相应的事件监听处理和外部调用的方法。
事件的处理:
对于Event的处理也有官方文档 ,不过对应的.JS文件并不健全,可以参考我写过的react-native-wheel的实现: WheelViewManager.java:
@ReactProp(name = "onItemChange", defaultBoolean = true)
public void setOnItemChange(final LoopView view, Boolean value) {
view.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
WritableMap event = Arguments.createMap();
event.putInt("index", index);
ReactContext reactContext = (ReactContext) view.getContext();
reactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(view.getId(), "topChange", event);
}
});
}
var iface = {
name: 'RCTWheelView',
propTypes: {
onItemChange: PropTypes.func,
values: PropTypes.array,
isLoop: PropTypes.bool,
selectedIndex: PropTypes.number,
textSize: PropTypes.number,
},
};
var MyWheelView = React.createClass({
handleOnChange(event){
if(this.props.onItemChange){
this.props.onItemChange(event.nativeEvent.index);
}
},
render(){
return <NativeWheelView {...this.props} onChange = {this.handleOnChange} />;
}
});
方法的处理:
React-Native的官方文档并没有对应的文档说明,找了好几天都没有找到相应的处理,最终无奈在react-native的github提交了一个issues,然后在@brentvatne的帮助下得以解决 参考以下内容: ReactViewPagerManager.java:
@Override
public Map<String,Integer> getCommandsMap() {
return MapBuilder.of(
"setPage",
COMMAND_SET_PAGE,
"setPageWithoutAnimation",
COMMAND_SET_PAGE_WITHOUT_ANIMATION);
}
@Override
public void receiveCommand(
ReactViewPager viewPager,
int commandType,
@Nullable ReadableArray args) {
Assertions.assertNotNull(viewPager);
Assertions.assertNotNull(args);
switch (commandType) {
case COMMAND_SET_PAGE: {
viewPager.setCurrentItemFromJs(args.getInt(0), true);
return;
}
case COMMAND_SET_PAGE_WITHOUT_ANIMATION: {
viewPager.setCurrentItemFromJs(args.getInt(0), false);
return;
}
default:
throw new IllegalArgumentException(String.format(
"Unsupported command %d received by %s.",
commandType,
getClass().getSimpleName()));
}
}
/**
* A helper function to scroll to a specific page in the ViewPager.
* The transition between pages will be animated.
*/
setPage: function(selectedPage: number) {
UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this),
UIManager.AndroidViewPager.Commands.setPage,
[selectedPage],
);
},
/**
* A helper function to scroll to a specific page in the ViewPager.
* The transition between pages will be *not* be animated.
*/
setPageWithoutAnimation: function(selectedPage: number) {
UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this),
UIManager.AndroidViewPager.Commands.setPageWithoutAnimation,
[selectedPage],
);
},
最后就是就像@brentvatne说的 “This isn't the best place to ask this kind of question, as the comment above suggests, you should try StackOverflow.” 提问问题最好去StackOverflow ,再次感谢@brentvatne的回答。
:dancer:
对于方法的处理,我也写了一个例子
@Override
public Map<String,Integer> getCommandsMap() {
return MapBuilder.of(
"previous",
COMMAND_PREVIOUS,
"next",
COMMAND_NEXT);
}
@Override
public void receiveCommand(LoopView root, int commandId, ReadableArray args) {
switch (commandId) {
case COMMAND_PREVIOUS: {
root.previous();
return;
}
case COMMAND_NEXT: {
root.next();
return;
}
default:
throw new IllegalArgumentException(String.format(
"Unsupported command %d received by %s.",
commandId,
getClass().getSimpleName()));
}
}
previous: function(){
UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this.refs.wheel),
UIManager.RCTWheelView.Commands.previous,
null,
);
},
next: function(){
UIManager.dispatchViewManagerCommand(
React.findNodeHandle(this.refs.wheel),
UIManager.RCTWheelView.Commands.next,
null,
);
},
使用方法
var AwesomeProject = React.createClass({
previous(){
this.refs.wheel.previous();
},
next(){
this.refs.wheel.next();
},
finish(){
ToastAndroid.show('select item : ' + wheelData[currentIndex] ,ToastAndroid.LONG);
},
onItemChange(index){
currentIndex = index;
},
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome} onPress={this.previous} >
上一个
</Text>
<Text style={styles.instructions} onPress={this.next} >
下一个
</Text>
<Text style={styles.instructions} onPress={this.finish} >
完成
</Text>
<WheelView
style={styles.wheelview}
onItemChange={this.onItemChange}
values={wheelData}
isLoop={false}
selectedIndex={0}
textSize={20}
ref='wheel'
/>
</View>
);
}
});