I have a React-Native component where im trying to create a “image” gallery of different items for the user to select.
After multiple hours of debugging i dont understand why the center item always is abit offset?
I have implemented a solution where the “GradeSelector” is using a flatList and Animations to create a “gallery” where the user can select the current item, my issue is that im not able to correcly center my items, and after a buch of testing with different parameters ive not yet been able to center it correctly.
My code:
const { width } = Dimensions.get("window");
const ITEM_SIZE = width * 0.3;
const SPACER_ITEM_SIZE = (width - ITEM_SIZE) / 2;
const scrollX = useRef(new Animated.Value(0)).current;
const flatListRef = useRef<FlatList>(null);
const renderItem = ({ item, index }) => {
if (item.key === "left-spacer" || item.key === "right-spacer") {
return (
<View
style={{
width: SPACER_ITEM_SIZE,
height: 50,
}}
></View>
);
}
const inputRange = [
(index - 3) * ITEM_SIZE,
(index - 2) * ITEM_SIZE,
(index - 1) * ITEM_SIZE,
index * ITEM_SIZE,
(index + 1) * ITEM_SIZE,
];
const scale = scrollX.interpolate({
inputRange,
outputRange: [0.6, 0.75, 1, 0.75, 0.6],
extrapolate: "clamp",
});
return (
<Animated.View
style={[
{
width: ITEM_SIZE,
justifyContent: "center",
alignItems: "center",
backgroundColor: "yellow",
},
{ transform: [{ scale }] },
]}
>
<TouchableOpacity
style={{
width: ITEM_SIZE,
height: ITEM_SIZE * 0.9,
justifyContent: "center",
alignItems: "center",
borderRadius: 10,
backgroundColor: item.color,
}}
onPress={() => handlePress(index)}
>
<Text style={{ color: "#fff", fontSize: 16 }}>{item.text}</Text>
</TouchableOpacity>
</Animated.View>
);
};
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Animated.FlatList
ref={flatListRef}
data={[{ key: "left-spacer" }, ...data, { key: "right-spacer" }]}
renderItem={renderItem}
keyExtractor={(item) => item.id || item.key}
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{ alignItems: "center" }}
snapToInterval={ITEM_SIZE}
snapToAlignment="center"
decelerationRate="fast"
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { x: scrollX } } }],
{ useNativeDriver: true }
)}
/>
</View>
);
Current center:
Wanted center: