Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/478.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在特定情况下,如果数据为空,如何防止滚动?_Javascript_Reactjs_React Native - Fatal编程技术网

Javascript 在特定情况下,如果数据为空,如何防止滚动?

Javascript 在特定情况下,如果数据为空,如何防止滚动?,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我有两个最上面的标签。每个选项卡都有一个从API接收数据的组件 我通过添加动画将这些选项卡包装在滚动视图中, 当按下第二个选项卡时,该组件将显示在屏幕上,并显示滑动动画 但我有个问题。如果我在选项卡1中,并且该选项卡的组件有一个很长的数据列表;滚动到末尾后,如果我按Tab 2,滚动指示器也会显示在Tab 2中,“在视图末尾” 那么,我可以让标签有单独的卷轴吗 我做了一个活生生的例子 尝试在“已打开”选项卡中向下滚动。然后转到“已关闭”选项卡,您将 看到问题了吗 这是密码 import * as

我有两个最上面的标签。每个选项卡都有一个从API接收数据的组件

我通过添加动画将这些选项卡包装在滚动视图中, 当按下第二个选项卡时,该组件将显示在屏幕上,并显示滑动动画

但我有个问题。如果我在选项卡1中,并且该选项卡的组件有一个很长的数据列表;滚动到末尾后,如果我按Tab 2,滚动指示器也会显示在Tab 2中,“在视图末尾”

那么,我可以让标签有单独的卷轴吗

我做了一个活生生的例子

尝试在“已打开”选项卡中向下滚动。然后转到“已关闭”选项卡,您将 看到问题了吗

这是密码

import * as React from 'react';
import {
  View,
  Animated,
  Text,
  TouchableOpacity,
  ScrollView,
  StyleSheet,
  FlatList,
  Dimensions,
} from 'react-native';

const { width, height } = Dimensions.get('window');
const SPACING = 20;
const SLIDE_WIDTH = width - SPACING * 2;

export default function App() {
  const [openedOrders, setOpenedOrders] = React.useState([]);
  const [closedOrders, setClosedOrders] = React.useState([]);

  const [active, setActive] = React.useState(0);
  const [xTabOne, setXTabOne] = React.useState(0);
  const [xTabTwo, setXTabTwo] = React.useState(0);

  const [translateX] = React.useState(new Animated.Value(0));
  const [translateXTabOne] = React.useState(new Animated.Value(0));
  const [translateXTabTwo] = React.useState(new Animated.Value(width));
  const [translateY, setTranslateY] = React.useState(-1000);

  const handleSlide = React.useCallback(
    (type) => {
      Animated.spring(translateX, {
        toValue: type,
        duration: 100,
        useNativeDriver: true,
      }).start();
      if (active === 0) {
        Animated.parallel([
          Animated.spring(translateXTabOne, {
            toValue: 0,
            duration: 100,
            useNativeDriver: true,
          }).start(),
          Animated.spring(translateXTabTwo, {
            toValue: width,
            duration: 100,
            useNativeDriver: true,
          }).start(),
        ]);
      } else {
        Animated.parallel([
          Animated.spring(translateXTabOne, {
            toValue: width,
            duration: 100,
            useNativeDriver: true,
          }).start(),
          Animated.spring(translateXTabTwo, {
            toValue: 0,
            duration: 100,
            useNativeDriver: true,
          }).start(),
        ]);
      }
    },
    [active, translateXTabOne, translateX, translateXTabTwo]
  );

  React.useEffect(() => {
    active === 0 ? handleSlide(xTabTwo) : handleSlide(xTabOne);
  }, [active, handleSlide, xTabTwo, xTabOne]);

  return (
    <>
      <View
        style={{
          flexDirection: 'row',
          marginTop: 20,
          marginBottom: 20,
          position: 'relative',
          justifyContent: 'center',
          alignItems: 'center',
          borderRadius: 15,
          height: 61,
          backgroundColor: '#ccc',
        }}>
        <Animated.View
          style={{
            position: 'absolute',
            width: '50%',
            height: '100%',
            top: 0,
            left: 0,
            backgroundColor: '#000',
            borderRadius: 15,
            transform: [
              {
                translateX,
              },
            ],
          }}
        />
        <TouchableOpacity
          style={{
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            height: 61,
          }}
          onLayout={(event) => setXTabOne(event.nativeEvent.layout.x)}
          onPress={() => {
            setActive(1);
          }}>
          <Text
            style={{
              fontSize: 18,
              color: active === 0 ? '#262626' : '#fff',
            }}>
            opened
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={{
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            height: 61,
          }}
          onLayout={(event) => setXTabTwo(event.nativeEvent.layout.x)}
          onPress={() => {
            setActive(0);
          }}>
          <Text
            style={{
              fontSize: 18,
              color: active === 1 ? '#262626' : '#fff',
            }}>
            closed
          </Text>
        </TouchableOpacity>
      </View>

      <ScrollView
        showsVerticalScrollIndicator={true}
        // contentContainerStyle={{flexGrow: 1}}
      >
        <Animated.View
          style={{
            transform: [
              {
                translateX: translateXTabOne,
              },
            ],
          }}
          onLayout={(event) => setTranslateY(event.nativeEvent.layout.height)}>
          <FlatList
            data={
              []
              // Array(900).fill(0)
            }
            contentContainerStyle={{flexGrow:1}}
            ListEmptyComponent={() => {
              return (
                <View style={{ flex: 1, backgroundColor: '#999' }}>
                  <Text>No data here...</Text>
                </View>
              );
            }}
            renderItem={({ item, index }) => {
              return <Text key={index}>hey: {index}</Text>;
            }}
            keyExtractor={(item) => item.toString()}
          />
        </Animated.View>
        <Animated.View
          style={{
            transform: [
              {
                translateX: translateXTabTwo,
              },
              {
                translateY: -translateY,
              },
            ],
          }}>
          <FlatList
            data={Array(900).fill(0)}
            renderItem={({ item, index }) => {
              return <Text key={index}>hey: {index}</Text>;
            }}
            keyExtractor={(item) => item.toString()}
          />
        </Animated.View>
      </ScrollView>
    </>
  );
}
import*as React from'React';
进口{
看法
有生气的
文本
可触摸不透明度,
滚动视图,
样式表,
平面列表,
尺寸,
}从“反应本机”;
const{width,height}=Dimensions.get('window');
常数间距=20;
常量滑动宽度=宽度-间距*2;
导出默认函数App(){
const[openedOrders,setOpenedOrders]=React.useState([]);
const[closedOrders,setClosedOrders]=React.useState([]);
const[active,setActive]=React.useState(0);
const[xTabOne,setXTabOne]=React.useState(0);
const[xTabTwo,setXTabTwo]=React.useState(0);
const[translateX]=React.useState(新的动画.Value(0));
const[translateXTabOne]=React.useState(新的动画.Value(0));
const[translateXTabTwo]=React.useState(新的动画.Value(width));
const[translateY,setTranslateY]=React.useState(-1000);
const handleSlide=React.useCallback(
(类型)=>{
动画。春天(translateX{
toValue:type,
持续时间:100,
useNativeDriver:没错,
}).start();
如果(活动===0){
平行动画([
动画。春天(translateXTabOne{
toValue:0,
持续时间:100,
useNativeDriver:没错,
}).start(),
动画。春天(第二{
toValue:width,
持续时间:100,
useNativeDriver:没错,
}).start(),
]);
}否则{
平行动画([
动画。春天(translateXTabOne{
toValue:width,
持续时间:100,
useNativeDriver:没错,
}).start(),
动画。春天(第二{
toValue:0,
持续时间:100,
useNativeDriver:没错,
}).start(),
]);
}
},
[活动,translateXTabOne,translateX,translateXTabTwo]
);
React.useffect(()=>{
活动===0?把手滑动(XTABTOW):把手滑动(xTabOne);
},[active,handleSlide,xTabTwo,xTabOne];
返回(
setXTabOne(event.nativeEvent.layout.x)}
onPress={()=>{
setActive(1);
}}>
开的
setXTabTwo(event.nativeEvent.layout.x)}
onPress={()=>{
setActive(0);
}}>
关闭
setTranslateY(event.nativeEvent.layout.height)}>
{
返回(
这里没有数据。。。
);
}}
renderItem={({item,index})=>{
返回hey:{index};
}}
keyExtractor={(item)=>item.toString()}
/>
{
返回hey:{index};
}}
keyExtractor={(item)=>item.toString()}
/>
);
}
有一个名为

它为创建动画提供了一个简单的解决方案

我建议您使用该库来创建顶部选项卡,而不是自己创建选项卡并添加动画

它提供了一个非常干净的解决方案,您可以为每个选项卡创建两个单独的组件,并将它们添加到相应的选项卡中

组件的内容和逻辑不会相互干扰

这样,您就不必在ScrollView中嵌套FlatList

一定要考虑使用图书馆。它为本地应用程序中的导航提供了一些很好的解决方案

这将解决当前实现中当前面临的大多数问题

以下是一些Youtube视频,演示如何使用React Navigation v5:


p、 s:从内容和解释上看,第一个视频要好得多。

我不能完全理解你想要什么,但看起来你想要两个并排的平面列表

第一步是让他们肩并肩。我们将创建一个容器视图,测量它的宽度,在其中有一个我们转换的第二个容器视图,然后在第二个容器视图中,我们将放置两个平面列表

const Example = () => {
  const [active, setActive] = React.useState(0)
  const [width, setWidth] = React.useState(0)
  const [translateX] = React.useState(() => new Animated.Value(0))

  React.useLayoutEffect(() => {
    Animated.timing(translateX, {
      toValue: active * width,
      duration: 300,
      useNativeDriver: true
    }).start()
  }, [active, width, translateX])

  return (
    <View
      style={{flex: 1}}
      onLayout={e => setWidth(e.nativeEvent.layout.width)}
    >
      <Animated.View style={{flexDirection: 'row', transform: [{translateX}]}}>
        <FlatList style={{width: width}} {…flatlist1Props} />
        <FlatList style={{width: width}} {…flatlist2Props} />
      </Animated.View>
    </View>
  )
}
const示例=()=>{
常量[active,setActive]=React.useState(0)
常量[width,setWidth]=React.useState(0)
const[translateX]=React.useState(()=>新的动画.Value(0))
React.useLayoutEffect(()=>{
动画。计时(translateX{
toValue:活动*宽度,
持续时间:300,
useNativeDriver:真的吗
}).start()
},[active,width,translateX])
返回(
setWidth(e.nativeEvent.layout.width)}
>
)
}
现在,当您更改活动选项卡时,它将自动滑到右侧列表


如果您只想使用选项卡在列表之间切换,则不需要额外的滚动视图。

嘿,感谢您分享此信息,我已经在我的应用程序中使用RN v5,但整个问题,我不知道如何将
createMaterialTopTabNavigator
作为一个独立组件,在我的屏幕上使用它,就像这样
//createMaterialTopTabNavigator
嗯,我只是在导航文件中导出一个常量
TopTabs
,然后在任何屏幕中导入它,它工作得很好:“但是