13

问题总结

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

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

我试过的

  1. 我试过把其他所有东西都从屏幕上移开
  2. 我也尝试过从头开始创建一个新屏幕。
  3. 我已经将屏幕作为 Stack Navigator 中的初始路线进行了测试,它运行良好,但我仍然无法在屏幕加载时渲染轮播。
  4. 我也尝试过切换到基于类的反应组件,但没有帮助。

代码

带有轮播的组件

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
  }
});

反应导航配置

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" 
  }
);

概述问题的图片

屏幕加载时,轮播不渲染 屏幕加载时,轮播不渲染

在旋转木马上滑动后 在旋转木马上滑动后

4

5 回答 5

26

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

我强烈建议不要使用延迟,因为它不是确定性的,并且每个设备都会发生变化。

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

于 2019-11-24T09:46:18.793 回答
7

我们的项目也出现了同样的问题,一个小技巧可以帮助我们。我们已将默认加载状态设置为 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
    ......... 
  }

于 2019-09-05T03:48:52.767 回答
4

我通过简单地使用 removeClippedSubviews={false} 解决了它

于 2020-12-25T14:31:37.783 回答
0
<Carousel
          ref={c => {
            _carousel = c;
          }}
          data={ENTRIES1}
          renderItem={_renderItem}
          sliderWidth={375}
          itemWidth={100}
          onSnapToItem={index => {
            setSelectedStat(ENTRIES1[index]);
          }}
        />
      </

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

于 2019-09-05T05:15:26.070 回答
-1

您可以创建自己的自定义轮播。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 });

如需进一步参考,请通过提供的链接。

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

于 2021-01-27T05:03:06.303 回答