【问题标题】:Play video in fullscreen(lanscape) on click of play button using Flatlist使用 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>
    );

【问题讨论】:

    标签: android ios react-native react-native-video


    【解决方案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 请按照上面给出的答案找到我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 2015-11-21
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      • 2017-03-13
      • 1970-01-01
      相关资源
      最近更新 更多