Javascript 即使在导航到react native flatlist中的不同屏幕后,也会调用onViewableItemsChanged

Javascript 即使在导航到react native flatlist中的不同屏幕后,也会调用onViewableItemsChanged,javascript,react-native,react-native-flatlist,Javascript,React Native,React Native Flatlist,我遇到了平面列表中onViewableItemsChanged的道具的问题。我有一个视频列表,当一个视频出现在屏幕上时播放,我做到了这一点 但问题是,一旦视频在滚动时自动开始播放,我就会导航到另一个有文本输入字段的位置。打开键盘进行文本输入后,将调用另一个屏幕中的onViewableItemsChanged,视频将继续在文本输入屏幕中播放 以下是两个不同屏幕的代码: FlatListSample.js import React,{useState,useCallback}来自“React”; 从

我遇到了平面列表中onViewableItemsChanged的道具的问题。我有一个视频列表,当一个视频出现在屏幕上时播放,我做到了这一点

但问题是,一旦视频在滚动时自动开始播放,我就会导航到另一个有文本输入字段的位置。打开键盘进行文本输入后,将调用另一个屏幕中的onViewableItemsChanged,视频将继续在文本输入屏幕中播放

以下是两个不同屏幕的代码:

FlatListSample.js

import React,{useState,useCallback}来自“React”;
从“react native”导入{样式表、文本、视图、平面列表、TouchableOpacity};
从“react native youtube iframe”导入youtube框架;
常数数据=[
{
id:'60524193a4e2070001537f51',
标题:“React Native Tutorial#1-简介”,
视频链接:“ur6I5m2nTvk”,
},
{
id:'6051f9bba4e2070001537f50',
标题:“React Native教程#2-创建React Native应用程序”,
视频链接:“pflXnUNMsNk”,
},
{
id:'6051F98ACCF9D6001F80429',
标题:“React Native Tutorial#3-视图、文本和样式”,
视频链接:''u yydvnjnfe',
},
{
id:'6051F94ACCF9D6001F80428',
标题:“反应本机教程#4-使用状态”,
视频链接:“1FiIYaRr148”,
},
{
id:'6051F921CFCF9D6001F80427',
标题:“React Native Tutorial#5-文本输入”,
视频链接:“c9Sg9jDitm8”,
},
{
id:'6051F8E8CCF9D6001F80426',
标题:“React Native Tutorial#6-列表和滚动视图”,
视频链接:“W-pg1r6-T0g”,
},
{
id:'6051f897a4e2070001537f4f',
标题:“React Native Tutorial#7-平面列表组件”,
视频链接:“iMCM1NceGJY”,
},
{
id:'6051f84ca4e2070001537f4e',
标题:“React Native教程#8-可触摸组件”,
视频链接:“QhX25YGf8qg”,
},
{
id:'6051F817CCF9D6001F80425',
标题:“React Native Tutorial#9-Todo应用程序(第1部分)”,
视频链接:“uLHFPt9B2Os”,
},
{
id:'6051f7dba4e2070001537f4d',
标题:“React Native Tutorial#10-待办事项应用程序(第2部分)”,
视频链接:“SGEitne8N-Q”,
},
];
const FlatListSample=props=>{
const[visibleItemIndex,setVisibleItemIndex]=useState();
常量[viewabilityConfiguration,setViewabilityConfiguration]=useState({
waitForInteraction:是的,
ViewArea覆盖率百分比阈值:40,
});
const onViewableItemsChangedHandler=useCallback(
({viewableItems,changed})=>{
console.log(“可查看项”);
if(viewableItems&&viewableItems.length!==0){
setVisibleItemIndex(可视项[0]。索引);
}
},
[],
);
常量renderItem=({item,index})=>{
返回(
{item.title}
{
setVisibleItemIndex(空);
props.navigation.navigate('TextInputSample');
}}>
);
};
返回(
项目id}
viewabilityConfiguration={viewabilityConfiguration}
onViewableItemsChanged={onViewableItemsChangedHandler}
/>
);
};
const styles=StyleSheet.create({
容器:{
弹性:1,
背景颜色:“#F7F7F7”,
},
视频安全:{
弹性:1,
填充垂直:10,
borderBottomColor:“#FCEABC”,
边界宽度:3,
背景颜色:“#FFFFFF”,
},
视频标题:{
尺寸:16,
颜色:“#1B110A”,
水平方向:10,
marginBottom:5,
},
});
导出默认FlatListSample;
TextInputSample.js

从“React”导入React;
从“react native”导入{View,TextInput};
常量TextInputSample=()=>{
返回(
console.log(文本)}
/>
);
};
导出默认文本InputSample;
当我从FlatListSample.js导航到TextInputSample.js并打开键盘后,视频再次开始播放。有人能找到解决办法吗


提前感谢您提供的解决方案。

嗯,我刚刚在IOS和Android上进行了验证。似乎问题只存在于安卓系统中。这也是一种奇怪的行为

试图通过查看react导航屏幕堆栈找到问题的原因,进行了大量调试,但仍无法跟踪

就你而言,我想出了两种方法来解决你的问题。(开放寻求更好的解决方案)

  • 使用导航事件侦听器“模糊”和“聚焦”更改聚焦布尔值
  • import React,{useState,useRef,useffect}来自'React';
    从“react”导入{useCallback};
    从“react native”导入{样式表、文本、视图、平面列表、TouchableOpacity};
    从“react native youtube iframe”导入youtube框架;
    常数数据=[
    {
    id:'60524193a4e2070001537f51',
    标题:“React Native Tutorial#1-简介”,
    视频链接:“ur6I5m2nTvk”,
    },
    {
    id:'6051f9bba4e2070001537f50',
    标题:“React Native教程#2-创建React Native应用程序”,
    视频链接:“pflXnUNMsNk”,
    },
    {
    id:'6051F98ACCF9D6001F80429',
    标题:“React Native Tutorial#3-视图、文本和样式”,
    视频链接:''u yydvnjnfe',
    },
    {
    id:'6051F94ACCF9D6001F80428',
    标题:“反应本机教程#4-使用状态”,
    视频链接:“1FiIYaRr148”,
    },
    {
    id:'6051F921CFCF9D6001F80427',
    标题:“React Native Tutorial#5-文本输入”,
    视频链接:“c9Sg9jDitm8”,
    },
    {
    id:'6051F8E8CCF9D6001F80426',
    标题:“React Native Tutorial#6-列表和滚动视图”,
    视频链接:“W-pg1r6-T0g”,
    },
    {
    id:'6051f897a4e2070001537f4f',
    标题:“React Native Tutorial#7-平面列表组件”,
    视频链接:“iMCM1NceGJY”,
    },
    {
    id:'6051f84ca4e2070001537f4e',
    标题:“React Native教程#8-可触摸组件”,
    视频链接:“QhX25YGf8qg”,
    },
    {
    id:'6051F817CCF9D6001F80425',
    标题:“React Native Tutorial#9-待办事项应用程序(pa
    
    import React, {useState, useCallback} from 'react';
    import {StyleSheet, Text, View, FlatList, TouchableOpacity} from 'react-native';
    import YouTubeIFrame from 'react-native-youtube-iframe';
    
    const data = [
      {
        id: '60524193a4e2070001537f51',
        title: 'React Native Tutorial #1 - Introduction',
        videoLink: 'ur6I5m2nTvk',
      },
      {
        id: '6051f9bba4e2070001537f50',
        title: 'React Native Tutorial #2 - Creating a React Native App',
        videoLink: 'pflXnUNMsNk',
      },
      {
        id: '6051f98accf9d60001f80429',
        title: 'React Native Tutorial #3 - Views, Text & Styles',
        videoLink: '_YydVvnjNFE',
      },
      {
        id: '6051f94accf9d60001f80428',
        title: 'React Native Tutorial #4 - Using State',
        videoLink: '1FiIYaRr148',
      },
      {
        id: '6051f921ccf9d60001f80427',
        title: 'React Native Tutorial #5 - Text Inputs',
        videoLink: 'c9Sg9jDitm8',
      },
      {
        id: '6051f8e8ccf9d60001f80426',
        title: 'React Native Tutorial #6 - Lists & ScrollView',
        videoLink: 'W-pg1r6-T0g',
      },
      {
        id: '6051f897a4e2070001537f4f',
        title: 'React Native Tutorial #7 - Flat List Component',
        videoLink: 'iMCM1NceGJY',
      },
      {
        id: '6051f84ca4e2070001537f4e',
        title: 'React Native Tutorial #8 - Touchable Components',
        videoLink: 'QhX25YGf8qg',
      },
      {
        id: '6051f817ccf9d60001f80425',
        title: 'React Native Tutorial #9 - Todo App (part 1)',
        videoLink: 'uLHFPt9B2Os',
      },
      {
        id: '6051f7dba4e2070001537f4d',
        title: 'React Native Tutorial #10 - Todo App (part 2)',
        videoLink: 'SGEitne8N-Q',
      },
    ];
    
    const FlatListSample = props => {
      const [visibleItemIndex, setVisibleItemIndex] = useState();
      const [viewabilityConfiguration, setViewabilityConfiguration] = useState({
        waitForInteraction: true,
        viewAreaCoveragePercentThreshold: 40,
      });
    
      const onViewableItemsChangedHandler = useCallback(
        ({viewableItems, changed}) => {
          console.log('Viewable item');
          if (viewableItems && viewableItems.length !== 0) {
            setVisibleItemIndex(viewableItems[0].index);
          }
        },
        [],
      );
    
      const renderItem = ({item, index}) => {
        return (
          <View key={item.id} style={styles.videoSec}>
            <Text style={styles.videoTitle}>{item.title}</Text>
            <TouchableOpacity
              activeOpacity={0.9}
              onPress={() => {
                setVisibleItemIndex(null);
                props.navigation.navigate('TextInputSample');
              }}>
              <YouTubeIFrame
                videoId={item.videoLink}
                height={230}
                play={index === visibleItemIndex}
                initialPlayerParams={{rel: false, controls: false, loop: true}}
              />
            </TouchableOpacity>
          </View>
        );
      };
      return (
        <View style={styles.container}>
          <FlatList
            style={{flex: 1}}
            data={data}
            renderItem={renderItem}
            keyExtractor={item => item.id}
            viewabilityConfig={viewabilityConfiguration}
            onViewableItemsChanged={onViewableItemsChangedHandler}
          />
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#F7F7F7',
      },
      videoSec: {
        flex: 1,
        paddingVertical: 10,
        borderBottomColor: '#FCEABC',
        borderBottomWidth: 3,
        backgroundColor: '#FFFFFF',
      },
      videoTitle: {
        fontSize: 16,
        color: '#1B110A',
        paddingHorizontal: 10,
        marginBottom: 5,
      },
    });
    
    export default FlatListSample;
    
    
    import React from 'react';
    import {View, TextInput} from 'react-native';
    
    const TextInputSample = () => {
      return (
        <View>
          <TextInput
            style={{height: 40, backgroundColor: 'azure', fontSize: 20}}
            placeholder="Type here to translate!"
            onChangeText={text => console.log(text)}
          />
        </View>
      );
    };
    
    export default TextInputSample;
    
    
    import React, {useState, useRef, useEffect} from 'react';
    import { useCallback } from 'react';
    import {StyleSheet, Text, View, FlatList, TouchableOpacity} from 'react-native';
    import YouTubeIFrame from 'react-native-youtube-iframe'; 
    
    const data = [
      {
        id: '60524193a4e2070001537f51',
        title: 'React Native Tutorial #1 - Introduction',
        videoLink: 'ur6I5m2nTvk',
      },
      {
        id: '6051f9bba4e2070001537f50',
        title: 'React Native Tutorial #2 - Creating a React Native App',
        videoLink: 'pflXnUNMsNk',
      },
      {
        id: '6051f98accf9d60001f80429',
        title: 'React Native Tutorial #3 - Views, Text & Styles',
        videoLink: '_YydVvnjNFE',
      },
      {
        id: '6051f94accf9d60001f80428',
        title: 'React Native Tutorial #4 - Using State',
        videoLink: '1FiIYaRr148',
      },
      {
        id: '6051f921ccf9d60001f80427',
        title: 'React Native Tutorial #5 - Text Inputs',
        videoLink: 'c9Sg9jDitm8',
      },
      {
        id: '6051f8e8ccf9d60001f80426',
        title: 'React Native Tutorial #6 - Lists & ScrollView',
        videoLink: 'W-pg1r6-T0g',
      },
      {
        id: '6051f897a4e2070001537f4f',
        title: 'React Native Tutorial #7 - Flat List Component',
        videoLink: 'iMCM1NceGJY',
      },
      {
        id: '6051f84ca4e2070001537f4e',
        title: 'React Native Tutorial #8 - Touchable Components',
        videoLink: 'QhX25YGf8qg',
      },
      {
        id: '6051f817ccf9d60001f80425',
        title: 'React Native Tutorial #9 - Todo App (part 1)',
        videoLink: 'uLHFPt9B2Os',
      },
      {
        id: '6051f7dba4e2070001537f4d',
        title: 'React Native Tutorial #10 - Todo App (part 2)',
        videoLink: 'SGEitne8N-Q',
      },
    ];
    
    const FlatListExample = (props) => {
    
      const [visibleItemIndex, setVisibleItemIndex] = useState();
      const [focused, setFocused] = useState();
    
      const viewabilityConfig = {
        itemVisiblePercentThreshold: 40,
        waitForInteraction: true,
      };
    
      useEffect(() => {
        const subscribeFocusEvent = props.navigation.addListener('focus', () => {
          setFocused(true);
          console.log('focus', focused);
        });
        const subscribeBlurEvent = props.navigation.addListener('blur', () => {
          setFocused(false);
          console.log('blur', focused);
        });
        return (() => {
          subscribeFocusEvent;
          subscribeBlurEvent;
        });
      }, [focused]);
      
      
      const onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
        console.log({
          message: 'triggers change....1', 
          viewableItems, 
          changed,
          focused
        }, 'CHECK');
        if (changed && changed.length > 0) {
          setVisibleItemIndex(changed[0].index);
        }
      });
    
      const viewabilityConfigCallbackPairs = useRef([{ viewabilityConfig, onViewableItemsChanged }]);
      
      const renderItem = ({item, index}) => {
        return (
          <View key={item.id} style={styles.videoSec}>
            <Text style={styles.videoTitle}>{item.title}</Text>
            <TouchableOpacity
              activeOpacity={0.9}
              onPress={() => {
                setVisibleItemIndex(null);
                // props.navigation.navigate('Shop');
              }}>
              <YouTubeIFrame
                videoId={item.videoLink}
                height={230}
                play={index === visibleItemIndex}
                initialPlayerParams={{rel: false, controls: false, loop: true}}
              />
            </TouchableOpacity>
          </View>
        );
      };
      if(focused) {
        return (
          <View style={styles.container}>
            <FlatList
              style={{flex: 1}}
              data={data}
              renderItem={renderItem}
              keyExtractor={item => item.id}
              viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
            />
          </View>
        );
      }
      return null;
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#F7F7F7',
      },
      videoSec: {
        flex: 1,
        paddingVertical: 10,
        borderBottomColor: '#FCEABC',
        borderBottomWidth: 3,
        backgroundColor: '#FFFFFF',
      },
      videoTitle: {
        fontSize: 16,
        color: '#1B110A',
        paddingHorizontal: 10,
        marginBottom: 5,
      },
    });
    
    export default FlatListExample;
    
    export const FlatListScreen = ({ navigation, route }) => {
    
        console.log(route.name);
    
        // this screen title
        if(route.name === 'VideoScreen') {
            return (
                <FlatList 
                    {...props}
                />
            );
        }
        return null;
    };