我有两个列表组件或卡片堆栈。 5 副牌,每副牌中有几张牌。我列出了 5 个牌组,并在我单击具有 (selectedItem) 状态的子组件时将其内容传递给子组件。然后我在它的子组件中选取它,并用里面的卡片映射另一个平面列表。
我的问题是,当我单击超出较小甲板限制的索引时。例如,
牌组 1 = 23 张牌 Deck2 = 15 张卡
当我在 Deck1 上索引+1 到超过 15 的任意位置,并尝试单击 Deck2 时,它说它超出范围(显然哈哈),我希望在更换牌组时将其重置为索引(0)。我不能只是添加更多卡片并使它们的数量相同,因为我稍后将设置一个新功能,用户可以构建自己的牌组,并且可以是任意数量的卡片
这是我的套牌组件
const Decks = () => {
const {theme} = useContext(ThemeContext)
let activeColors = colors[theme.mode]
const allbelts = [yellowbelt, orangebelt, greenbelt, brownbeltthree, brownbelttwo, brownbeltone]
const ref = useRef(null);
const [selectedItem, setSelectedItem] = useState(null);
const [deckIndex, setDeckIndex] = useState(0);
const handleItemPress = (item) => {
setSelectedItem(item);
console.log("deckIndex:", deckIndex);
};
return (
<View style={{flex:1}}>
<View style={{flex:1, marginTop: 40}}>
<Text style={[{color:activeColors.primary}, styles.sectionheading]}>
Testing Card Decks
</Text>
<Animated.FlatList
ref={ref}
data={allbelts}
horizontal
keyExtractor={(item, index) => index.toString()}
showsHorizontalScrollIndicator={false}
snapToInterval={ITEM_SIZE}
decelerationRate={0}
bounces={false}
scrollEventThrottle={16}
renderItem={({item, deckIndex}) => (
<View
style={{}}>
<TouchableOpacity
key={deckIndex}
onPress={() => {
handleItemPress(item)
}}>
<Animated.View
style={[{
backgroundColor: item.color,
shadowColor: item.color,
borderColor: activeColors.bgalt},
styles.card]}>
<Text
numberOfLines={2}
style={[{color: item.color === "#F5D143" ? activeColors.black : activeColors.white}, styles.cardtitle]}>
{item.rank_japanese}
</Text>
<Text
numberOfLines={2}
style={[{color: item.color === "#F5D143" ? activeColors.black : activeColors.white}, styles.cardtitle]}>
{item.rank_english}
</Text>
</Animated.View>
</TouchableOpacity>
</View>
)}
/>
<TestingCards selectedItem={selectedItem} deckIndex={deckIndex} />
</View>
</View>
)
}
export default Decks
这是卡片组件
const Card = ({info}) => {
const {theme} = useContext(ThemeContext)
let activeColors = colors[theme.mode]
const rotate = useSharedValue(0);
const frontAnimatedStyle = useAnimatedStyle(() => {
const rotateValue = interpolate(
rotate.value,
[0, 1],
[0, 180]
);
return {
transform: [
{rotateY: withTiming(`${rotateValue}deg`, {duration: 500})}
]
}
})
const backAnimatedStyle = useAnimatedStyle(() => {
const rotateValue = interpolate(
rotate.value,
[0, 1],
[180, 360]
);
return {
transform: [
{rotateY: withTiming(`${rotateValue}deg`, {duration: 500})}
]
}
})
return (
<View style={[styles.cardcontainer]}>
<View style={styles.iconcnt}>
<Pressable
onPress={() => {
rotate.value = rotate.value ? 0 : 1;
}}
style={styles.icon}>
<Icon name="swap-horizontal" size={24} color={activeColors.textcolor} />
</Pressable>
</View>
<View style={styles.cardContent}>
<Animated.View style={[ {backgroundColor: activeColors.bgalt, position:"absolute"}, styles.card, frontAnimatedStyle]}>
<View>
<Text
style={[{color: activeColors.textcolor}, styles.cardtext]}>
{info.q}
</Text>
</View>
</Animated.View>
<Animated.View style={[ {backgroundColor: activeColors.primary}, styles.card, backAnimatedStyle]}>
<View>
<Text
style={[{color: activeColors.textcolor}, styles.cardtext]}>
{info.a}
</Text>
</View>
</Animated.View>
</View>
</View>
)
}
const FlashCards = ({selectedItem, deckIndex}) => {
const {theme} = useContext(ThemeContext)
let activeColors = colors[theme.mode]
const [index, setIndex] = useState(0);
const [lastIndex, setLastIndex] = useState(null);
const [viewPosition, setViewPosition] = useState(0.5);
const flatlistRef = useRef(null)
useEffect(() => {
setLastIndex(selectedItem?.questions?.length - 1);
// console.log("selectedItem:", selectedItem);
console.log("lastIndex at TestingCards:", lastIndex);
flatlistRef.current?.scrollToIndex({
index: index,
animated: true,
viewPosition,
})
} , [index, viewPosition, lastIndex, selectedItem])
if (!selectedItem) {
return null;
}
return (
<View style={[styles.container]}>
<Animated.FlatList
data={selectedItem.questions}
ref={flatlistRef}
index={deckIndex}
keyExtractor={(item, index) => index.toString()}
initialScrollIndex={0}
horizontal
showsHorizontalScrollIndicator={false}
snapToInterval="ITEM_SIZE"
decelerationRate={0}
bounces={false}
scrollEventThrottle={16}
initialNumToRender={10}
onScrollToIndexFailed={index => {
setIndex(0)
const wait = new Promise(resolve => setTimeout(resolve, 0));
wait.then(() => {
flatlistRef.current?.scrollToIndex({ index: index, animated: true });
});
}}
renderItem={({item, index}) => <Card info={item} index={index} totalLength={lastIndex} seefront={true} />}
/>
<View style={styles.btnGroup}>
<TouchableOpacity
onPress={()=>{
setIndex(0);
setViewPosition(0.5);
}}>
<LinearGradient
colors={['rgba(1,102,175,1)', 'rgba(155,24,213,1)']}
start={{ x: 0, y: 1 }}
end={{ x: 1, y: 1 }}
style={styles.btnPrimary}>
<Icon name="chevron-double-left" size={24} color={activeColors.white} />
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity
onPress={()=>{
if (index === 0) {
return;
}
setIndex(index - 1);
setViewPosition(0.5);
}}>
<LinearGradient
colors={['rgba(1,102,175,1)', 'rgba(155,24,213,1)']}
start={{ x: 0, y: 1 }}
end={{ x: 1, y: 1 }}
style={styles.btnPrimary}>
<Icon name="chevron-left" size={24} color={activeColors.white} />
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity
onPress={()=>{
if (index === lastIndex) {
return;
}
setIndex(index + 1);
setViewPosition(0.5);
}}>
<LinearGradient
colors={['rgba(1,102,175,1)', 'rgba(155,24,213,1)']}
start={{ x: 0, y: 1 }}
end={{ x: 1, y: 1 }}
style={styles.btnPrimary}>
<Icon name="chevron-right" size={24} color={activeColors.white} />
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity
onPress={()=>{
if (index === lastIndex) {
return;
}
setIndex(lastIndex - 1);
setViewPosition(0.5);
}}>
<LinearGradient
colors={['rgba(1,102,175,1)', 'rgba(155,24,213,1)']}
start={{ x: 0, y: 1 }}
end={{ x: 1, y: 1 }}
style={styles.btnPrimary}>
<Icon name="chevron-double-right" size={24} color={activeColors.white} />
</LinearGradient>
</TouchableOpacity>
</View>
</View>
)
}
export default FlashCards
useEffect(()=>{
setIndex(0)
}, [deckIndex])
每当牌组索引更改时,它会将索引重置为 0,另一方面,每当您选择不同的牌组时。 这是你想做的吗?