在官方文档的原生UI模块章节: (IOS Android),我们可以学会如何导出原生UI组件,如何导出prop,如何设置事件回调等等,但是缺少一个内容,那就是如何导出方法。举个例子,我们在使用ScrollView组件时,如果想让它滚动,需要先获取到它的ref,然后调用它的scrollTo方法,这就是一个原生UI导出的方法。通过阅读源代码,我找到了如何实现的方案,这里介绍一下。
iOS
iOS端直接在继承自RCTViewManager的类中提供接口。照着下面的模板写就可以了,将获取到的view转换成实际的View然后调用方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #import <React/RCTUIManager.h>
RCT_EXPORT_METHOD(scrollToIndexWithOffset:(nonnull NSNumber *)reactTag index:(NSInteger)index offset:(CGFloat)offset animated:(BOOL)animated) { [self.bridge.uiManager addUIBlock: ^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry){ UIView *view = viewRegistry[reactTag]; if([view class] == MyTableView.class) { MyTableView* table = (MyTableView*)view; [table scrollToIndex:index offset:offset animated:animated]; }else { RCTLogError(@"tried to call scrollToIndexWithOffset on %@ " "with tag #%@", view, reactTag); } }]; }
|
Android
android端处理方式不一样,我们在继承SimpleViewManager或者ViewGroupManager的类中需要重写getCommandsMap方法,提供暴露到js层的command命令。然后重写receiveCommand方法,通过commandId判断js层是想要调用什么方法,然后把参数转换好之后进行调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Override public @javax.annotation.Nullable Map<String, Integer> getCommandsMap() { return MapBuilder.of( "scrollToIndexWithOffset", COMMAND_SCROLL_TO); }
@Override public void receiveCommand( MyView scrollView, int commandId, @javax.annotation.Nullable ReadableArray args) { if(commandId == COMMAND_SCROLL_TO) { int index = Math.round(PixelUtil.toPixelFromDIP(args.getInt(0))); float offset = Math.round(PixelUtil.toPixelFromDIP(args.getDouble(1))); boolean animated = args.getBoolean(2); scrollView.scrollTo(index, offset, animated); } }
|
javaScript
在js层调用的代码为
1 2 3 4 5 6 7
| scrollToIndexWithOffset (index, offset, animated) { UIManager.dispatchViewManagerCommand( ReactNative.findNodeHandle(this.tableRef), UIManager.MyTableView.Commands.scrollToIndexWithOffset, [index, offset, animated] ) }
|
这里的tableRef就是原生组件在js层使用ref获取到的。scrollToIndexWithOffset对应着原生暴露的方法名(iOS为RCT_EXPORT_METHOD之后的方法名,Android为getCommandsMap暴露的方法名),后面三个参数数组一次是原生方法接受的参数。
这就是原生组件封装方法到js层的全部流程了,这是基本的操作,实际开发中再注意下例如参数类型转换等小问题即可。
Ursprünglicher Link: http://yangguang1029.github.io/2018/09/27/rn-native-view-method/
Copyright-Erklärung: 转载请注明出处.