0

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

1 Answer 1

0

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;

Sign up to request clarification or add additional context in comments.

3 Comments

Appreciate for the Answer but can you tell me how Horizontal works in Horizontal FlatList !?
Do you mean the behavior of a single FlatList in Horizontal? if yes the see this: reactnative.dev/docs/flatlist#horizontal
Ok, I am aware of this reactnative.dev/docs/flatlist#horizontal, suppose if i want to implement this , <FlatList horizontal ... renderItem={({ item }: any) => { return ( <FlatList horizontal ... /> ) }/>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.