Currently what is happening right is that I have 4 categories namely : all , category 1, category 2 and category 3
Now here’s the scenario If i am from the all category and choose category 1 the scroll effect animation works perfect same goes to all -> category 2, all -> category 3 or category 1 -> category 2 and so on.
Now if I do it inverted like from category 3 -> category 2 it works fine also but when I tried category 3 or category 2 -> all category the scroll effect animation doesn’t work.
Here’s my code
interface Item {
id: string;
title: string;
}
const getItemMargin = (isFirstIndex: boolean, isLastIndex: boolean) => {
return {
marginLeft: isFirstIndex ? 24 : 0,
marginRight: isLastIndex ? 24 : 8,
};
};
interface CSProps<T extends Item> extends ViewProps {
items: T[];
onSelectItem: (id: T['id']) => void;
selectedId: string;
// categoryIndex: number;
}
const CategoryList = <T extends Item>({
style,
items,
onSelectItem,
selectedId,
// categoryIndex,
...rest
}: CSProps<T>): JSX.Element => {
const {t} = useTranslation();
const flatList = useRef<FlatList>(null);
const [cIndex, setCIndex] = useState<number>(0);
useEffect(() => {
if (selectedId === 'all') {
setCIndex(0);
} else if (selectedId === 'category 1') {
setCIndex(1);
} else if (selectedId === 'category 2') {
setCIndex(2);
} else {
setCIndex(3);
}
const timeout = setTimeout(() => {
console.log(`Check cIndex : ${cIndex}`);
flatList?.current?.scrollToIndex({
index: cIndex,
animated: true,
viewOffset: 10,
});
}, 100); // You can adjust the delay as needed
return () => clearTimeout(timeout);
}, [cIndex, items.length, selectedId]);
/**
* For smooth transition of category tab on FlatList
* @param data
* @param index
* @returns
*/
const getItemLayout = (data: any, index: any) => {
return {
length: styles.item.height,
offset: styles.item.height * index,
index,
};
};
const onMomentumScrollEnd = (event: any) => {
const windowWidth = Dimensions.get('window').width;
const currentIndex = Math.round(
event.nativeEvent.contentOffset.x / windowWidth,
);
if (currentIndex !== cIndex) {
console.log(`Check cIndex: ${currentIndex}`);
setCIndex(currentIndex);
}
};
const renderItem = ({item, index}: {item: T; index: Number}) => {
const backgroundColor =
item.id === selectedId
? Colors.PRIMARY_01_BLUE_4
: Colors.PRIMARY_03_WHITE;
const color =
item.id === selectedId
? Colors.PRIMARY_03_WHITE
: Colors.PRIMARY_01_BLUE_4;
const borderWidth = item.id === selectedId ? 0 : 1;
const isFirstIndex = index === 0;
const isLastIndex = index === items.length - 1;
return (
<TouchableOpacity
testID={item.title.replace(/[A-Z]/g, c => c.toLowerCase())}
onPress={() => onSelectItem(item.id)}
style={[
styles.item,
{backgroundColor},
{borderWidth},
getItemMargin(isFirstIndex, isLastIndex),
]}>
<Text style={[styles.title, {color}]}>{t(item.title)}</Text>
</TouchableOpacity>
);
};
return (
<View style={style} {...rest}>
<FlatList
ref={flatList}
horizontal
// initialScrollIndex={cIndex}
data={items}
renderItem={renderItem}
keyExtractor={({id}) => String(id)}
extraData={selectedId}
showsHorizontalScrollIndicator={false}
onMomentumScrollEnd={onMomentumScrollEnd}
snapToAlignment="center"
onScrollToIndexFailed={info =>
setTimeout(() => {
console.log(
`Check if failed to scrollIndeX: ${JSON.stringify(info)}`,
);
flatList.current?.scrollToIndex({
index: info.index,
animated: false,
});
}, 500)
}
getItemLayout={getItemLayout}
/>
</View>
);
};
const styles = StyleSheet.create({
input: {
...Typography.BODY_2_16_BOOK,
borderBottomColor: Colors.PRIMARY_03_GREY_3,
borderBottomWidth: 0.7,
paddingVertical: 12,
},
inputActive: {
borderBottomColor: Colors.PRIMARY_01_BLUE_4,
},
item: {
borderRadius: 16,
borderStyle: 'solid',
borderColor: Colors.PRIMARY_03_GREY_3,
paddingHorizontal: 16,
height: 28,
justifyContent: 'center',
alignItems: 'flex-start',
},
title: {
...Typography.REMARK_1_13_MEDIUM,
},
});




