Reputation: 11734
I've 4 FlatList
s with maxHeight
set to 200
inside a ScrollView
.
<ScrollView>
<FlatList/>
<FlatList/>
<FlatList/>
<FlatList/>
</ScrollView>
and when I try to scroll a FlatList
, it doesn't scroll but the ScrollView
scrolls. How do I fix this issue ?
Full Source Code
import { Component, default as React } from 'react';
import { FlatList, ScrollView, Text } from 'react-native';
export class LabScreen extends Component<{}> {
render() {
return (
<ScrollView>
{this.renderFlatList('red')}
{this.renderFlatList('green')}
{this.renderFlatList('purple')}
{this.renderFlatList('pink')}
</ScrollView>
);
}
getRandomData = () => {
return new Array(100).fill('').map((item, index) => {
return { title: 'Title ' + (index + 1) };
});
};
renderFlatList(color: string) {
return (
<FlatList
data={this.getRandomData()}
backgroundColor={color}
maxHeight={200}
marginBottom={50}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
);
}
}
Upvotes: 61
Views: 154737
Reputation: 1411
Caution
There are some reported cases in which ScrollView imported from 'react-native' is now working properly. For instance this nested scroll issue, I even tried
nestedScrollEnabled
Still it didn't work
On the other hand importing ScrollView from
import { ScrollView } from 'react-native-gesture-handler';
is working fine even without nestedScollEnabled.
Thanks.
Upvotes: 0
Reputation: 528
Make sure you add nestedScrollEnabled
to each flatlist / scrollview but most importantly make sure you do not use pos absolute and allow your screen to flex to be able to scroll
Upvotes: 0
Reputation: 1630
I'm surprised that none of the answers actually worked for me. I went searching for the reason ScrollView and FlatList don't work together and found that there are props on FlatList that can accomodate the header and footer areas above and below my FlatList. If I use this I can make sure the whole screen still scrolls and I don't get the error.
Here is where I found this answer and I've put an example below.
<View>
<FlatList
ListHeaderComponent={<View><Text>Top of screen content goes here</Text></View>}
keyExtractor={(item) => item._id}
data={[{_id: 1, text: 'one'}, {_id: 2, text: 'two'}]
renderItem={({item}) => (<View><Text>{item.text}</Text></View>)}
/>
</View>
Upvotes: 6
Reputation: 74
The better answer is to put a horizontal ScrollView inside of the other ScrollView and then the FlatList
Upvotes: -1
Reputation: 314
This is the simplest answer that requires zero configuration.. and it works like a charm
<ScrollView horizontal={false}>
<ScrollView horizontal={true}>
<Flatlist
....
....
/>
</ScrollView>
</ScrollView>
Upvotes: 22
Reputation: 2691
I was having a very similar issue until I came across an almost complete solution in a very helpful comment on one of the GitHub issues for the react-native project: https://github.com/facebook/react-native/issues/1966#issuecomment-285130701.
The issue is that the parent component is the only one registering the scroll event. The solution is to contextually decide which component should actually be handling that event based on the location of the press.
You'll need to slightly modify your structure to:
<View>
<ScrollView>
<View>
<FlatList />
</View>
<View>
<FlatList />
</View>
<View>
<FlatList />
</View>
<View>
<FlatList />
</View>
</ScrollView>
</View>;
The only thing I had to change from the GitHub comment was to use this._myScroll.contentOffset
instead of this.refs.myList.scrollProperties.offset
.
I've modified your fully working example in a way that allows scrolling of the inner FlatLists.
import { Component, default as React } from "react";
import { View, FlatList, ScrollView, Text } from "react-native";
export default class LabScreen extends Component<{}> {
constructor(props) {
super(props);
this.state = { enableScrollViewScroll: true };
}
render() {
return (
<View
onStartShouldSetResponderCapture={() => {
this.setState({ enableScrollViewScroll: true });
}}
>
<ScrollView
scrollEnabled={this.state.enableScrollViewScroll}
ref={(myScroll) => (this._myScroll = myScroll)}
>
{this.renderFlatList("red")}
{this.renderFlatList("green")}
{this.renderFlatList("purple")}
{this.renderFlatList("pink")}
</ScrollView>
</View>
);
}
getRandomData = () => {
return new Array(100).fill("").map((item, index) => {
return { title: "Title " + (index + 1) };
});
};
renderFlatList(color: string) {
return (
<View
onStartShouldSetResponderCapture={() => {
this.setState({ enableScrollViewScroll: false });
if (
this._myScroll.contentOffset === 0 &&
this.state.enableScrollViewScroll === false
) {
this.setState({ enableScrollViewScroll: true });
}
}}
>
<FlatList
data={this.getRandomData()}
backgroundColor={color}
maxHeight={200}
marginBottom={50}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
</View>
);
}
}
Hopefully you find this useful!
Upvotes: 40
Reputation: 19
Use map instead of Flatlist, same result and don't break the application
Minha conta {
buttonsProfile.map(button => (
<ArrowButton
key={button.key}
title={button.title}
iconName={button.icon}
toogle={button.toogle}
onPress={() => {navigation.navigate(button.route)}}
/>
))
}
Upvotes: -1
Reputation: 191
I fixed my problem with nested FlatList
not being able to scroll items on android by simply importing FlatList
import { FlatList } from 'react-native-gesture-handler';
If this would not work, also try to import ScrollView
.
import { ScrollView } from 'react-native';
// OR
import { ScrollView } from 'react-native-gesture-handler';
You need to play around with these imports, at least it worked in my case.
Upvotes: 19
Reputation: 2539
We can use the built-in nestedscrollenabled prop for the children FlatList/ScrollView components.
<FlatList nestedScrollEnabled />
This is only required for Android (Nested scrolling is supported by default on iOS).
Upvotes: 135
Reputation: 149
Try to set the FlatList as nested
nestedScrollEnabled={true}
Upvotes: 10