-
Notifications
You must be signed in to change notification settings - Fork 1
SimpleViewManager
import com.facebook.react.uimanager.SimpleViewManager
抽象方法
返回此视图管理类的名称。这将在JavaScript端requireNativeComponent()
中引用。
同ReactContextBaseJavaModule#getName
Java端
@Override
public String getName(){
return "RCTImageView";
}
JavaScript端
import { requireNativeComponent } from 'react-native';
const RKImage = requireNativeComponent('RCTImageView');
抽象方法
视图在createViewInstance
中创建,且应当把自己初始化为默认的状态。所有属性的设置都通过后续的updateView
来进行。
- 例子: 返回一个
ReactImageView
实例
com.facebook.react.views.image.ReactImageManager
@Override
public ReactImageView createViewInstance(ThemedReactContext context) {
return new ReactImageView(context, ...);
}
当自定义原生组件被卸载(Unmount)时调用,常用于一些需要额外清理的(例如关闭摄像机、停止播放视频)。
@Override
public void onDropViewInstance(Video view) {
view.stop();
}
子类可以重写此方法,以在给定的View上安装自定义事件发射器(EventDispatcher
)。 如果您的视图需要向JS发送基本触摸事件以外的事件( com.facebook.react.uimanager.events.Event
)(例如滚动事件),则可能需要覆盖此方法。
@Override
protected void addEventEmitters(ThemedReactContext reactContext, T view) {
/**
* 实例化与(泛型T指)自定义UIManagerModule 关联的dispatcher
* **/
EventDispatcher dispatcher = reactContext.getNativeModule(T.class).getEventDispatcher();
// 派发事件,与getExportedCustomDirectEventTypeConstants相对应
dispatcher.dispatchEvent(new UIEvent(view.getId()))
}
- 例子:
Modal
直接调度onRequestClose()
事件
Java端
@Override
protected void addEventEmitters(ThemedReactContext reactContext, final ReactModalHostView view) {
final EventDispatcher dispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
//onRequestClose listner
view.setOnRequestCloseListener(new ReactModalHostView.OnRequestCloseListener() {
@Override
public void onRequestClose(DialogInterface dialog) {
dispatcher.dispatchEvent(new RequestCloseEvent(view.getId()));
}
});
//onShow listner
view.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
dispatcher.dispatchEvent(new ShowEvent(view.getId()));
}
});
}
再配合getExportedCustomDirectEventTypeConstants为其注册直接调度类的事件
JavaScript端
import { requireNativeComponent } from 'react-native';
const Modal = requireNativeComponent('RCTModalHostView');
render(){
return (
<Modal
onRequestClose={this.props.onRequestClose}
onShow={this.props.onShow}
>
...
</Modal>
)}
在当前更新事务所有属性都已更新时触发回调(所有@ReactProp,如自定义属性值被改变或者继承的style
被改变后)。如果要重写此方法,你应该调用super.onAfterUpdateTransaction
因为ViewManager父类可能正在执行这个回调。
@Override
protected void onAfterUpdateTransaction(SignaturePadView view) {
super.onAfterUpdateTransaction(view);
}
在View还未layout 时就会触发,所以加个保护
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onAfterUpdateTransaction(SignaturePadView view) {
if(view.isLayoutDirectionResolved())
// ...
}
如果<T extends ViewManager>
子类希望通过UIManagerModule#dispatchViewManagerCommand
接收命令,应该重写此方法。返回命令名与随后在receiveCommand
方法中使用的id
(通过findNodeHandle获取特定ViewManager的ViewTag)之间的映射,以达到为该特定ViewManager子类发送命令。
Java端
public static final int COMMAND_SCROLL_TO = 1;
public static final int COMMAND_SCROLL_TO_END = 2;
@Override
public Map<String,Integer> getCommandsMap() {
Map<String, Integer> map = new HashMap<>();
map.put("scrollTo", COMMAND_SCROLL_TO);
map.put("scrollToEnd", COMMAND_SCROLL_TO_END);
return map;
}
JavaScript端
第一步:findNodeHandle(ref)
直接操作获取ViewTag
import { findNodeHandle } from 'react-native'
<ScrollView
ref={ref => {
this._handle = findNodeHandle(ref)
}}>
>
</ScrollView>
第二步:dispatchViewManagerCommand
发送命令
import { UIManager } from 'react-native'
UIManager.dispatchViewManagerCommand(
this._handle, // 告诉原生需要定位到的组件
UIManager.RCTScrollView.Commands.scrollTo, // 原生getCommandsMap提前定义好的命令
[x, y, animated], // 携带的参数ReadableArray
)
使用此方法接收来自UIManagerModule#dispatchViewManagerCommand
的命令。
Java端
@Override
public void receiveCommand(
ScrollViewManager view,
int commandType,
@Nullable ReadableArray args) {
switch (commandType) {
case COMMAND_SCROLL_TO:{
view.scrollTo(
(int)args.getDouble(0),
(int)args.getDouble(1),
args.getBoolean(2));
return; // 结束switch判断
}
case COMMAND_SCROLL_TO_END:{
boolean animated = args.getBoolean(0);
view.scrollToEnd(animated);
return;
}
default:
throw new IllegalArgumentException(String.format(
"Unsupported command %d received by %s.",
commandType,
getClass().getSimpleName()));
}
}
Q:和Module的@ReactMethod有什么区别❓
A:Command模式只负责发送事件,不能使用callback和promise,即无任何返回值
返回传递给JS的配置数据映射,该映射定义了可以放置在本机视图上的合格事件。 这应该返回冒泡的直接分派事件类型,并指定使用哪种名称来订阅任何一种形式(冒泡/捕获)。
同getExportedCustomDirectEventTypeConstants
,但应通过冒泡触发事件。
返回格式应遵循下面的格式:
{
"onTwirl": {
"phasedRegistrationNames": {
"bubbled": "onTwirl",
"captured": "onTwirlCaptured"
}
}
}
返回传递给JS的配置数据映射(Map),该映射键(key)为原生视图的事件<T extends com.facebook.react.uimanager.events.Event>类
常量,值(value)为注册给JS的MapBuilder.of("registrationName"," -自定义事件- ")
。
原生事件应返回非冒泡(non-bubbling)的直接调度(directly-dispatched)事件类型。常和addEventEmitters
配合使用。
返回格式应遵循下面的格式:
{
"onTwirl": {
"registrationName": "onTwirl"
}
}
- 例如:
向JS端注册Modal的
onRequestClose
、onShow
直接调度类监听事件。
import com.facebook.react.common.MapBuilder;
@Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
return MapBuilder.<String, Object>builder()
.put(RequestCloseEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRequestClose"))
.put(ShowEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShow"))
.build();
}
返回JavaScript可访问的特定常量的映射对象。这些常量是可通过UIManager.<ViewName>.Constants
进行访问。
@Override
public Map<String, Object> getExportedViewConstants(){
final Map<String, Object> constants = new HashMap<>();
constants.put("APPID", "1234567890");
return constants;
}