Reputation: 2246
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:
FlatList
in a View
or a ScrollView
or bothstyle={{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>
Upvotes: 44
Views: 56794
Reputation: 706
Moving all styling from the FlatList
view and adding a View
as the main container worked for me.
<View style={{flex: 1, width: '100%', paddingVertical: 10, alignItems: 'center'}}>
<FlatList
data={data}
keyExtractor={item => item.code}
renderItem={({ item }) => renderItem(item)}
ListHeaderComponent={renderHeader}
/>
</View>
Inside my renderItem and renderHeader, I had an AutoHeightWebView
component that was messing up my screen. Deleting all flex: 1
and keeping it only in the Flatlist's new view parent worked wonders!
Upvotes: 0
Reputation: 11
Try use to resolve the props ListFooterComponent
<FlatList
data={data}
renderItem={renderItems}
ListFooterComponent={<View style={{height: 200}}/>}
/>
Upvotes: 0
Reputation: 1676
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.
Upvotes: 14
Reputation: 11
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>
Upvotes: 1
Reputation: 321
I had the same issue and just found the solution. Add the prop ListFooterComponent
by 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%!
Upvotes: 23
Reputation: 1301
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>
Upvotes: 2
Reputation: 398
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.
Upvotes: 1
Reputation: 31
Add
flex: 1
to child intorenderItem
<View style={{ height: `93%` }}>
<FlatList
contentContainerStyle={{ minHeight: `100%` }}
scrollEnabled={true}
...props
renderItem={({item}) => (
<View style={{ flex: 1 }}>
...
</View>
)}
Upvotes: 3
Reputation: 1833
Add style={{flex: 1}}
for each View element who is a parent for FlatList.
Upvotes: 107
Reputation: 850
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}
/>
Upvotes: 0
Reputation: 1084
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
.
Upvotes: 4
Reputation: 403
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
?
Upvotes: 4