Flatlist is not scrollable - react-native

I am trying to create a scrollable grid in my app but I am unable to scroll it . Tried everything but nothing is working .
return (
<FlatList
data={data}
renderItem={({item}) => (
<GridImage style={styles.imageThumbnail} imageUri={item} numColumns={3} />
)}
/>
);
};

Wrap flatlist in a view and give height & width to it.
return (
<View style={{ height:600,width:600 }}>
<FlatList
data={this.state.data}
renderItem={({item}) => <Country name={item} />}
/>
</View>
);

Related

Flatlist inside into Scrollview

I try to show some items inside a ScrollView, but it shows me this error.
VirtualizedLists should never be nested inside plain ScrollViews with
the same orientation - use another VirtualizedList-backed container
instead.
I tried with scrollview, but i need columns in my list.
return (
<View>
<ScrollView style={{backgroundColor: '#612d7c'}} >
<View style={{marginTop: headerHeight}}>
<ProfilePictureItem />
</View>
<View style={styles.badgeTextContainer}>
<Text style={styles.badgeText}>Badges</Text>
</View>
<Card style={styles.card}>
<FlatList
data={products}
style={{marginBottom: 20}}
renderItem={itemData => (
<BadgeItem key={itemData.item.id} style={styles.badge}/>
)}
numColumns={3}
/>
</Card>
</ScrollView>
</View>
);
That's right, either you display a ScrollView or a FlatList if you use the same scroll direction. For example, you can use the FlatList with the ListHeaderComponent prop.
You can try this:
function renderListHeader() {
return (
<View style={{marginTop: headerHeight}}>
<ProfilePictureItem />
</View>
<View style={styles.badgeTextContainer}>
<Text style={styles.badgeText}>Badges</Text>
</View>
)
}
.....
return (
<FlatList
data={products}
ListHeaderComponent={renderListHeader()}
style={{marginBottom: 20}}
renderItem={itemData => (
<BadgeItem key={itemData.item.id} style={styles.badge}/>
)}
numColumns={3}
/>
);

React-Native horizontal FlatList

I have flat list that is returning a JSON feed with nested objects / arrays. All is working except horizontal listing, it still lists each item vertically. Does anyone know how I can list the returned images horizontally instead of vertically?
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={[data]}
horizontal={true}
keyExtractor={({ id }, index) => id}
renderItem= {({ item, index }) => (
<View>
{item.items.map((v, i) => (
<TouchableOpacity onPress={() => props.navigation.navigate('Pdp', {articleid: item.id})}>
<View style={styles.container}>
<Image style={styles.imgyoutubeprev} source={{ uri: chkValue(v.snippet.thumbnails.high.url) }} />
<Image style={styles.imgyoutubebtnoverlay} source={require('../assets/youtubebtn.png')} />
</View>
</TouchableOpacity>
))}
</View>
)}
/>
)}
We would need to have a bit more information about the styles that you are using. If the items are rendered vertically instead of horizontal then this is likely caused by the element that surrounds the FlatList.
Make sure that the View or other component that contains the FlatList has the flex: 1 style or at least takes up the full width. Otherwise the horizontal elements would still wrap and be rendered vertically.
Bonus tip: You might be able to remove the View child from the TouchableOpacity by moving the styles.container to the TouchableOpacity and then replacing the inner View with a Fragment.
Thanks all. The big difference was removing the view surrounding the item.items.map. I haven't had to force flex: 1 against the view, though I have forced flex 1 across the whole screen, so possibly thats helped as well. Thanks again all.
The code I used (taking on your code reduction, and is working as expected is;
return (
<View>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={[data]}
horizontal={true}
horizontal
keyExtractor={({ id }, index) => id}
renderItem= {({ item, index }) => (
item.items.map((v, i) => (
<TouchableOpacity onPress={() => props.navigation.navigate('Pdp', {articleid: item.id})}>
<Image style={styles.imgyoutubeprev} source={{ uri: chkValue(v.snippet.thumbnails.high.url) }} />
<Image style={styles.imgyoutubebtnoverlay} source={require('../assets/youtubebtn.png')} />
</TouchableOpacity>
))
)}
/>
)}
</View>
);
};

Get warning after update react : VirtualizedLists should never be nested inside plain ScrollViews with the same orientation

i'm working on a react native app and i updated my react version.
I use Flatlist inside a ScrollView.
I got this warning :
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
My component :
return (
<KeyboardAvoidingView behavior="padding" enabled style={styles.keyboardAvoidingView}>
<SafeAreaView style={styles.keyboardAvoidingView}>
<Header
..
}}
containerStyle={styles.headerContainer}
rightComponent={{
...
}}
/>
<ScrollView style={styles.body}>
<View style={styles.titleSection}>
<Text style={styles.stepTitle}>Étape 1/3</Text>
<Text style={styles.questionTitle}>Quel contact voulez-vous partager ?</Text>
</View>
<View>
<FlatList
data={contacts}
renderItem={({ item, index }) => (
<TouchableHighlight onPress={() => this.onItemClickHandler(index, item.id, item.firstName, item.lastName)} style={styles.touchableHighlight}>
<View>
<ListItem
chevron={
(
<Icon
color={this.state.selectedIndex === index
? `${defaultTheme.palette.white.main}`
: `${defaultTheme.palette.primary.dark}`}
name="chevron-right"
size={40}
type="material"
/>
)
}
containerStyle={
this.state.selectedIndex === index
? styles.selected
: styles.notSelected
}
leftElement={
(
<Icon
...
/>
)
}
title={`${item.firstName} ${item.lastName}`}
titleStyle={this.state.selectedIndex === index
? [styles.titleStyle, styles.titleSelected]
: [styles.titleStyle, styles.defaultTitle]}
/>
</View>
</TouchableHighlight>
)}
extraData={this.state.selectedIndex}
keyExtractor={(item) => item.email}
ListHeaderComponent={this.renderHeader(searchValue)}
style={styles.flatListStyle}
ListFooterComponent={this.renderFooter}
/>
{
(contacts.length > 0 && page > 0)
&& <CustomButton title="Afficher la suite" onPress={() => this.makeRemoteRequest()} loading={loading} disabled={loading} />
}
</View>
</ScrollView>
</SafeAreaView>
</KeyboardAvoidingView>
);
I had the same issue. See my code
What I did is the component which I wanted to render outside the flatlist I included that inside the ListHeaderComponent and removed the Scrollview component. Now its working fine without any warning.
Below is the previous code:
<ScrollView >
<ReadCard data={this.state.data}/>
<FlatList
data={this.state.data.related}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
ItemSeparatorComponent={ListSeprator}
/>
</ScrollView>
Below is the changed code without any warning:
<FlatList
data={this.state.data.related}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
ItemSeparatorComponent={ListSeprator}
ListHeaderComponent={
<ReadCard data={this.state.data}/>
}
/>

Last item in React native flat list goes beyond screen

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.

React Native Elements Handle ListItem click

I use React Native Elements library to create list items inside of a Flat List. I show a list of users and i need to handle style after a click.
My code is :
<View style={{flex: 1}}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<ListItem
leftAvatar={{source: {uri: item.avatar}}}
title={`${item.firstName} ${item.lastName}`}
// subtitle={item.email}
chevron
onPress={this.onItemClickHandler}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
<Button
title='Suivant'
onPress={() => navigation.navigate('LastStepToShare')}
containerStyle={{marginBottom: 15}}
/>
</View>
How can i edit the background of a clicked ListItem item ?
You could do something like this:
<FlatList
data={this.state.data}
renderItem={({item, index}) => {
const {selectedIndex} = this.state;
const itemStyle = selectedIndex === index ? styles.selected : styles.notSelected;
return (
<ListItem
leftAvatar={{source: {uri: item.avatar}}}
title={`${item.firstName} ${item.lastName}`}
style={itemStyle}
// subtitle={item.email}
chevron
onPress={() => this.onItemClickHandler(index)}
/>
)
}}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
and in your onItemClickHandler function, set the selectedIndex value in the state using this.setState.
Basically, get the selected index thanks to the onPress event and compare it to the current index from the renderItem function. Based on that, you can set a style variable.
Here is a sample code snippet, this might help you :
<FlatList
data={this.getAllTask()}
renderItem={({ item, index }) =>
<TouchableHighlight
onPress={() => {this.props.navigation.navigate('OtherPage', {text: item.task_name, index: index})}}>
<View style={styles.customRowContainer}>
<View style={styles.listContainer}>
<Image source={require('../Img/ic_task_icon.png')} style={styles.photo} />
<View style={styles.container_text}>
<Text style={styles.title}>
{item.task_name}
</Text>
<Text style={styles.description}>
ETA : {item.task_eta}
</Text>
</View>
</View>
</View>
</TouchableHighlight>}
keyExtractor={item => item.id}
/>
If you need to change the background color only while the item is pressed (ie. change back when the finger is up), you can customise underlayColor and activeOpacity of the underlying TouchableHighlight to achieve what you need:
<ListItem underlayColor="#ff0000" activeOpacity={1} title="Title" onPress={yourClickHandler} />
You can easily store the state of active Item, and set state on onItemClickHandler function, now you can change style according to state of item (is it active or not)
<View style={{ flex: 1 }}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
style={this.state.active === item.id ? styles.active : null} //***
leftAvatar={{ source: { uri: item.avatar } }}
title={`${item.firstName} ${item.lastName}`}
// subtitle={item.email}
chevron
onPress={() => this.onItemClickHandler(item.id)}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
<Button
title='Suivant'
onPress={() => navigation.navigate('LastStepToShare')}
containerStyle={{ marginBottom: 15 }}
/>
</View>
and
this.onItemClickHandler(id) => {
this.setState({
active: id
})
}