React Native 如何阻止未解锁的视频被用户播放
实现思路
- 新增未解锁视频的全屏遮罩拦截交互:你当前只渲染了锁图标,没有覆盖整个视频区域的拦截层,导致空白区域仍可触发视频原生控件的点击事件。可以在未解锁状态下渲染一个铺满整个Video组件的View层,设置
pointerEvents="auto"属性拦截所有触摸事件,也可以额外绑定点击事件弹出「请先观看前置视频」的提示。 - 动态控制Video组件的播放权限:未解锁时强制禁用播放能力,避免用户通过其他方式触发播放:
- 未解锁时将
paused属性设为true,强制视频暂停 - 未解锁时将
useNativeControls属性设为false,直接隐藏原生播放控制栏,从根源消除点击触发播放的入口
- 未解锁时将
- 完善前置视频完成后的解锁逻辑:在前置视频的
onPlaybackStatusUpdate回调中判断播放状态,如果是循环播放的视频可以判断播放进度超过总时长的95%即算完成,非循环播放可以直接判断playbackStatus.didJustFinish字段为true,满足条件时修改对应后续视频的解锁状态变量,同时可以将进度同步存储到本地或后端,实现用户退出后重进仍保留解锁状态。
优化后的代码示例
<View style={styles.videoRow}> {/* 第一个视频 */} <View style={styles.videoWrapper}> <Video style={styles.image} source={{uri: 'https://firebasestorage.googleapis.com/v0/b/roundpower-88ef9.appspot.com/o/BootyAbsPower%2FTuto%2013.mp4?alt=media&token=da011245-fce2-4796-a78b-3abc518c73ef'}} // 动态控制控制栏显隐 useNativeControls={debloque3} resizeMode="contain" isLooping // 未解锁时强制暂停 paused={!debloque3} onPlaybackStatusUpdate={(playbackStatus) => onPlaybackStatusUpdate3(playbackStatus)} /> {!debloque3 ? <View style={styles.lockMask}> <FontAwesome5 name="lock" size={40} color="white" style={styles.icon}/> </View> : null} </View> {/* 第二个视频 */} <View style={styles.videoWrapper}> <Video style={styles.image} source={{uri: 'https://firebasestorage.googleapis.com/v0/b/roundpower-88ef9.appspot.com/o/BootyAbsPower%2FTuto%2014.mp4?alt=media&token=cd3d12be-05fd-4fc4-91d9-cd518faf14ce'}} useNativeControls={debloque4} resizeMode="contain" isLooping paused={!debloque4} onPlaybackStatusUpdate={(playbackStatus) => onPlaybackStatusUpdate4(playbackStatus)} /> {!debloque4 ? <View style={styles.lockMask}> <FontAwesome5 name="lock" size={40} color="white" style={styles.icon}/> </View> : null} </View> </View>
新增对应的样式配置:
const styles = StyleSheet.create({ // 保留原有样式,新增以下配置 videoWrapper: { position: 'relative' }, lockMask: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, // 可选添加半透明背景,更直观提示视频未解锁 backgroundColor: 'rgba(0,0,0,0.3)', justifyContent: 'center', alignItems: 'center', // 拦截所有触摸事件 pointerEvents: 'auto' } })
解锁逻辑参考(以第一个视频完成后解锁第二个为例):
const onPlaybackStatusUpdate3 = (playbackStatus) => { // 保留原有逻辑,新增完成判断 if (playbackStatus.isLoaded && playbackStatus.positionMillis >= playbackStatus.durationMillis * 0.95) { // 解锁第二个视频 setDebloque4(true) } }
内容的提问来源于stack exchange,提问作者Hadrien Jaubert
相关产品推荐
相关产品推荐

