Flatlist inside tabs not renedering properly - react-native

I am using tabs component from nativebase.io .
I want to display flatlist in one tab.
In that flatlist srcolling is not working properly lastitems are not dispaying.
Here is my code
<Tabs>
<Tab>
<FlatList
data={this.state.notes}
renderItem={({ item, index }) =>
<View>{item.note}</View>
}
keyExtractor={(item, index) => index.toString()}
extraData={this.state.notes}
ListEmptyComponent={<ErrorMessage />}
/>
</Tab>
</Tabs>

Put Flatlist inside a View with the view's style having flex:1. If it does not work add marginBottom to flatlist
<View style={{flex:1}}>
</View>

Wrapping it in the native base Content component, with the following style, worked for me (beware not to wrap Tab inside Content, that was my mistake):
<Tabs>
<Tab>
<Content style={{flex: 1}} contentContainerStyle={{flex: 1}}>
// your FlatList here
</Content>
</Tab>
</Tabs>

Related

VirtualizedLists should never be nested inside plain ScrollViews with the same orientation

I'm building a mobile application with React Native, and I have a ScrollView inside one of the pages.
The problem is that I have in this page a FlatList so when I go to that page, I get this error:
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation... The thing is, I set the ScrollView nestedScrollEnabled to true and I also set the FlatList's scrollEnabled to false because I don't really need the scroll there (I'm using it to render items from an enum) so I thought that should fix the error, but the error still persist.
It looks like this:
<ScrollView showsVerticalScrollIndicator={false} nestedScrollEnabled={true}>
<MyComponent />
</ScrollView>
And MyComponent has this FlatList:
<FlatList
scrollEnabled={false}
style={{padding: 8,marginBottom: 8,}}
data={categories}
numColumns={numOfColumns}
keyExtractor={category => category}
renderItem={item => renderItem(item.item)}
/>
It essentially looks like this:
<SafeAreaView>
<ScrollView>
<FlatList />
<OTHER COMPONENTS />
</ScrollView>
</SafeAreaView>
Your component FlatList and ScrollView have the same orientation(vertical), so you need put your component inside a ScrollView with horizontal orientation like this:
<View>
<ScrollView nestedScrollEnabled={true} style={{ width: "100%" }} >
<View>
<ScrollView horizontal={true} style={{ width: "100%" }}>
<MyComponent />
</ScrollView>
</View>
</ScrollView>
</View>
The error is because you are using a FlatList inside a ScrollView.
The FlatList is already a scrollable component,
FlatList are accepting props like ListHeaderComponent for rendering header content and ListFooterComponent for rendering footer content. Here you can remove the ScrollView and instead of that you can only render FlatList for making whole page scrollable
You need to change your code as shown below:
const _renderHeader = () => <Text>Your Header</Text>
const _renderFooter = () => <Text>Your Footer</Text>
const _renderFooter = () => <Text>FlatList items</Text>
<SafeAreaView>
<FlatList
data={data}
keyExtractor={(item, index) => String(index)}
renderItem={_renderItem}
ListHeaderComponent={_renderHeader}
ListFooterComponent={_renderFooter}
ListFooterComponentStyle={styles.footerStyle} //If you need to give specific styles for footer component
ListHeaderComponentStyle={styles.headerStyle} //for header comp style
/>
</SafeAreaView>
You don't want to use a ScrollView when you are using a FlatList
You can check the official docs for more clarification

VirtualizedLists should never be nested error

I'm building a mobile application with React Native, and I have a ScrollView inside one of the pages.
The problem is that I have in this page a FlatList so when I go to that page, I get this error:
VirtualizedLists should never be nested inside plain ScroolViews with the same orientation... The thing is, I set the ScrollView nestedScrollEnabled to true and I also set the FlatList's scrollEnabled to false because I don't really need the scroll there (I'm using it to render items from an enum) so I thought that should fix the error, but the error still persist.
It looks like this:
<ScrollView showsVerticalScrollIndicator={false} nestedScrollEnabled={true}>
<MyComponent />
</ScrollView>
And MyComponent has this FlatList:
<FlatList
scrollEnabled={false}
style={{padding: 8,marginBottom: 8,}}
data={categories}
numColumns={numOfColumns}
keyExtractor={category => category}
renderItem={item => renderItem(item.item)}
/>
Can you try to add the property nestedScrollEnabled={true} to both the parents and the children:
<ScrollView showsVerticalScrollIndicator={false} nestedScrollEnabled={true}>
<MyComponent />
</ScrollView>
<FlatList
nestedScrollEnabled={true}
scrollEnabled={false}
style={{padding: 8,marginBottom: 8,}}
data={categories}
numColumns={numOfColumns}
keyExtractor={category => category}
renderItem={item => renderItem(item.item)}
/>
You can use the ListHeaderComponent and ListFooterComponent of the FlatList to render the other parts inside the scrollView. Using a FlatList inside a scrollview limits the performance of the FlatList.
<FlatList
ListHeaderComponent={
<>
<AboveFlatList />
</>
}
data={yourData}
renderItem={this.renderComponents}
...
...
ListFooterComponent={
<>
<BelowFlatList />
</>
}
/>

how to resove the scroll conflict between scrollview and flatList in React Native

I have a flatList and some views in the scrollView, how to make when the flatList scroll to top, we start to scroll flatList not scrollView.
<ScrollView>
<View>
// some child views
</View>
<FlatList
data={this.props.sourceData}
renderItem={this._renderItem}
/>
<View>
.... // some child views
</View>
the scroll conflict is complex, you can try to move the header views into FlatLIst
ListHeaderComponent, and the footer views into the ListFooterComponent
<FlatList
data={DATA}
ListHeaderComponent={"your header component"}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor={item => item.id}
ListFooterComponent={"your bottom views"}
/>
you can also read my question, in the description I give some solution. I hope it can help you

Create a layout where one part is static and other is scrollable on swipe in Native-Base

I got one tab screen on my App that I would like to have a layout separated into 2 parts.
1) Would be the top container which is static, no matter if you swipe up/down. It also contains Native-Base tabs.
2) Each tab would have a FlatList or ScrollView I guess to make it scroll on swipe?
This is the basic idea:
Now, it seems that this scrollable behavior is being added by the Native-Base "Container" component, when I changed from Container to View, my screen changed of course, but at least it wasn't scrollable at all. But the tabs weren't displaying, it was completely empty.
How can I achieve this layout?
This is my current layout skeleton:
<Container>
<Header>
... some header title and icon, doesn't matter ...
</Header>
<Content>
<View>
<Tabs>
<Tab heading={ TabHeading here }>
<ScrollView>
<Text>Some Content Here</Text>
</ScrollView>
</Tab>
<Tab heading={ TabHeading here }>
<ScrollView>
<Text>Some Content Here</Text>
</ScrollView>
</Tab>
<Tab heading={ TabHeading here }>
<ScrollView>
<Text>Some Content Here</Text>
</ScrollView>
</Tab>
</Tabs>
</View>
</Content>
</Container>
It is actually the Content component that is causing the scrolling as it is wrapped in a react-native-keyboard-aware-scroll-view https://github.com/GeekyAnts/NativeBase/blob/master/src/basic/Content.js
To disable the scroll on the Content all you have to do is pass false to the scrollEnabled prop
<Content scrollEnabled={false}>
...
</Content>
That should stop the scrolling of the top.

Flatlist covering the a element with absolute position

I was trying to make a view that I wanted to come over a flatlist so that on clicking it user can reach the top.But the flatlist was covering that element.
<View style={{backgroundColor:'#e6e6e6',flex:1,}>
<View style={{position:'absolute'}}>
<Text>Scroll To Reload</Text>
</View>
<FlatList refreshing={this.state.refresh} onRefresh={()=>this.refreshAllTweets()}
data={tweets}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) =>
<TweetItem onPress={()=>this.goToDetail(item.id)} onImagePress={()=>this.toggleModal(item.id)}
onCommentPress={()=>this.showComments(item.id)} tweet={item}/>}
/>
</View>
Each child in a view is rendered in order, and ultimately stacked on top of each other until all the children are rendered. As the view you want on the top is being rendered first it is going to be at the bottom. Change your code so that the view that you want on the top is rendered last. i.e. move it to the bottom of the view.
<View style={{backgroundColor:'#e6e6e6',flex:1}}>
<FlatList
refreshing={this.state.refresh}
onRefresh={()=>this.refreshAllTweets()}
data={tweets}
keyExtractor={(item, index) => index.toString()}
renderItem={({item}) => <TweetItem onPress={()=>this.goToDetail(item.id)} onImagePress={()=>this.toggleModal(item.id)} onCommentPress={()=>this.showComments(item.id)} tweet={item}/>}
/>
<View style={{position:'absolute', top: 0}}>
<Text>Scroll To Reload</Text>
</View>
</View>
As the view is now absolutely positioned you may wish to give it an actual position.
Update for comment
Flatlist covering the a element with absolute position
FlatLast has a prop called ListFooterComponent it takes a React Component Class, a render function, or a rendered element. So you could update your FlatList by adding the following prop.
<FlatList
...
ListFooterComponent={
<View>
<Text>Scroll To Reload</Text>
</View>
}
/>
This will attach the view as a footer to the FlatList, so it will be visible when the bottom of your FlatList is reached.
Check out the docs for more information about FlatLists.