ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-07-18 18:43:52  阅读:1028  来源: 互联网

标签:播放器 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. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有