Reputation: 1
`The problem here is the nested scroll View. In the UI there is a parent Flat list as a vertical, inside it child flat list with a Horizontal and then there is one scrollView with a Horizontal
what we are expecting, we are unable to Scroll the inner Scroll View, every time the Flatlist with the Horizontal will scroll.
I have tried to implement the Flatist instead of the inner Scroll View! still, it didn't work! also used react-native-gesture-handler but the issue persisted.
Following is the code for FlatList :`
<FlatList data={Object.entries(ExpData)}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
nestedScrollEnabled
renderItem={({ item }: any) => {
let key = item[0];
let val = item[1];
let mealId = item[1][0].meal_category_id;
return <View>
<View style={styles.expContainerHeader}>
<Text style={styles.nearByHeaderText}> {key} </Text>
<TouchableOpacity style={{ flexDirection: "row" }}
onPress={() => handleSeeAll(mealId, key)}>
<Text style={styles.seeAllText}>See All</Text>
<Image
source={IMG_CONST.seeAll}
style={styles.seeAll}
testID="seeAllIconId"
/>
</TouchableOpacity>
</View>
<FlatList data={val}
horizontal
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
nestedScrollEnabled
renderItem={({ item }: any) => {
let id = item.id;
const CurrencyPriceIndicator =
(priceindicator: any, currency: any) => {
let currencysymbol = '';
if (priceindicator == 1) {
currencysymbol = `${currency}`;
} else if (priceindicator == 2) {
currencysymbol = `${currency}${currency}`;
} else if (priceindicator == 3) {
currencysymbol = `${currency}${currency}${currency}`;
}
return currencysymbol;
}
return (
<View style={styles.expCardContaioner} key={Date()}>
<ScrollView horizontal={true}
style={styles.expImgContainer}
showsHorizontalScrollIndicator={false}>
{item?.images?.map((elem: any) => {
return (
<TouchableOpacity
key={elem.id} onPress={() => handleImagePress(id)}>
<Image
source={{ uri: elem.url }}
style={styles.images}
testID="locationIconId"
/>
</TouchableOpacity>
);
})}
</ScrollView>
<TouchableOpacity style={styles.expTitleView}
onPress={() => handleViewExpCard(id)}>
<Text style={styles.expTitleText}>
{item.title} </Text>
<Text style={styles.mealTypeTitle}>
{item.meal_type} •
{CurrencyPriceIndicator(item.price_indecator, currency)}</Text>
<View style={styles.ratingContainer}>
<Rating
readonly={true}
type='custom'
ratingImage={IMG_CONST.STAR}
ratingColor='#F59E0B'
ratingBackgroundColor='#CBD5E1'
ratingCount={5}
startingValue={item.average_rating}
imageSize={25}
fractions={2}
style={{ paddingVertical: 1 }}
/>
<Text style={styles.rate}>
{item.average_rating} ({item.total_reviews})
</Text>
</View>
<View
style={{ flexDirection: 'row', marginBottom: wp(4) }}>
<Image
source={IMG_CONST.location}
style={styles.locationIcon}
testID="locationIconId"
/>
<Text style={styles.rate}>
{item.city_name}
{location ? `• ${milesToKilometers(item.distance, currency)}`: null}
</Text>
</View>
</TouchableOpacity>
</View>
)
}} />
</View>
}}
/>
const styles = StyleSheet.create({ seeAll: { marginLeft: wp(1), alignSelf: 'center', height: wp(2.5), width: wp(2), }, images: { height: hp(15), width: hp(15), marginEnd: wp(2), borderRadius: 20 }, locationIcon: { height: wp(5), width: wp(5), }, rate: { color: '#000', marginLeft: wp(2) }, ratingContainer: { flexDirection: 'row', alignItems: "center", paddingVertical: hp(1.2) }, mealTypeTitle: { marginTop: wp(2.5), color: '#000', fontWeight: "500", fontSize: Scale(16) }, expTitleView: { marginLeft: wp(3), }, expTitleText: { color: '#000', fontWeight: '700', fontSize: Scale(20), }, expImgContainer: { marginTop: wp(3), marginLeft: wp(3), marginBottom: wp(3), zIndex: 99 }, expImgs: { backgroundColor: 'red', height: hp(15), width: hp(15), borderRadius: Scale(20) }, expCardContaioner: { marginTop: wp(2), marginRight: wp(3), backgroundColor: '#ffffff', paddingVertical: wp(1), borderRadius: Scale(20), marginBottom: wp(3), width: width - Scale(50), }, expContainer: { margin: wp(5), marginTop: wp(1.5) },
nearByHeaderText: {
fontSize: Scale(16),
fontWeight: "500",
color: "#120d26"
},
seeAllText: {
fontSize: Scale(16),
fontWeight: "500",
color: "#747688"
},
expContainerHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
margin: wp(1)
},
});
Upvotes: 0
Views: 87
Reputation: 617
Using nested Flatlist is not a good solution at all. There are several built-in props inside Flatlist
like ListHeaderComponent
and ListFooterComponent
we can pass our custom component inside it. And inside our component we can use a Flatlist
as well.
Here is an example where you can use Vertical
and Horizontal
scroll at the same time.
const YourComponent = () => {
//// & flatlist function for Order list ///
const renderItemFunction = ({ item, index }) => {
return (
<YourCustomeComponet
title={item.clientName}
status={item.status}
date={item.date}
document={item.numDocuments}
billStatus={item.paymentStatus}
userName={item.agentName}
/>
);
};
//// & flatlist HeaderComponent function///
const listHeaderComponent = () => {
return (
<>
<FlatList
data={StatusData}
ref={flatListRef}
horizontal={true}
keyExtractor={(item) => item.id}
horizontal={true}
showsHorizontalScrollIndicator={false}
renderItem={renderItemList}
/>
</>
);
};
// const listFooterComponent = () => {
// return (
// <>
// <FlatList
// data={StatusData}
// ref={flatListRef}
// horizontal={true}
// keyExtractor={(item) => item.id}
// horizontal={true}
// showsHorizontalScrollIndicator={false}
// renderItem={renderItemList}
// />
// </>
// );
// };
return (
<>
<FlatList
ListHeaderComponent={listHeaderComponent}
ListHeaderComponentStyle={styles.headerComponent}
data={yourData}
contentContainerStyle={{ alignItems: "center" }}
showsVerticalScrollIndicator={false}
keyExtractor={(item) => item.id}
renderItem={renderItemFunction}
// You can use ListFooterComponent as well
// ListFooterComponent={listFooterComponent}
// ListFooterComponentStyle={styles.footerComponent}
/>
</>
);
};
const styles = StyleSheet.create({
headerComponent: {},
});
export default YourComponent;
Upvotes: 0