Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tabs with FlatLists inside ScrollView - like Instagram or Twitter profile pages

I would like to have a set of tabs that each have a FlatList inside a ScrollView. This is similar to the layout of Instagram or Twitter.

I am aware that there are some issues with having a FlatList inside a ScrollView and getting onEndReached to be triggered as only the ScrollView's scroll events are registered?

This results in the inner onEndReached being called immediately on load and then over and over again...

If you make the ScrollView scrollEnabled false and flex: 1 instead of flexGrow: 1 then you can get the inner FlatLists to scroll but the outer content doesnt... This looks like this:

enter image description here

I think there are a lot of people who are struggling with this problem and I can't find a really clear solution anywhere.

I have also tried to implement react-navigation-collapsible with createMaterialTopTabNavigator to create the tabs. However, you can't implement a pull-to-refresh on the whole screen?

Any help would be much appreciated.

Update

I've also looked into implementing: FlatList inside ScrollView doesn't scroll

AND I've looked at dynamically toggling the scrollEnabled property (even though it creates a re-render. This ALMOST works... but there is an issue with the ScrollView height being flexGrow: 1 and the inner FlatList not filling the space...

SECOND UPDATE

This snack almost does the right thing... https://snack.expo.io/@satya164/collapsible-header-with-tabview It uses react-native-tab-view and collapses the header using animation. If the header was a component, it could fetch data on load but you would only get a pull-to-refresh on the inner list (unlike Instagram).

Related questions:

There is an issue with onEndReached being called infinitely - https://github.com/facebook/react-native/issues/18887 - https://github.com/facebook/react-native/issues/6002

FlatList cannot work right inside a ScrollView... - https://github.com/facebook/react-native/issues/12827#issuecomment-320509824

Flatlist inside ScrollView - https://github.com/facebook/react-native/issues/19971

FlatList inside ScrollView doesn't scroll - https://github.com/facebook/react-native/issues/19971

FlatList child is calling onEndReached on render - https://github.com/react-native-community/react-native-tab-view/issues/501

React Native Nested Listview Triggers onEndReached Multiple Times - React Native nested ListView triggers onEndReached multiple times on loading

When FlatList wrapped inside ScollView, onEndReached doesnt work expected. - https://github.com/facebook/react-native/issues/22008

Twitter-like profile layout - How to create Twitter like profile layout? But I believe that the answer is now not correct.

like image 824
Alex Chin Avatar asked Feb 14 '19 15:02

Alex Chin


1 Answers

Probably you should work with Animated api to handle the translateY of the content of TabView and the header.

For example:

<View>    <Header />    <TabView /> //With lists <View> 

Your Header should have a position: 'absolute' and a fixed height, and your TabView should have a paddingTop transparent to match the Header height. Once you scroll one or other list, you should move the Header with transform: [{ translateY }] and your TabView too, so it can match the position of the Header until it clamps.

EDIT:

Sorry, didn't saw your update about the expo example.

Your expo example has some errors. For example if you scroll one list (to hide the header) your second list will have a blank space.

You should set the height of the list (TabView containing the lists) to be the window height - header size clamped. With this you can set translateY of the tabview to be the size of the header. Once you start scroll up, you should translateY both the header and the tabview until it clamps. From that point you should only scroll the list.

Another solution would be increase the height of tabView onScroll to match the translateY of header

like image 129
WitaloBenicio Avatar answered Sep 17 '22 13:09

WitaloBenicio