RCTVideoPlayer
假定原生组件是一个View,在ios端封装该View
1.1 导入头文件 <React/RCTComponent.h>
1.2 导入原生组件头文件,本例子是 "TTAVPlayer.h"
1.3 引入js层传入的block 事件属性
RCTVideoPlayer.h
#import#import
#import "TTAVPlayer.h"
@interface RCTVideoPlayer : TTAVPlayerView
@property (nonatomic, copy) RCTBubblingEventBlock onBack;
@property (nonatomic, copy) RCTBubblingEventBlock onPlayError;
@property (nonatomic, copy) RCTBubblingEventBlock onPause;
@property (nonatomic, copy) RCTBubblingEventBlock onEnd;
@property (nonatomic, copy) RCTBubblingEventBlock onPlay;
@end
2.1 导入"RCTVideoPlayerManager.h"和<React/UIView+React.h>
2.2 init该View,并初始化js层设置的属性
2.3 如果该View有设置代理,实现代理方法并向js层发通知以执行额外操作
#import "RCTVideoPlayer.h"#import "RCTVideoPlayerManager.h"#import@implementation RCTVideoPlayer
- (id)init
{
self = [super initWithFrame:CGRectZero withViewMode:TTAVPlayerViewNormalMode];
[super setDelegate:self];
return self;
}
- (void)setSrc:(NSString *)src {
NSLog(@"set src -> %@", src);
[super setVideoUrl:src];
}
- (void)backButtonGetTap:(BOOL)isFullScreen {
if(self.onBack && !isFullScreen){
self.onBack(@{@"isFullScreen": @(isFullScreen)});
}
}
RCTVideoPlayerManager
1.1 继承RCTViewManager
#import<React/RCTViewManager.h>
#import "TTAVPlayer.h"
@interface RCTVideoPlayerManager : RCTViewManager
@end
2.1 声明该class属性共享
RCT_EXPORT_MODULE();
RCT_EXPORT_VIEW_PROPERTY(placeholderImage, NSString) 值属性
RCT_EXPORT_VIEW_PROPERTY(onPlay, RCTBubblingEventBlock) 事件属性
事件属性与View中的事件属性相对应,实现原生向js层通信
2.2 初始化view(每个manager都有一个view)
- (UIView *)view
{ return [[RCTVideoPlayer alloc] init]; }
2.3 导出方法给js层调用
RCT_EXPORT_METHOD(play: (nonnull NSNumber *)reactTag) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary*viewRegistry) {
UIView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTVideoPlayer class]]) {
RCTLog(@"expecting UIView, got: %@", view);
}
else {
RCTVideoPlayer *player = (RCTVideoPlayer *)view;
[player play];
}
}];
}
在js主动要求更新原生UI层的事件中,需要注意两点,
1是使用[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary*viewRegistry) {}]来更新UI,该方法需要导入<React/RCTUIManager.h>
2是该方法需要特定的线程执行,如下
- (dispatch_queue_t)methodQueue
{
return self.bridge.uiManager.methodQueue;
}
js
导出UI组件
import { requireNativeComponent } from'react-native';
class VideoPlayer extends Component {
render() {
return <RCTVideoref="native" {...this.props} onPlayError={this.onPlayError}/>;
}
}
constRCTVideo =requireNativeComponent('RCTVideoPlayer',VideoPlayer);
export defaultVideoPlayer;
需要注意
1.1 class类似一般的react class
1.2 constructor(...args) {}
1.3 staticpropTypes= {
...View.propTypes,
src: PropTypes.string.isRequired,
onPlayError: PropTypes.func
};
1.4 js层调用原生方法
play= (url,isCache,title) => {
if(Platform.OS =='android') {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this),
UIManager.RCTVideoPlayer.Commands.play,
[url,isCache,title]
);
}else{
const{ VideoPlayerManager } = NativeModules;
VideoPlayerManager.play(ReactNative.findNodeHandle(this));
}
};
网友评论