安裝與依賴請參考github地址
https://github.com/react-native-community/react-native-video
//---------
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Platform,
ActivityIndicator,
TouchableOpacity,
ScrollView,
Image,
ListView,
} from 'react-native';
import Video from 'react-native-video';
import Dimensions from 'Dimensions';
import Icon from 'react-native-vector-icons/Ionicons';
import config from '../common/config';
import request from '../common/request';
const {width,height} = Dimensions.get('window');
export default class Detail extends Component {
constructor(props){
super(props);
this.state={
rowData:this.props.rowData,
rate: 10,//播放速率
volume: 1,
muted: true,//静音
resizeMode: 'contain',
paused: false,//暂停
videoError:false,//错误
duration: 0.0,
currentTime: 0.0,
videoLoaded:false,
playing:false,
playEnd:false,
dataSource:new ListView.DataSource({
rowHasChanged:(r1,r2) => r1 !== r2,
})
}
// this._onLoadStart = this._onLoadStart.bind(this);
// this._onLoad = this._onLoad.bind(this);
this._onProgress = this._onProgress.bind(this);
// this._onEnd = this._onEnd.bind(this);
// this._onError = this._onError.bind(this);
this._rePlay = this._rePlay.bind(this);
this._resume = this._resume.bind(this);
this._pause = this._pause.bind(this);
this._pop = this._pop.bind(this);
this._renderRow = this._renderRow.bind(this);
}
_renderRow(rowData_reply){
return(
<View
style={styles.replyBox}
key={rowData_reply._id}
>
<Image style={styles.replyAvatar}
source={{uri:rowData_reply.replyBy.avatar}}
/>
<View style={styles.reply}>
<Text style={styles.replyNickname}>{rowData_reply.replyBy.nickname}</Text>
<Text style={styles.replyContent}>{rowData_reply.content}</Text>
</View>
</View>
)
}
componentDidMount(){
this._fetchData();//从服务器获取数据
}
_fetchData(){
let url = config.api.base + config.api.comments;
//发送网络请求
request.get(url,{
id:"112233",
accessToken:'jjjj'
}).then(
(data)=>{
if(data && data.success){
let comments = data.data;
if(comments && comments.length > 0){
this.setState({
dataSource:this.state.dataSource.cloneWithRows(comments)
})
}
}
}
).catch(
(error)=>{
console.log('数据有问题');
}
)
}
_pop(){
let {navigator} = this.props;
if(navigator){
navigator.pop();
}
}
_resume(){
if(this.state.paused){
this.setState({
paused:false
});
}
}
_pause(){
if(!this.state.paused){
this.setState({
paused:true
});
}
}
_rePlay(){
this.setState({
playEnd:false,
paused: false,
})
this.refs.videoPlayer.seek(0);
}
_onLoadStart=()=>{
console.log('_onLoadStart');
}
_onLoad=(data)=>{
console.log('_onLoad--视频总长度'+data.duration);
this.setState({duration:data.duration});
}
_onProgress(data){
if(!this.state.videoLoaded){
this.setState({
videoLoaded:true,
});
}
if(!this.state.playing && !this.state.playEnd){
console.log('进来改变状态');
this.setState({
playEnd:false,
playing:true,
});
}
this.setState({currentTime:data.currentTime});
//console.log('_onProgress---当前时间'+data.currentTime);
}
_onEnd=()=>{
this.setState({
playing:false,
paused:true,
playEnd:true,
})
console.log('结束了');
}
_onError=(error)=>{
console.log('错误'+JSON.stringify(error))
this.setState({
videoError:true,
})
}
getCurrentTimePercentage() {
if (this.state.currentTime > 0) {
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
} else {
return 0;
}
}
render() {
let rowData = this.state.rowData;
//一个是当前时间,一个是剩余时间
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
return (
<View style={styles.container}>
{/*导航栏*/}
<View style={styles.navStyle}>
{/*返回按钮*/}
<TouchableOpacity
style={styles.backBox}
onPress={this._pop}
>
<Icon name="ios-arrow-back"
style={styles.backIcon}
/>
<Text style={styles.backText}>返回</Text>
</TouchableOpacity>
{/*中间的文字*/}
<Text style={styles.navText} numberOfLines={1}>视频详情页面</Text>
</View>
{/*播放器*/}
<View style={styles.videoBox}>
<Video
source={{uri:rowData.video}}
style={styles.video}
rate={this.state.rate}
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
resizeMode={this.state.resizeMode}
repeat={false}
ref='videoPlayer'
onLoadStart={this._onLoadStart}
onLoad={this._onLoad}
onProgress={this._onProgress}
onEnd={this._onEnd}
onError={this._onError}
/>
{/*错误提示*/}
{this.state.videoError?
<Text style={styles.failText}>很抱歉,你访问的视频飞走了...</Text>
:null
}
{/*小菊花*/}
{!this.state.videoLoaded ?
<ActivityIndicator
color="red"
size="large"
style={styles.loading}
/>
:null
}
{/*播放按钮*/}
{!this.state.playing && this.state.videoLoaded ?
<Icon name='ios-play'
size={45}
style={styles.play}
onPress={this._rePlay}
/>
:null
}
{/*暂停&&继续*/}
{this.state.videoLoaded && this.state.playing?
<TouchableOpacity
onPress={this._pause}
style={styles.pauseStyle}
>
{this.state.paused?
<Icon name='ios-play'
size={45}
style={styles.play}
onPress={this._resume}
/>
:null
}
</TouchableOpacity>
:null
}
{/*进度条*/}
<View style={styles.progress}>
<View style={[styles.innerProgressCompleted, {flex: flexCompleted}]} />
<View style={[styles.innerProgressRemaining, {flex: flexRemaining}]} />
</View>
</View>
{/*底部内容*/}
<ScrollView
enableEmptySections={true}
automaticallyAdjustContentInsets={false}
showsVerticalScrollIndicator={false}
style={styles.scrollview}
>
{/*视频信息*/}
<View style={styles.infoBox}
>
{/*头像*/}
<Image
style={styles.avatar}
source={{uri:rowData.author.avatar}}
/>
<View style={styles.descBox}>
<Text style={styles.nickname}>作者:{rowData.author.nickname}</Text>
<Text style={styles.title}>标题:{rowData.title}</Text>
</View>
</View>
{/*评论信息*/}
<ListView
dataSource={this.state.dataSource}
renderRow = {this._renderRow}
enableEmptySections={true}
automaticallyAdjustContentInsets={false}
showsVerticalScrollIndicator={false}
/>
</ScrollView>
</View>
);
}
_backToList = ()=>{
let {navigator} = this.props;
if(navigator){
navigator.pop();
}
}
}
let videoBoxHeight = 250;
let videoHeight = videoBoxHeight - 10;
let loadingTop = videoBoxHeight * 0.5 - 30;
let playWH = 60;
let playTop = videoBoxHeight * 0.5 - playWH*0.5;
let failTextTop = videoBoxHeight * 0.5 + playWH*0.5;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
marginTop:Platform.OS === 'ios'?20:0,
},
videoBox:{
width:width,
height:videoBoxHeight,
backgroundColor:'black'
},
video:{
width:width,
height:videoHeight,
backgroundColor:'black'
},
loading:{
position:'absolute',
top:loadingTop,
width:width,
left:0,
alignItems:'center',
},
progress: {
flex: 1,
flexDirection: 'row',
borderRadius: 3,
overflow: 'hidden',
},
innerProgressCompleted: {
height: 10,
backgroundColor: '#cccccc',
},
innerProgressRemaining: {
height: 10,
backgroundColor: '#2C2C2C',
},
play:{
position:'absolute',
top:playTop,
left:width * 0.5 - playWH*0.5,
width:playWH,
height:playWH,
paddingTop:10,
paddingLeft:22,
backgroundColor:'transparent',
borderColor:'black',
borderWidth:1,
borderRadius:playWH * 0.5,
},
pauseStyle:{
position:'absolute',
top:0,
left:0,
width:width,
height:videoHeight,
},
failText:{
position:'absolute',
left:0,
width:width,
top:failTextTop,
backgroundColor:'transparent',
textAlign:'center',
color:'red',
fontSize:20,
},
navStyle:{
flexDirection:'row',
justifyContent:'center',
alignItems:'center',
width:width,
height:64,
backgroundColor:'#dddddd',
borderBottomWidth:0.5,
borderBottomColor:'black',
},
backBox:{
position:'absolute',
left:12,
top:25,
width:60,
flexDirection:'row',
alignItems:'center'
},
backIcon:{
fontSize:22,
marginRight:5
},
backText:{
fontSize:16
},
navText:{
textAlign:'center',
lineHeight:64,
height:64,
fontSize:18,
width:width - 120,
},
infoBox:{
flexDirection:'row',
width:width,
justifyContent:'center',
marginTop:10,
},
avatar:{
width:60,
height:60,
borderRadius:30,
marginRight:10,
marginLeft:10
},
descBox:{
flex:1,
},
nickname:{
fontSize:18,
},
title:{
marginTop:8,
fontSize:16,
color:'#666',
},
replyBox:{
flexDirection:'row',
width:width,
justifyContent:'center',
marginTop:10,
},
replyAvatar:{
width:40,
height:40,
borderRadius:20,
marginRight:10,
marginLeft:10
},
reply:{
flex:1
},
replyNickname:{
fontSize:16,
},
replyContent:{
marginTop:5,
paddingRight:10
}
});
效果圖如下:
图片.png
网友评论