在React Native的RecyclerListView中超出屏幕视图时暂停视频

问题描述

我正在使用React {Native}中的RecyclerListView来实现视频播放应用程序(例如Instagram Reels或tik tok)。在应用程序的开发中,我面临着列表中所有视频同时播放的问题。我想暂停屏幕外的所有其他视频,并仅在滚动到特定视频并且视频在屏幕上可见时播放。

该怎么做?我已经尝试了很多事情,但是找不到RecyclerListView的解决方案。

我已经使用react-native-video播放视频了。

App.js

import VideoPlayer from './ViewVideo';
const fakeData = [
  {
    type: 'norMAL',item: {
      uri: require('./images/likd2.mp4'),},{
    type: 'norMAL',item: {
      uri: require('./images/Linkd.mp4'),item: {
      uri: require('./images/PlayDate.mp4'),];
export default class Myworld extends React.Component {
  dataProvider = new DataProvider((r1,r2) => {
    return r1 !== r2;
  }).cloneWithRows(fakeData);

  layoutProvider = new LayoutProvider(
    (i) => {
      return this.dataProvider.getDataForIndex(i).type;
    },(type,dim) => {
      switch (type) {
        case 'norMAL':
          dim.width = '100%';
          dim.height = '100%';
          break;
        default:
          dim.width = '100%';
          dim.height = '100%';
          break;
      }
    },);

  roWrenderer = (type,data,index) => {
    switch (type) {
      case 'norMAL':
        return (
          <View>
            <VideoPlayer source={uri} />
          </View>
        );
    }
  };

  render() {
    return (
      <>
        <SafeAreaView style={styles.container}>
          <RecyclerListView
            style={styles.videolistcontainer}
            roWrenderer={this.roWrenderer}
            dataProvider={this.dataProvider}
            layoutProvider={this.layoutProvider}
            initialOffset={1}
            pagingEnabled={true}
            showsverticalScrollIndicator={false}
          />
        </SafeAreaView>
      </>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,alignItems: 'center',backgroundColor: '#14171A',});

ViewVideo.js

const VideoPlayer = (props) => {
  const [paused,setPause] = useState(false);
  return (
    <>
      <TouchableOpacity
        style={{height: height,width: width}}
        onPress={() => setPause(!paused)}>
        <Video
          ref={(ref) => {
            setVideoRef(ref);
          }}
          source={props.source}
          style={styles.backgroundVideo}
          resizeMode={'cover'}
          onError={onError(videoRef)}
          paused={paused}
          onLoad={onLoad}
          onProgress={onProgress}
          onEnd={onEnd}
          repeat={false}
          rate={1.0}
          volume={1.0}
          muted={false}
          onLayout={onVideoLayout}
        />
      </TouchableOpacity>
    </>
  );
};

export default VideoPlayer;
const styles = StyleSheet.create({
  backgroundVideo: {
    position: 'absolute',width: WP('100%'),height: HP('100%'),left: 0,right: 0,top: 0,bottom: 0,});

解决方法

您可以使用React-Native的AppState。

它指示应用程序的未来状态:活动,后台或不活动(仅适用于IOS)

示例:

import React,{ useRef,useState,useEffect } from "react";
import { AppState,Text,View } from "react-native";
    
const AppInactiveHandleExample = () => {
    const appState = useRef(AppState.currentState);
    const [appStateVisible,setAppStateVisible] = useState(appState.current);

    useEffect(() => {
        AppState.addEventListener("change",handleAppStateChange);
        // Return for clear the cache of action
        return () => {
            AppState.removeEventListener("change",handleAppStateChange);
        };
    },[]);

    const handleAppStateChange = nextAppState => {
    if (
        appState.current.match(/inactive|background/) &&
        nextAppState === "active"
    ) {
        // Execute here your action  
        onAppInactive()
    }
        appState.current = nextAppState;
        setAppStateVisible(appState.current);
    };

    // Action executed when app was inactive or background
    const onAppInactive = () => {
        // Your code here 
    }

    return (
    <View>
        <Text>Current state is: {appStateVisible}</Text>
    </View>
    );
};

export default AppInactiveHandleExample;

https://reactnative.dev/docs/appstate