Horizontal scrolling in FlatList - React Native - react-native

I'm listing data with flatlist. But while listing the data, it lists it vertically, I want it to be sorted horizontally. So instead of scrolling down, I want to scroll left and right. I think it's called pagingEnabled. How can I do that?
<FlatList
style={{
flex: 1
}}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
data={this.state.allReasons}
keyExtractor={(item,index)=>index.toString()}
renderItem={({ item ,index}) => {
return (
<ScrollView onScroll={(event)=>{
this.setState({
activePage:Math.round(parseFloat(event.nativeEvent.contentOffset.x/Dimensions.get('window').width))
})
}}
style={{width:'100%'}} showsHorizontalScrollIndicator={false} pagingEnabled={true} horizontal={true}>
<View style={{width:'100%'}}>
<Image style={{ resizeMode: 'contain',width:Dimensions.get('window').width,height:250}} source={{uri:"http://ledslider.stechomeyazilim.com/" + item.Slider_Image}}/>
.....
</View>

Add horizontal prop in Flatlist like
horizontal={true}
Try removing scrollview from item may cause the issue

Related

FlatList initialScrollIndex not working as expected

I am using a horizontal FlatList as menu bar for my application. The FlatList must scroll to the clicked item and I am using initialScrollIndex for this.
But the problem is that it scrolls but the content is not visible many times.
My code
<FlatList
ref={listRef}
data={headerMenuChannels}
style={{
backgroundColor: applicationTopBar.buttonBarColor,
width: Dimensions.get('window').width,
}}
showsHorizontalScrollIndicator={false}
horizontal={true}
onScrollToIndexFailed={error => console.log('scroll failed', error)}
initialScrollIndex={screenNumber}
renderItem={v => (
<View
key={v.index}
onLayout={ref => onMenuLayout(ref, v.index)}>
<Text
onPress={() => {
setScreenNumber(v.index);
}}>
{v.item}
</Text>
</View>
)}
/>
Video of the problem
here
With initialScrollIndex you should use getItemLayout prop. Something like this:
getItemLayout={(data, index) => ({
length: width,
offset: width * index,
index,
})}

Aligning ListHeaderComponent vertically above Horizontal Flatlist

I have a horizontal Flatlist and right above it i want to add a custom header. I have an option to wrap the Flatlist & custom header in a ScrollView - which isn't good practice according to RN 0.61
VirtualizedLists should never be nested inside plain ScrollViews with
the same orientation
Another option is to use:
ListHeaderComponent
<FlatList
horizontal
ListHeaderComponent = {<CustomHeader>What can we help you find?</CustomHeader> }
keyExtractor = {(item) => item.unique_id }
data = {this.props.categories}
contentContainerStyle={{ flexGrow: 1}}
renderItem={ ({item}) => (
<TouchableOpacity>
<View>
<Image
style={{
height:80,
width:100}}
source={{uri:'some_url'}}
/>
<Title>{item.category}</Title>
</View>
</TouchableOpacity>)}
/>
Whilst the above works with a vertical Flatlist, it completely fails with a horizontal flatlist with my use case.
Expected:
Actual Output:
What are the possible fixes?
You can Conditional Rendering like this, just a workaround
{this.props.category.length ? <CustomHeader>What can we help you find?</CustomHeader> : null}
<FlatList
horizontal
keyExtractor = {(item) => item.unique_id }
data = {this.props.categories}
contentContainerStyle={{ flexGrow: 1}}
renderItem={ ({item}) => (
<TouchableOpacity>
<View>
<Image
style={{
height:80,
width:100}}
source={{uri:'some_url'}}
/>
<Title>{item.category}</Title>
</View>
</TouchableOpacity>)}
/>

flatlist is stuttering in arabic language

I am using the Flatlist to display the products horizontally. When I am using the app in English mode RTL that time Flatlist is working fine, after switch the Arabic LTR the Flatlist stuttering, after drag this is come again in first where I start to the drag the Flatlist items.
<ScrollView>
<FlatList
contentContainerStyle={styles.flatlist}
data={list}
keyExtractor={(item) => `post__${item.id}`}
renderItem={this.renderItem}
showsHorizontalScrollIndicator={false}
horizontal
pagingEnabled={isPaging}
onEndReached={false && this._nextPosts}
/>
</ScrollView>
<ScrollView
horizontal
style={{ flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row' }}
>
<FlatList
contentContainerStyle={styles.flatlist}
data={list}
keyExtractor={(item) => `post__${item.id}`}
renderItem={this.renderItem}
showsHorizontalScrollIndicator={false}
horizontal
pagingEnabled={isPaging}
onEndReached={false && this._nextPosts}
/>
</ScrollView>
I found the solution need to add the
horizontal
style={{ flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row' }}
line in the ScrollView.
https://github.com/facebook/react-native/issues/11960#issuecomment-278918568

react-native : horizontal scrollview won't work inside flatlist

I have a horizontal scrollview inside my flatlist but it won't scroll.
renderRow = ({ item }) => {
return (
<View style={{width:'100%', backgroundColor:'transparent'}}>
<ScrollView horizontal={true}>
//I have multiple images here
</ScrollView>
</View>
)
}
This is my flatlist
<FlatList
keyExtractor={(item, index) => index.toString()}
data={this.state.data}
renderItem={this.renderRow}
/>
is it possible to put horizontal scrollview inside flatlist?
Try to add style width:100% in ScrollView
<ScrollView horizontal={true} style={{width:'100%'}}>
//I have multiple images here
</ScrollView>
You can try somethig like this:
<ScrollView horizontal={true} style={{flex: 1}}>
//Place Mutiple image in ScrollView.
</ScrollView>

React Native FlatList not scrolling to end

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}
/>