39

I've got (what I thought was) a simple FlatList which renders a list of Cards (code below)

Problem: the list renders, but won't scroll to fully display the last element in the list, OR to the content below the FlatList

What I've tried: basically everything in related SO questions:

  • Removing ALL styling
  • Wrapping the FlatList in a View or a ScrollView or both
  • Adding style={{flex: 1}} to the FlatList or wrappers (this causes **ALL* content to disappear)

Any ideas?

<FlatList
        data={props.filteredProducts}
        renderItem={({item}) => (
          <TouchableOpacity onPress={() => props.addItemToCart(item)}>
            <Card
              featuredTitle={item.key}
              image={require('../assets/icon.png')}
            />
          </TouchableOpacity>
        )}
        keyExtractor={item => item.key}
        ListHeaderComponent={
          <SearchBar />
        }
      />
...
<Other Stuff>
rubie
  • 1,906
  • 2
  • 20
  • 26
  • Have you checked if it's nested inside a ScrollView with a FlexGrow: 1 + your FlatList has also a flexGrow: 1? ...cause if yes it will not work... – Hend El-Sahli Mar 22 '19 at 12:37
  • Yes @HendEl-Sahli - I've tried both adding and removing a scrollview, tried to just render the list with no containers - no joy I'm afraid – rubie Mar 22 '19 at 12:39
  • So please try replacing `renderItem` component with a very simple `Text` for example ... to see if it has to do with that. – Hend El-Sahli Mar 22 '19 at 12:51

12 Answers12

90

Add style={{flex: 1}} for each View element who is a parent for FlatList.

סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
Eugene P.
  • 1,517
  • 12
  • 16
  • 5
    That's awesome. I can't believe it was just that. I literally spent 4 hours and 43 minutes trying to figure this out. – martin Mar 29 '21 at 21:00
  • 6
    Could you provide the reasoning/intuition behind this being the solution? – A. Khaled Jul 12 '21 at 11:28
  • Sometimes all you need to is to add "MarginBottom" so to your Flatlist style so it reach the "Edge" of your component , like this style = {{marginBottom : 150 }} , make sure to keep increasing the value until it starts scrolling – Khalid Tamine Jan 03 '23 at 19:09
  • adding marginbottom/paddingBottom works but seems "hacky" `Add style={{flex: 1}} for each View element who is a parent for FlatList`. This is the most appropriate solution,however i'd recommend adding marginbottom/paddingBottom for 10-20 so everything looks nice – louis Mar 31 '23 at 07:02
  • This is greate thsi just save my day – sam Jul 04 '23 at 11:40
16

I had the same issue and just found the solution. Add the prop ListFooterComponentby giving it a React element/component. I just passed a view with the preferable height and it worked for me perfectly.

Here is the code snippet:

<FlatList
        data={DATA}
        renderItem={({ item }) => (<ListItem itemData={item} />) }
        keyExtractor={item => item.id}
        ListFooterComponent={<View style={{height: 20}}/>}
      />

This works 100%!

Vars Zakaryan
  • 251
  • 2
  • 6
12

The ultimate solution is ✔

Any view/subview that holds a flatlist must have a flex of 1 - Regardless of how deep.

So if you apply this and it's not working, check your styling and make sure there's no mistake somewhere.

Joseph Ajibodu
  • 1,093
  • 10
  • 14
4

I'm not sure if your scenario is exactly the same as one I encountered on a project a few months ago, but I noticed that I had to add a margin/padding (depends on what you prefer) to lift the bottom of the scrollable container. This was usually because a parent container seemed to interfere with the styling of the scrollable element.

Have you tried adding flexGrow: 1 to your styling in place of flex?

Nnanyielugo
  • 401
  • 4
  • 13
  • Thanks for the explanation - adding a `marginBottom` does help with the scrolling, but the content below is still not there. I suspect the problem might be coming from elsewhere - a parent container as you suggest - in which case I'll accept this answer once I've confirmed that. Also, `flexGrow` did nothing, but it was good to learn about it nonetheless, thanks – rubie Mar 22 '19 at 11:48
  • Not yet, unfortunately - didn't have much time over the weekend to work on it, but will come back and update / accept answer this week – rubie Mar 25 '19 at 08:13
  • 2
    hey guys, I'm getting the same issue, any solution? – suisied Sep 18 '19 at 23:39
4

My case is a little different, in that I used FlatList inside bottom sheet provided by reanimated-bottom-sheet package. But the problem was the same: scrolling didn't show the last item properly.

The way I did was I calculated and set the height of the view that included the FlatList. To make it look better when there is bottom inset, I gave more bottom margin to the last item of the FlatList by doing like this:

<FlatList
    data={results}
    keyExtractor={(item) => item.name}
    scrollEnabled={bottomSheetIndex == 1 ? true : false}
    renderItem={({ item }) =>
        <LocationInfo
            bottom={results[results.length - 1].id == item.id ? insets.bottom : 0}
            result={item}
            wait={waitState[item.id]}
            bsIndex={bottomSheetIndex}
        />
    }
/>

const LocationInfo = ({ bottom, result, wait, bsIndex }) => {

    return (
        <View style={[styles.container, { paddingBottom: bottom }]}>
            ... 

for insets, see react-native-safe-area-context.

Brian Hong
  • 930
  • 11
  • 15
3

Remove flex:1 from the FlatList and leave only the parent View.

Lima Neto
  • 53
  • 1
  • 9
3

Add flex: 1 to child into renderItem

<View style={{ height: `93%` }}>
  <FlatList
    contentContainerStyle={{ minHeight: `100%` }}
    scrollEnabled={true}
    ...props
    renderItem={({item}) => (
      <View style={{ flex: 1 }}>
        ...
      </View>
    )}
2

I had the same problem. What I did was to provide a marginBottom to the parent view of the FlatList with size that is equivalent (or a little larger) than the size of the rendered item .

<View style={{marginBottom: HEIGHT_OF_CELL + 60, flexGrow:1}}>
    <FlatList
         keyExtractor={(item, index) => index.toString()}
         data={posts}
         renderItem={renderItem}
    />
            
</View>
        
Meo Flute
  • 1,211
  • 11
  • 9
1

I method I used to resolve this is by setting the parent view to the FlatList's background color to a visible color(e.g red). Then adjust the margin bottom for that view so that it is large enough for all the contents in the FlatList to be viewed.

In my case the parent view was wrapped in another view which I could not give the flex: 1 style to.

Wilfred Mulenga
  • 378
  • 3
  • 10
1

use dimensions for parent view and set height as given:

const screenHeight = Dimensions.get('window').height - 100 
 <View style={{...styles.container,height:screenHeight}}>
 ....All child components
 </View>
Sallar Rabiei
  • 630
  • 1
  • 12
  • 33
0

adding flex:1 to my render item worked for me

 <FlatList
      data={data}
      renderItem={({ item }) => (
        <ListItem
          onPress={() => console.log('ok')}
          bottomDivider
          rightTitle={
            <Divider style={{ marginBottom: 4, backgroundColor: item.status, width: '50%', height: '11%', borderRadius: 10 }} />
          }
          titleProps={{ numberOfLines: 1 }}

          rightSubtitle={item.date}
          rightTitleStyle={{ fontFamily: 'poppins' }}
          rightSubtitleStyle={{ fontFamily: 'poppins' }}
          titleStyle={{ fontFamily: 'poppins' }}
          subtitleStyle={{ fontFamily: 'poppins' }}
          title={item.device}
          subtitle={item.type}
          leftAvatar={{ source: item.icon, rounded: false }}
          **style={{ flex: 1 }}**
        />
      )}
      keyExtractor={item => item._id}
      ListHeaderComponent={renderHeader}
      ListFooterComponent={renderFooter}
      onEndReached={handleLoadMore}
      onEndReachedThreshold={0.2}

    />
nipek
  • 810
  • 1
  • 9
  • 22
0

Try use to resolve the props ListFooterComponent

<FlatList
    data={data}
    renderItem={renderItems}
    ListFooterComponent={<View style={{height: 200}}/>}
/>
General Grievance
  • 4,555
  • 31
  • 31
  • 45
Hfajardo
  • 11
  • 3