使用 Flatlist 单击播放按钮以全屏(横向)播放视频

Posted

技术标签:

【中文标题】使用 Flatlist 单击播放按钮以全屏(横向)播放视频【英文标题】:Play video in fullscreen(lanscape) on click of play button using Flatlist 【发布时间】:2018-07-26 12:42:59 【问题描述】:

我已经使用 Flatlist 及以下库实现了视频滚动。

反应原生视频

react-native-orientation

点击播放按钮会在同一帧开始播放视频,如下所示:

我想在单击播放按钮和单击关闭按钮时以横向全屏播放视频,它应该是纵向模式。

使用的依赖项:

"dependencies": 
    "axios": "^0.18.0",
    "native-base": "^2.7.2",
    "prop-types": "^15.6.2",
    "react": "16.4.1",
    "react-native": "0.56.0",
    "react-native-orientation": "^3.1.3",
    "react-native-vector-icons": "^4.6.0",
    "react-native-video": "^3.1.0",
    "react-navigation": "^2.8.0"
  ,

当前实现的代码:

return (
      <View style=styles.flatList>
        <View style=styles.image>
          <Video
            source=
              uri: item.video_url
            
            ref=ref => 
              this.player = ref;
            
            onEnd=() => 
            style=styles.videoContainer
            paused=this.state.paused
            muted=this.state.muted
            repeat=this.state.repeat
            controls=true
          />
        </View>
        <Text style=styles.itemTitle> item.title </Text>
      </View>
    );

【问题讨论】:

【参考方案1】:
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React,  Component  from "react";
import 
  StyleSheet,
  Text,
  View,
  FlatList,
  TouchableHighlight,
  ActivityIndicator,
  SafeAreaView,
  Image,
  Modal,
  Dimensions
 from "react-native";
import MaterialIcons from "react-native-vector-icons/MaterialIcons";
import  Container, Content, Header, Body, Title  from "native-base";
import Video from "react-native-video";
import Orientation from "react-native-orientation";
import VideoActions from "../Redux/VideoRedux";
import  connect  from "react-redux";
// Styles
import styles from "./Styles/VideoListScreenStyles";

class LaunchScreen extends Component 
  static navigationOptions = 
    header: null
  ;
  constructor(props) 
    super(props);
    this.state = 
      isLoading: false,
      isLoadingMore: false,
      loading: true,
      dataSource: [],
      video_url: "",
      data: [],
      status: false,
      muted: false,
      paused: true,
      repeat: false,
      videos: []
    ;
  

  apiParsing() 
    const axios = require("axios");
    axios
      .get("https://private-c31a5-task27.apiary-mock.com/videos")
      .then(response => 
        // handle success
        this.setState(
          isLoading: false,
          dataSource: response.data.videos,
          data: response.data.videos
        );
        console.log(response.data.videos);
      )
      .catch(error => 
        // handle error
        console.log(error);
      )
      .then(() => 
        // always executed
      );
  

  fetchMore = () => 
    const data = this.state.data.concat(this.state.dataSource);
    this.setState(
      isLoading: false,
      data: data
    );
  ;

  componentDidMount() 
    // this.apiParsing();

    // Orientation.unlockAllOrientations();
    this.props.getVideos();

    Orientation.addOrientationListener(this._orientationDidChange);
  

  static getDerivedStateFromProps(props, state) 
    props.videos ?  videos: props.videos  : null;
    return null;
  

  _orientationDidChange = orientation => 
    if (orientation === "LANDSCAPE") 
      console.log("Landscape Mode On");
     else 
    
  ;

  // componentWillUnmount() 
  //   Orientation.getOrientation((err, orientation) => 
  //     console.log(`Current Device Orientation: $orientation`);
  //   );

  //   Orientation.removeOrientationListener(this._orientationDidChange);
  // 

  handlePlayAndPause = item => 
    this.setState(prevState => (
      paused: !prevState.paused,
      video_url: item.video_url
    ));
  ;

  handleVolume = () => 
    this.setState(prevState => (
      muted: !prevState.muted
    ));
  ;

  handleRepeat = () => 
    this.setState(prevState => (
      repeat: !prevState.repeat
    ));
  ;

  handleFullScreenToPortrait = () => 
    Orientation.lockToPortrait();
    this.setState(
      video_url: "",
      paused: true
    );
  ;

  handleFullScreenToLandscape = () => 
    this.player.presentFullscreenPlayer();
    Orientation.lockToLandscape();
  ;

  onEndVideo = () => 
    this.player.dismissFullscreenPlayer();
    Orientation.lockToPortrait();
    this.setState(
      video_url: "",
      paused: true
    );
  ;

  renderFooter = () => 
    if (!this.state.loading) return null;

    return (
      this.state.isLoadingMore && (
        <View
          style=
            paddingVertical: 10,
            // borderTopWidth: 1,
            borderColor: "#CED0CE"
          
        >
          <ActivityIndicator animating size="large" />
        </View>
      )
    );
  ;

  renderItem(item) 
    console.log("Image URL", item.thumbnail_url);
    return (
      <View style=styles.faltList>
        <View style=styles.image>
          <Image
            style=styles.image
            source=
              uri: item.thumbnail_url
            
            resizeMode="cover"
          />
          <View style=styles.controlBar>
            <MaterialIcons
              name=this.state.paused ? "play-arrow" : "pause"
              size=45
              color="white"
              onPress=() => this.handlePlayAndPause(item)
            />
          </View>
        </View>
        <Text style=styles.welcome> item.title </Text>
      </View>
    );
  

  render() 
    console.log("Image URL", this.props.videos);
    if (this.state.isLoading) 
      return (
        <View style=styles.activityIndicator>
          <ActivityIndicator />
        </View>
      );
    

    return (
      <Container>
        <Header>
          <Body>
            <Title> Videos </Title>
          </Body>
        </Header>
        <View style=styles.container>
          <SafeAreaView>
            this.state.video_url ? (
              <Video
                source=
                  uri: this.state.video_url
                
                ref=ref => 
                  this.player = ref;
                
                onEnd=this.onEndVideo
                onLoadStart=this.handleFullScreenToLandscape
                // style=styles.videoContainer
                paused=this.state.paused
                muted=this.state.muted
                repeat=this.state.repeat
                onFullscreenPlayerDidDismiss=() =>
                  this.handleFullScreenToPortrait()
                
              />
            ) : null
            <FlatList
              data=this.props.videos
              renderItem=( item ) => this.renderItem(item)
              keyExtractor=(item, index) => index.toString()
              showsVerticalScrollIndicator=false
              showsHorizontalScrollIndicator=false
              ListFooterComponent=this.renderFooter
              onEndReached=() =>
                this.setState( isLoadingMore: true , () => this.fetchMore())
              
              onEndReachedThreshold=0.01
            />
          </SafeAreaView>
        </View>
      </Container>
    );
  


const mapStateToProps = state => (
  videos: state.videos.videos
);

const mapDispatchToProps = dispatch => (
  getVideos: () => dispatch(VideoActions.videoRequest())
);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(LaunchScreen);

【讨论】:

【参考方案2】:

如果您使用的是 react-native-orientation,则在使用 import Orientation from 'react-native-orientation'; 导入库后,您应该能够在事件处理程序上使用 Orientation.lockToLandscape();。或者可能更好的是,您应该能够创建一个函数,该函数调用react-native-video 中可用的presentFullscreenPlayer 方法,使用它的ref 就像this.player.presentFullscreenPlayer(); 一样,它也会在像onLoadStart 这样的事件处理程序上被调用。

【讨论】:

它不起作用。应用程序在尝试打开全屏视频时崩溃。实际上,我需要一个播放按钮单击事件,然后才能全屏播放。 @JaydeepPatel 你有什么解决办法吗? @Jaydip 请按照上面给出的答案找到我的答案。

以上是关于使用 Flatlist 单击播放按钮以全屏(横向)播放视频的主要内容,如果未能解决你的问题,请参考以下文章

关闭 MPMoviePlayerViewController 的全屏模式时出现问题

使用 MPMoviePlayerController 无法以全屏模式播放大尺寸视频

在 QT 中以全屏模式播放视频

在 iOS 中单击全屏按钮时可以强制 MPMoviePlayerController 横向

iphone - 强制 MPMoviePlayerController 以横向模式播放视频

在我的 android 应用中以全屏模式播放 youtube 视频