其他分享
首页 > 其他分享> > React Native实现仿抖音视频列表(滑动切换)

React Native实现仿抖音视频列表(滑动切换)

作者:互联网

实现思路:
视频播放采用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