React Native 类组件自定义video播放/暂停按钮触发失效问题
解决方案
问题根因
- 常用的
react-native-video组件本身不支持onPress/onTouchStart等直接绑定的触摸事件,事件仅会被组件内部消费不会向外传递,所以直接绑定的点击逻辑不会触发 - 原有代码中自定义播放图标仅在
paused=true时渲染,播放状态下图标消失无法点击触发切换 - Android端叠加的封面图默认会拦截所有下层的触摸事件
- 列表场景下使用全局统一的
paused状态会导致所有视频同步切换状态,不符合单视频控制的需求
修正后完整实现
状态定义部分
列表场景建议存储当前播放的视频ID做状态隔离,单视频场景可直接沿用原paused状态:
constructor(props) { super(props); this.state = { data: [], // 视频列表源数据 isLoading: false, activePlayId: null // 存储当前正在播放的视频id,为null时所有视频暂停 }; }
状态切换方法
updatePause = (itemId) => { this.setState(prevState => ({ // 点击当前播放的视频则暂停,否则切换为点击的视频播放 activePlayId: prevState.activePlayId === itemId ? null : itemId })) }
列表渲染部分
// 先从react-native引入TouchableWithoutFeedback组件 const renderItem = ({ item }) => { // 单条视频的暂停状态:当前id等于activePlayId时为播放,否则暂停 const isPaused = this.state.activePlayId !== item.id; return ( {/* 外层套可触摸组件绑定点击事件,所有子元素的点击都会触发回调 */} <TouchableWithoutFeedback onPress={() => this.updatePause(item.id)}> <View style={styles.item}> <Text style={styles.title}>{item.title}</Text> <Text numberOfLines={3} style={styles.description}>{item.description}</Text> {/* 去掉paused判断,图标常驻显示 */} <CustomIcon style={styles.playButton} name={isPaused ? "play" : "pause"} size={85} color="#E5E5E5" /> <Video style={styles.player} source={{ uri: item.url }} repeat paused={isPaused} resizeMode="cover" /> {Platform.OS === 'android' && isPaused && ( <Image source={{ uri: item.poster}} style={styles.posterPlayer} /> )} </View> </TouchableWithoutFeedback> ) };
注意事项
- 如果需要支持仅点击图标响应切换,可以把图标单独包裹在
TouchableOpacity中绑定事件,不用套在最外层 - 如果是单视频控制场景,删除
activePlayId相关逻辑,直接操作原paused状态即可
内容的提问来源于stack exchange,提问作者principemestizo3
相关产品推荐
相关产品推荐

