react-native-snap-carousel 无法正确呈现

react-native-snap-carousel doesn't render properly

问题总结

我正在使用 react-native-snap-carousel,但它没有正确呈现。它仅在被滑动后呈现,我需要在屏幕最初呈现时呈现。当我将屏幕分配给我的 BottomTabNavigator 的初始路线或在 React Navigation 中的 Stack Navigator 中的初始路线时,轮播会完美呈现。当我将完全相同的屏幕分配给 Stack Navigator 中的任何其他路线时,它不会呈现轮播,直到我滑动它。

我需要在我的 Stack Navigator 中使用带轮播的屏幕作为第二条路线,但我不知道如何让它正常工作。

我试过的

  1. 我试过将屏幕上的其他所有内容都去掉
  2. 我也试过从头开始创建一个新屏幕。
  3. 我已经在 Stack Navigator 中将屏幕作为初始路径进行了测试,并且 它工作得很好,但我仍然无法让旋转木马在 屏幕加载。
  4. 我也试过切换到基于 class 的 React 组件 没有帮助。

代码

带轮播的组件

import React, { useState } from "react";
import { View, Text } from "react-native";
import { useDispatch } from "react-redux";
import styles from "./StatSelectorStartComp.style";
import HeaderText from "~/app/Components/HeaderText/HeaderText";
import Carousel from "react-native-snap-carousel";
import LargeButton from "~/app/Components/Buttons/LargeButton/LargeButton";
import NavigationService from "~/app/services/NavigationService";
import { saveStartCompStatCategory } from "~/app/Redux/actions/dailyCompActions";

const StatSelectorStartComp = ({}) => {
  const dispatch = useDispatch();
  const ENTRIES1 = ["Kills", "Wins", "K/D", "Win %"];
  const [selectedStat, setSelectedStat] = useState(ENTRIES1[0]);

  const _renderItem = ({ item, index }) => {
    return (
      <View style={styles.slide}>
        <Text style={styles.compSelectStatCarousel}>{item}</Text>
      </View>
    );
  };

  return (
    <View style={styles.container}>
      <View style={styles.headerTextView}>
        <HeaderText header={"Configure Competition"} />
      </View>
      <Text style={styles.h5Secondary}> Which stat will you track?</Text>
      <View style={styles.selectStatView}>
        <Text style={styles.mediumGreyedOut}>Most {selectedStat} Wins</Text>
        <Carousel
          ref={c => {
            _carousel = c;
          }}
          data={ENTRIES1}
          renderItem={_renderItem}
          sliderWidth={375}
          itemWidth={100}
          onSnapToItem={index => {
            setSelectedStat(ENTRIES1[index]);
          }}
        />
      </View>
      <View style={styles.buttonView}>
        <LargeButton
          onPress={() => {
            dispatch(saveStartCompStatCategory(selectedStat));
            NavigationService.navigate("CompAddFriends");
          }}
          buttonText="Add Friends"
        />
      </View>
    </View>
  );
};

export default StatSelectorStartComp;

轮播组件的样式

import { StyleSheet } from "react-native";
import { backgroundColor } from "~/app/Constants";
import {
  h5Secondary,
  mediumGreyedOut,
  compSelectStatCarousel
} from "~/app/FontConstants";

export default StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "space-between",
    backgroundColor
  },
  headerTextView: {
    flex: 1
  },
  h5Secondary,
  selectStatView: {
    flex: 3
  },
  mediumGreyedOut,
  compSelectStatCarousel,
  buttonView: {
    flex: 2
  }
});

React 导航配置

const StartCompStack = createStackNavigator({
  StartFriendsComp: {
    screen: StartFriendsComp
  },
  StatSelectorStartComp: {
    screen: CarouselTest
  },
  CompAddFriends: {
    screen: CompAddFriends
  },
  FinalCompScreen: {
    screen: FinalCompScreen
  }
});

const ProfileStack = createStackNavigator({
  Profile: {
    screen: ProfileScreen
  },
  Settings: {
    screen: SettingsScreen
  }
});

const BottomTabNav = createBottomTabNavigator(
  {
    Home: {
      screen: HomeScreen
    },
    Competitions: {
      screen: Competitions
    },
    StartComp: {
      screen: StartCompStack,
      navigationOptions: () => ({
        tabBarVisible: false
      })
    },
    CompScreen: {
      screen: CompScreen
    },
    Friends: {
      screen: FriendsDrawer
    },
    Profile: {
      screen: ProfileStack
    },
    FacebookFriendsList
  },
  {
    tabBarComponent: CustomTabNav,
    initialRouteName: "Home" 
  }
);

图片概括问题

加载屏幕时,轮播未呈现

在旋转木马上滑动后

我们的项目也遇到了同样的问题,一个小技巧可以帮助我们。我们已将默认加载状态设置为 true,并在 componentDidMount 中将状态设置为 false 以显示 Carousel

试试这个,它可能对你有帮助

state = { loading: true };

  componentDidMount() {
    setTimeout(() => {
      this.setState({ loading: false });
    }, 10);
  }
  render() {
    if(this.state.loading) {
      return null;
    }

    // return component render which contain Carousel
    ......... 
  }

<Carousel
          ref={c => {
            _carousel = c;
          }}
          data={ENTRIES1}
          renderItem={_renderItem}
          sliderWidth={375}
          itemWidth={100}
          onSnapToItem={index => {
            setSelectedStat(ENTRIES1[index]);
          }}
        />
      </

我认为问题在于给出静态高度和宽度。尝试动态计算高度和宽度,然后显示它。这里的动态是指计算设备的高度和宽度,然后对其进行计算。

有一个实验性配置(当前为 v3.8.4)- removeClippedSubviews - 默认设置为 true。将其设置为 false 解决了我的问题。

我强烈建议不要使用延迟,因为它不是确定性的,并且会因设备而异。

感谢在评论中写下这篇文章的@auticcat。

我通过简单地使用 removeClippedSubviews={false}

解决了它

您可以创建自己的自定义轮播。 Carousel 最终结果如下所示-

     goToNextPage = () => {
    const childlenth = this.getCustomData().length;
    selectedIndex = selectedIndex + 1;
    this.clearTimer();
    if (selectedIndex === childlenth) {
        this.scrollRef.current.scrollTo({ offset: 0, animated: false, nofix: true });
        selectedIndex = 1;
    }
    this.scrollRef.current.scrollTo({
        animated: true,
        x: this.props.childWidth * selectedIndex,
    });
    this.setUpTimer();
}

// pushing 1st element at last
 getCustomData() {
    const {data} = this.props;
    const finaldata = [];
    finaldata.push(...data);
    finaldata.push(data[0]);
    return finaldata;
}

这是循环轮播背后使用的主要逻辑。 在这里,我们再次推送列表中的第一个项目,然后当滚动到达最后一个位置时,我们让滚动视图滚动到第一个位置,因为现在第一个和最后一个元素相同,我们用这样的动画滚动到第一个位置

this.scrollRef.current.scrollTo({ offset: 0, animated: false, nofix: true });

如需进一步参考,请查看所提供的 link。

https://goel-mohit56.medium.com/custom-horizontal-auto-scroll-looped-carousel-using-scrollview-42baa5262f95