标签:播放器 index 仿抖 onViewableItemsChanged 音视频 React item state isPause
实现思路:
视频播放采用react-native-video,非常好用的视频播放库,列表整体采用FlatList实现,每一个item都占一整屏(flex设为1),再给FlatList设定pagingEnabled属性(滑动滚动一屏),viewabilityConfig中设定可见区域滑动的阈值。
效果图:
实现过程:
我的代码使用了react-native-ui-lib库,所以直接复制控件的属性会报错,把写在标签里的style样式写进对应控件的style={{}}中。
react-native-video的具体导入和使用方法 就自己去github看一下把,文档说明非常详细
constructor(props){
super(props)
this.state={
data:tempCollect,//我模拟的数据 这个就自行找一些视频url就好
isPause:true, //控制播放器是否播放,下面的代码有解释一个列表只需要一个state控制,而不用数组
current:0,//表示当前item的索引,通过这个实现一个state控制全部的播放器
}
this.renderItem = this.renderItem.bind(this)
this._onViewableItemsChanged = this._onViewableItemsChanged.bind(this)
}
render方法代码:
render(){
const VIEWABILITY_CONFIG = {
viewAreaCoveragePercentThreshold: 80,//item滑动80%部分才会到下一个
};
return(
<View>
<FlatList
data={videoUrl}
renderItem={this.renderItem}
horizontal={false}
pagingEnabled={true}
getItemLayout={(data, index) => {
return {length: height, offset: height * index, index}
}}
keyExtractor={(item, index) => index.toString()}
viewabilityConfig={VIEWABILITY_CONFIG}
showsHorizontalScrollIndicator={false}
onViewableItemsChanged={this._onViewableItemsChanged}
/>
{/*顶部 关闭、搜索 按钮*/}
<View style={{position:'absolute',width:width,}}>
<View row style={{justifyContent: 'space-between',alignItems: 'center',width:width,padding:20}} >
<TouchableOpacity onPress={()=>{
this.props.navigation.goBack();
}}>
<Image source={require('../../res/img/shootVideo/close.png')} style={{width:30,height:30}} />
</TouchableOpacity>
<TouchableOpacity >
<Image source={require('../../res/img/shootVideo/search.png')} style={{width:30,height:30}} />
</TouchableOpacity>
</View>
</View>
</View>
)
}
_onViewableItemsChanged({viewableItems, changed}) {
//这个方法为了让state对应当前呈现在页面上的item的播放器的state
//也就是只会有一个播放器播放,而不会每个item都播放
//可以理解为,只要不是当前再页面上的item 它的状态就应该暂停
//只有100%呈现再页面上的item(只会有一个)它的播放器是播放状态
if(viewableItems.length === 1){
this.setState({
current:viewableItems[0].index,
})
}
}
FlatList中renderItem布局代码:
/** item布局 播放器 等*/
renderItem({item,index}){
return(
<View style={{width:width,height:height-STATUSBAR_HEIGHT}}>
<TouchableWithoutFeedback style={{flex:1}} onPress={()=>{
this.setState({
isPause:!this.state.isPause,
})
}}>
<Video source={{uri:item}}
style={{flex: 1,backgroundColor:'#000'}}
repeat={true}
paused={index===this.state.current?this.state.isPause:true}
resizeMode='contain'
>
</Video>
</TouchableWithoutFeedback>
{/*信息(头像,标题等)、写评论*/}
<View column style={{position:'absolute',width:width,height:height-STATUSBAR_HEIGHT,justifyContent:'flex-end',padding: 20,marginBottom:30}}>
<View row style={{alignItems:'center'}}>
<Image source={require('../../res/img/shootVideo/user_icon.png')} style={{width:50,height:50,borderRadius:50,}} />
<Text style={{fontSize:15,color:'#fff',marginLeft:10}}>懒散少女和猫</Text>
<TouchableOpacity center style={{width:60,height:30,backgroundColor:'#f98589',borderRadius:5,marginLeft:10}}>
<Text style={{fontSize:14,color:'#fff'}}>关注</Text>
</TouchableOpacity>
</View>
<Text style={{fontSize:14,color:'#fff',marginTop:10}}>美丽的傍晚</Text>
<View style={{flexDirection:'row',alignItems:'center',backgroundColor:'rgba(0,0,0,0.5)',borderRadius:5,padding:3,width:155,marginTop:10}}>
<Image source={require('../../res/img/shootVideo/bgmusic.png')} style={{width:15,height:15}} />
<Text style={{fontSize:13,color:'#fff',marginLeft:10}}>@懒散的少女和猫</Text>
</View>
<View style={{marginTop:10}}>
<TouchableOpacity row style={{backgroundColor:'#4d4d4d',borderRadius:17,padding:10,alignItems:'center',width:270}}>
<Image source={require('../../res/img/shootVideo/write_review.png')} style={{width:15,height:15}} />
<Text style={{fontSize:14,color:'#fff',marginLeft:10}}>写评论...</Text>
</TouchableOpacity>
</View>
</View>
{/*底部 右侧 功能键 (我拍,点赞,评论,转发)*/}
<View column style={{position:'absolute',width:width,height:height-STATUSBAR_HEIGHT,justifyContent:'flex-end',alignItems:'flex-end',padding: 20}}>
<TouchableOpacity column center style={styles.bottomRightBn} >
<Image source={require('../../res/img/shootVideo/shoot.png')} resizeMode={'contain'} style={styles.bottomRightImage}/>
<Text style={styles.bottomRightText}>我拍</Text>
</TouchableOpacity>
<TouchableOpacity column center style={styles.bottomRightBn}>
<Image source={require('../../res/img/shootVideo/like.png')} resizeMode={'contain'} style={styles.bottomRightImage}/>
<Text style={styles.bottomRightText}>2.1万</Text>
</TouchableOpacity>
<TouchableOpacity column center style={styles.bottomRightBn}>
<Image source={require('../../res/img/shootVideo/review.png')} resizeMode={'contain'} style={styles.bottomRightImage}/>
<Text style={styles.bottomRightText}>300</Text>
</TouchableOpacity>
<TouchableOpacity column center style={[styles.bottomRightBn,{marginBottom:50}]}>
<Image source={require('../../res/img/shootVideo/share.png')} resizeMode={'contain'} style={styles.bottomRightImage}/>
<Text style={styles.bottomRightText}>分享</Text>
</TouchableOpacity>
</View>
{/* 屏幕中央 播放按钮 */}
{
this.state.isPause?
<View column center flex style={{position:'absolute',width:width,height:height-STATUSBAR_HEIGHT,}}>
<TouchableOpacity
onPress={()=>{this.setState({
isPause:!this.state.isPause,
})}}
>
<Image source={require('../../res/img/shootVideo/play.png')} resizeMode={'contain'} style={{width:60,height:60}} />
</TouchableOpacity>
</View>:null
}
</View>
)
}
代码中用到的样式:
const styles = StyleSheet.create({
container: {
flex: 1,
},
center: {
justifyContent: 'center',
alignItems: 'center',
},
bottomRightBn:{
width:50,
height:50,
marginTop:20,
},
bottomRightImage:{
width:30,
height:30,
},
bottomRightText:{
fontSize:14,
color:'#fff',
marginTop:5,
}
});
标签:播放器,index,仿抖,onViewableItemsChanged,音视频,React,item,state,isPause 来源: https://blog.csdn.net/qq_38356174/article/details/96439456
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。