Guide on making a Horizontal Flatlist in React Native displaying 2 rows and 3 columns at a time

I am looking to create a Horizontal Scrolling Flatlist with 2 rows and 3 columns visible, pulling dynamic data from an API. Currently, I have successfully implemented a vertical scrolling Flatlist that resembles the following: https://i.sstatic.net/oJJyA.png. There is a parameter called numOfColumns to set the number of columns, but nothing for rows. Upon attempting to set horizontal={true}, the layout became distorted: https://i.sstatic.net/14VwP.png Additionally, it throws an error indicating that numOfColumns cannot be used with a Horizontal Scrolling Flatlist. Please refer to the attached screenshot for the Desired output: https://i.sstatic.net/X3IMP.png.

This is my code for the Vertical Scrolling Flatlist:

<FlatList
        ref={(ref) => { this.flatListRef = ref; }}
        style={{ width: '90%', marginTop: 10, marginLeft: 10, backgroundColor: 'transparent', borderRadius: 5, alignSelf: 'center' }}
        bounces={false}
        // horizontal={true}
        numColumns={3}
        data={this.state.categoryData}
        renderItem={({ item: data, index }) => {
        return (
          <ServiceView viewWidth={'100%'} viewHeight={'100%'} viewPaddingLeft={1} viewPaddingRight={10} viewPaddingTop={1} viewPaddingBottom={12} serviceName={(globalUserType == 'provider') ? data.services.name : data.name} serviceIconUrl={(globalUserType == 'provider') ? data.services.image : data.image} jobCount={(globalUserType == 'provider') ? '' : ''} showDot={(globalUserType == 'provider') ? false : false} 
           serviceAction={
           () => this.navigateTo('category', data)

         }/>

What modifications should be made to achieve the desired outcome.

Answer №1

class Application extends Component {
  renderListItems = ({item, index}) => {
    <FlatList
      data={item}
      renderItem={this.renderNestedListItems}
    />
  }
  render() {
    return (
      <View>
        <FlatList
          data={this.state.categoryData}
          renderItem={this.renderListItems}
        />
      </View>
    );
  }
}

Answer №2

To create this effect, you can nest a Horizontal Flatlist inside Vertical Flatlist items like so:

Vertical FlatList
<FlatList  
   data={[  
   {imageKey: 'image1', imageKey: 'image2', imageKey: 'image3'}, {imageKey: 'image4', imageKey: 'image5', imageKey: 'image6'}, {imageKey: 'image7', imageKey: 'image8', imageKey: 'image9'} ]}  
    renderItem={({item}) =>  
       <FlatList  
         horizontal={true}
         showsHorizontalScrollIndicator={false}
         data={item}  
         renderItem={({item}) =>  
          <Text>{item.key}</Text>}  
       /> 
   />  

Answer №3

Encountered the same problem while attempting to display the desired output of this question using a JSON array data structure

[{"id": 1, "name": "John", "image": "/api/12.jpg"}, {"id": 2, "name": "James", "image": "/api/14.jpg"}, {"id": 3, "name": "David", "image": "/api/172.jpg"} ...]

I attempted various approaches to render it in a two-row format without success. As a result, I modified the JSON to have the following structure:

    [
      [
         {"id": 1, "name": "John", "image": "/api/12.jpg"}, 
         {"id": 2, "name": "James", "image": "/api/14.jpg"}, 
         {"id": 3, "name": "David", "image": "/api/172.jpg"} 
           ...
      ],
      [
         {"id": 9, "name": "Kim", "image": "/api/12hj.jpg"}, 
         {"id" 10, "name": "Jim", "image": "/api/14ff.jpg"}, 
         {"id" 11, "name": "Rose", "image": "/api/1723.jpg"} 
         ...
      ]
]

You can obtain this JSON format in two ways:

  1. Using backend API
  2. By splitting the JSON array into chunk arrays within a single array using JavaScript code in componentDidMount or a function.

Subsequently, you can use the provided code to achieve the desired output for this question

<ScrollView
      
        horizontal={true}
        showsHorizontalScrollIndicator={false}
      
      >
        //two row formatted JSON array
        {this.state.checkData.map((dd, index) => 
          
            <FlatList
           
            contentContainerStyle={{alignSelf: 'flex-start'}}
            numColumns={3} //<---------- here we can change the number of rows
            data={dd}
            renderItem={({ item: rowData }) => {
           
              return (
                <TouchableOpacity style={{ padding: 6}} onPress={() => this.props.navigation.navigate('RDetails', { id: rowData.id })}>

                  <View style={{flex: 1, height:110, width: 96}}>

                  
                  <View style={{ flex: 1 }}>
                    <Image resizeMode='stretch' style={{ borderRadius: 5, width: 80, height: 70, margin: 2 }} source={{ uri: rowData.image }} />

                  </View>
                  
              </View>

                </TouchableOpacity>
              );

            }
            }
            keyExtractor={(item, index) => index.toString()}
          />
        )}
      </ScrollView>

Answer №4

Another approach is to utilize the _.chunk function from Lodash library.

For instance:

{_.chunk(data, 2).map((item, index) => (
  <View key={index} style={{flexDirection: "column"}>
  {item.map((subItem, subIndex) => (

  <Text key={subIndex}>{subItem}</Text>

  ))}
  </View>
))}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What steps should I take to resolve the 'buffer' issue in my jsonwebtoken?

As I am still new to ReactJS and the MERN stack in general, the code in Activate.js below essentially means that when the useEffect() hook is triggered, we will receive the jwt token extracted from the route parameter/url using the {match} props. This toke ...

Switch the glyphicon based on the open/closed state of the collapsible element - Bootstrap

Is there a way to update the glyphicon based on whether or not a collapsible element is open? This is the code I currently have: <div class="jumbotron ref" data-toggle="collapse" data-target="#collapse"> <div class="row"> <div class=" ...

Issue with executing a jQuery event within a JavaScript object due to application error

I am struggling to comprehend how to set listeners in my JavaScript object. For instance: var obj = function(){ this.test = function(){ console.log('test'); } $(document).on('click','#test',(function(){ ...

How to apply class binding within a v-for loop in Vue.js

When using Vuejs3, I am currently iterating through an array of objects: <div v-for="ligne in lignes" :key="ligne.id" :class="{ 'border-b-2':isSelected }" :id="`ligne_${ligne.id}`" > ...

Utilizing GraphicsMagick with Node.js to Extract Page Frames from Multi-Page TIF Files

I am currently working with a JavaScript script that can successfully convert a single page TIF file to JPEG. However, I am facing difficulties in determining whether "GraphicsMagick For Node" (https://github.com/aheckmann/gm) has the capability to extra ...

Ways to make a div disappear gradually when the user is not active, or completely remove it to reveal a different div

I'm having trouble making this work the way I want it to. I have a div element that acts as a button and I only want it to appear when the user interacts with the screen (via touch or mouse). It should stay visible for 2 seconds after inactivity and t ...

Troubleshooting ng-repeat in AngularJS: Multi checkbox filter malfunction

My AngularJS app has multiple age range filters implemented, but one of them is not functioning correctly and I can't figure out why. You can view a functional example here. The various filters are defined as follows: .filter('five', func ...

Sluggish Bootstrap Carousel Requires Mouseover or Click to Start Sliding

Having Trouble with Bootstrap Carousel Sliding: I've been trying to solve this issue for a while now, but nothing seems to be working. I know this might be a common question, but I really need to fix this problem quickly and none of the suggested solu ...

What is the best way to reset the dropdown state back to its initial setting whenever I change tabs?

I'm currently using a bottom tab bar with three screens, each screen containing a dropdown picker in the header section. The issue I'm facing is that when I have the dropdown open and switch tabs, the dropdown remains open instead of closing auto ...

What is the best way to apply multiple text shadows to a single piece of text using the jQuery ".css()" method?

Is it possible to create multiple text shadows for a single piece of text using the jQuery ".css()" method? I'm currently working on animating the title of a page on my website, which includes adding a 3D effect with multiple shadows. I also want to ...

Looking for a .NET MVC AJAX search solution. How can I enhance the code below?

I am looking to implement a search functionality using AJAX. I have tried using the get method in my controller by passing the search string, but it is not working as expected. Below is a snippet of my controller code, where I retrieve the search value fr ...

Set the class of the list item to "active" class

My approach to styling involves using a UL and li class to contain form selection options. I plan on hiding the radio button and using its value upon form submission. I have managed to enable checking the radio box when the <li> is clicked, but for s ...

Tips for sequentially executing URL requests in Node.JS without triggering a stack overflow

Currently, the code I am using is as follows: function DownloadPage(uri) { request(uri, function (err, res, body) { if (err) { console.log(err); } else { nextURL = FindURLBySomeLogic(body); DownloadP ...

While loop not yielding immediate result with asynchronous function

As a beginner in Node.js, I have successfully connected an LCD Panel and a 4x4 Membrane matrix keypad to my Raspberry Pi. Using Node.js, I have programmed them to work together. My goal is to have the LCD panel immediately display any key pressed on the ke ...

Preserve the newline character within a string in JavaScript

One of my API methods returns an RSA key in the following format: "publickey" : "-----BEGIN PUBLIC KEY-----\nMIGfMA0G CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5WleAVeW5gySd QVFkTi44q1cE\ncWDT2gmcv2mHcWhwI/9YqGV2LqpMASe 4t4XS/88fvTTHafHn1KaL9F7d73T9k4cp&bs ...

Error: The function referenced is not defined when the page loads

Trying to incorporate two different script tags in a single HTML page has been quite a task for me. The first script tag contains the location of a JS file that I need to use for a specific function, while the second script tag is where I have written anot ...

E2E testing on mobile devices with the Webdriver JavaScript client API from the official source

In the Appium documentation, it is noted that the wd.js Webdriver Javascript bindings are mentioned instead of the official bindings. While Appium can work with both clients, the wd.js offers specific mobile methods like touch and shake which are not prese ...

steps for adding text to the header with selenium webdriver

I came across the following code snippet: <body> <table> <tr> <td style= "width:30%;"> <img class = "new" src="images/new-icon.png"> <td> <h1>Hello there!</h1> ...

Tips for updating an Android RelativeLayout dynamically when the orientation shifts without resetting the Activity

I am working with an Android Activity that contains a RelativeLayout. In order to prevent the activity from being recreated when the orientation changes, I have implemented the following method: @Override public void onConfigurationChanged(Configuration n ...

Extracting the call from REST API in JSON format

Working with a third-party database using a REST API, I encountered an error response (as expected). Here is the code snippet: transaction.commit(function(err) { if (err){ var par = JSON.parse(err); \\ leading to error: SyntaxError: Unexpecte ...