I have a menu with 3 levels in my app, and I would like just to refresh data in my flat list more than using 3 different screens (like I'm doing now), but, I don't know, how to manage the back button.
Can you help me?
<View style={styles.container}>
<Navbar enableBackButton title={t('product.menu.LABEL_CATEGORY')} />
<FlatList
style={[styles.container, { paddingBottom: insets.bottom }]}
data={menuData}
keyExtractor={(item) => item.catalog.code}
renderItem={({ item }) => <ItemMenu name={item.catalog.name} goTo="Menu2" subItem={item} />}
/>
</View>
<FlatList
data={categoryData}
horizontal
showsHorizontalScrollIndicator={false}
pagingEnabled
bounces={false}
renderItem={({ item }) => (
<HomeTabCategoryItem
categorySelected={categorySelected}
setCategorySelected={setCategorySelected}
item={item}
/>
)}
keyExtractor={(item) => item.id}
/>
This the code that I am using but whenever I try to scroll right it automatically scrolls back to leftmost
Done...
just remove pagingEnabled
I can scroll only in case when I change SafeAreaView to ScrollView but I get this error
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
{subCategoryIsLoading ? (
<ActivityIndicator
size='large'
color={primColor}
style={{marginTop: 150}}
/>
) : (
<SafeAreaView>
<View style={styles.containerSubCategory}>
<FlatList
showsVerticalScrollIndicator={false}
data={filterCatTrue()}
keyExtractor={item => item._id}
renderItem={({item}) => {
return (
<View style={styles.containerImages}>
<TouchableHighlight onPress={() => console.log(item._id)}>
<Image
source={{
uri: `${urlImages}subCategories/${item.image}`,
}}
style={styles.imageSubCategory}
/>
</TouchableHighlight>
</View>
)
}}
/>
<FlatList
horizontal={false}
numColumns={2}
showsVerticalScrollIndicator={false}
columnWrapperStyle={{
justifyContent: 'space-between',
}}
data={filterCatFalse()}
keyExtractor={item => item._id}
contentInset={{bottom: 60}}
renderItem={({item}) => {
return (
<View style={styles.containerImagesWide}>
<TouchableHighlight>
<Image
source={{
uri: `${urlImages}subCategories/${item.image}`,
}}
style={styles.imageSubCategoryWide}
/>
</TouchableHighlight>
</View>
)
}}
/>
</View>
</SafeAreaView>
)}
Virtualized lists, that means 'SectionList' and 'FlatList' for example, are performance-optimized meaning they improve memory consumption when using them to render large lists of content. The way this optimization works is that it only renders the content that is currently visible in the window, usually meaning the container/screen of your device. It also replaces all the other list items same sized blank space and renders them based on your scrolling position.
Now If you put either of these two lists inside a ScrollView they fail to calculate the size of the current window and will instead try to render everything, possibly causing performance problems, and it will of course also give you the warning mentioned before.
Check this post, it perfectly explains your problem.
I have a flatlist with some styles on the outer containers as follows.
<View style={containerStyle}>
// more jsx components come here
<View style={resultContainerStyle}>
<FlatList
data={results}
keyExtractor={(item) => (item.id && item.id.toString())}
renderItem={({ item, index }) => (
<ListItem
item={item}
selectItem={selectItem}
/>
)}
/>
</View>
</View>
The issue is that the last values of the list go beyond the view of the screen and there is no way to view it unless a fixed height is put on the parent container. Is it possible to do this without a fixed height.
A SafeAreaView can be used to limit the view to the "safe" areas of the screen(avoiding the notch and curved bottom. Checkout the following example
<SafeAreaView style={containerStyle}>
// more jsx components come here
<View style={resultContainerStyle}>
<FlatList
data={results}
keyExtractor={(item) => (item.id && item.id.toString())}
renderItem={({ item, index }) => (
<ListItem
item={item}
selectItem={selectItem}
/>
)}
/>
</View>
</SafeAreaView>
more examples can be found at the react native docs.
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>
Add style={{flex: 1}} for each View element who is a parent for FlatList.
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%!
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.
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?
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.
Remove flex:1 from the FlatList and leave only the parent View.
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>
)}
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>
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.
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>
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}
/>