I need help in setting correctly a Flatlist in my React Native app.
What I need is:
I have a View
Inside that view i have a title on top and a bottom below.
Between I want to insert a Flatlist that displays a list of elements, but i want a fixed height and scroll capability to see all elements from the list.
Part of my code:
return (
<Container theme={theme}>
<TitleContainer theme={theme}>
<Title theme={theme}>Destino da publicação:</Title>
</TitleContainer>
<ButtonContainer>
<Option theme={theme} onPress={() => setView('contacts')}>
<Texto theme={theme}>Contactos</Texto>
</Option>
<Option theme={theme} onPress={() => setView('groups')}>
<Texto theme={theme}>Grupos</Texto>
</Option>
</ButtonContainer>
<ContactContainer>
{view === 'contacts' && (
<FlatList
key="contactList"
data={contactListFiltered}
renderItem={renderItemContact}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Sem contatos
</Text>
)}
keyExtractor={(item) => item.email}
/>
)}
{view === 'groups' && (
<FlatList
key="groupListShare"
data={groupListFiltered}
renderItem={renderItemGroup}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Não existem grupos criados
</Text>
)}
keyExtractor={(item) => item}
/>
)}
<ButtonContainer>
<Option onPress={close} theme={theme}>
<MaterialCommunityIcons
name="cancel"
size={VMHSize(811, 25)}
color={theme.mainColor}
/>
<OptionText theme={theme}>Cancelar</OptionText>
</Option>
</ButtonContainer>
</ContactContainer>
</Container>
);
};
I already tried many suggestions I readed, but or the flatlist appears with the height I want but i cant scroll the content, or the flatlist renders all elements pushing the bellow content of the view to outside the view.
To explain the idea if the code:
I´m building a social media app, something alike facebook. I have a view Posts, where i have a flatlist that displays the posts from the feed for the user.
Then, each post have a Options button with many options, one is to share the post with another friend. In the code above, i need to show in a view with a fixed height, a list with the friends. If i have many friends, i need to scroll that list within the limited size view. I´m using another flatlist to list the friends.
Can anybody help me? Thanks!
Well, I resolved my problem with a ScrollView and nestedScrollEnabled prop.
<ScrollView style={{ height: VMHSize(811, 300) }} nestedScrollEnabled>
{view === 'contacts' && (
<FlatList
key="contactList"
data={contactListFiltered}
renderItem={renderItemContact}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Sem contatos
</Text>
)}
keyExtractor={(item) => item.email}
/>
)}
{view === 'groups' && (
<FlatList
key="groupListShare"
data={groupListFiltered}
renderItem={renderItemGroup}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Não existem grupos criados
</Text>
)}
keyExtractor={(item, index) => item + index}
/>
)}
</ScrollView>
Related
i get the 22 images from the react-native-image-filter.
this image are base64 format,
Here is the code on render runction.
render() {
const { images, imageIndex } = this.state;
return (
<View style={styles.container}>
{images?.length > 21 && <View style={{ flex: 1 }}>
<Image resizeMode={'contain'} source={{ uri: `data:image/png;base64,${images[imageIndex]?.base64}` }} style={{ width: 400, flex: 1 }} />
</View>}
<View style={{ height: 140, paddingVertical: 20 }}>
<ScrollView horizontal>
{images?.map((item, index) => {
return (
<View style={[{ marginHorizontal: 10 }, styles.center]}>
<Image
resizeMode={'cover'}
key={index.toString()}
onPress={() => this.setState({ imageIndex: index })}
source={{ uri: `data:image/png;base64,${item.base64}` }}
style={{ width: 80, height: 100, borderRadius: 8 }} />
</View>
)
})}
</ScrollView>
</View>
</View>
);
}
everything is good, but the image loading is too slow.
How can i increate the loading speed? Help me...
The problem is most definitely in Base64-encoded images.
The slowdown is because React Native has to pass quite long Base64 strings back and forth through the Native<->JS bridge, plus native platform has to parse Base64 and convert it into the correct memory representation for the native image view. Many optimizations provided by the platform are therefore missed.
Ideally, all image manipulations should happen on the native platform, and none of the actual image data should even touch JS.
I'd advise to try these two libraries for more performant filter implementations:
https://github.com/GregoryNative/react-native-gl-image-filters
https://github.com/iyegoroff/react-native-image-filter-kit
I've got a minimal test ReactNative test in Expo running. 2 screens, both just have Text within a View.
This is run on a MBP, and tested on my Android device (Note10+) via QR code.
It is not just slow, it's unresponsive most of the time, when it does navigate to a tab on click then it's either instant (rarely) or takes 5-10 seconds. But usually nothing happens.
There are no errors being shown, replacing the same code with a Stack or Drawer works fine.
2 basic screens:
function StackScreenA0({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test stack 0</Text>
<Button title="goto 1" onPress={() => navigation.navigate('Screen A1')} />
</View>
);
}
function StackScreenA1({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test stack 0</Text>
<Button title="goto 0" onPress={() => navigation.navigate('Screen A0')} />
</View>
);
}
App code (minus imports):
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator initialRoutName='Screen A0'>
<Tab.Screen name="Screen A0" component={StackScreenA0} />
<Tab.Screen name="Screen A1" component={StackScreenA1} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
I've never used Expo before but I can't imagine this is normal behaviour but cannot see a reason for it working so badly.
EDIT: I've found other devices to test and tabs are fine on iPad4, Galaxy9, but seriously bad on Note10+.
Rich
Focusing only in renderItem and FlatList.
Avatars are being displayed like this.
Some are circles some with rounded corners and defaultSource avatar are squares.
Can't seem to find a solution..
I've tried using borderRadius as an Image prop instead of using inside of the Image style.
renderItem = ({item}) => (
<ListItem
bottomDivider={true}
Component={TouchableScale}
friction={90}
tension={100}
activeScale={0.95}
title={item.name}
titleStyle={styles.titleStyle}
subtitle={item.email}
subtitleStyle={styles.subStyle}
leftAvatar={<Image source={{uri: 'my URL'}}
defaultSource={require('../resources/defaultAvatar.png')}
style={{width: 45, height: 45, borderRadius: 80}}
resizeMode={'contain'}/>}
onPress={() => this.onUserPress(item)}
chevronColor="white"
chevron
/>
)
render() {
const {search} = this.state;
return (
<View>
<SearchBar
platform={"ios"}
ref={search => this.search = search}
placeholder={'Escrever aqui...'}
color={'#808080'}
onChangeText={this.SearchFilterFunction}
value={search}
round={true}
inputStyle={{fontSize: 16}}
inputContainerStyle={{height: 35}}
containerStyle={{height: 53}}
showLoading={true}
/>
<FlatList
data={this.state.usersFilter.sort((a, b) => a.name.toString().localeCompare(b.name))}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
</View>
);
}
I would like to all avatars being formatted properly.
I uploaded app print in comments!
import { Platform } from 'react-native';
borderRadius: Platform.OS === 'ios' ? 60 : 100
Try this, it works fine for me.
I started react-native and I am having a hard time finding how I can load a picture from an uri and show it into two scrollView (seems I need that, one for vertical and one for horizontal scrolls). I could make it works for a local file, but as soon as I get it from internet, the picture never show up except if I give a specific size.
<View style={{ flex: 1 }}>
<ScrollView contentContainerStyle={{ flex: 0, alignContent: "stretch" }}>
<ScrollView horizontal={true} contentContainerStyle={{ flex: 0, alignContent: "stretch" }}>
<Image
style={{ flex: 1, backgroundColor: 'white' }}
resizeMode='cover'
source={{ uri: 'https://cdn.pixabay.com/photo/2017/02/15/11/15/wintry-2068298_960_720.jpg' }}
/>
</ScrollView>
</ScrollView>
</View>
The same code without the scrollViews shows the image perfectly but with them the image never shows. I tried, the alignSelf:'stretch', or to set top/bottom/right/left to 0 and also width:'100%' and height:'100%' for the image nothing giving the expected result which is take all the space possible showing the image and be able to scroll inside it horizontally and vertically
Thanks for your help.
Finally found the answer :
var myUri = 'https://cdn.pixabay.com/photo/2017/02/15/11/15/wintry-2068298_960_720.jpg';
var mode = 'cover'
Image.getSize(myUri, (width, height) => { this.setState({ width, height }) });
return (
<ScrollView contentContainerStyle={{ flex: 0 }}>
<ScrollView horizontal={true} contentContainerStyle={{ flex: 0 }}>
<Image
style={{ width: width, height: height }}
resizeMode={mode}
source={{ uri: myUri }}
/>
</ScrollView>
</ScrollView>
);
I have a ScrollView with a list of items. When I click on one item I navigate to a new scene (slide in from the right). However, during the transition period the two scenes overlap; they are fine after the animation/transition is done.
Here's an example:
and heres the related code:
render() {
return (
<Navigator
initialRoute={routes.frontpage()}
renderScene={(route, navigator) => {
if(route.index === 1) {
return (
<TouchableHighlight
onPress={() => navigator.pop()}>
<View style={{flex: 1}}>
<Text style={styles.header}> other </Text>
<Text> {route.post.title} </Text>
</View>
</TouchableHighlight>
)
}
return (
<View style={{flex: 1}}>
<Text style={styles.header}> Frontpage </Text>
<ScrollView>
{
this.props.posts.map(post => (
<TouchableHighlight
key={post.created}
onPress={() => {
if (route.index === 0) {
return navigator.push(routes.post(post))
}
navigator.pop();
}}>
<View>
<PostSummary
title={post.title}
upvotes={post.ups}
author={post.author}
subreddit={post.subreddit}
created={post.created_utc}
/>
</View>
</TouchableHighlight>
))
}
</ScrollView>
</View>
)
}}
/>
)
}
Any ideas on how to solve this?
Navigator uses animations during transitions between two scenes. In your case it uses fade during the transition. How about using a different animation. Navigator has Scene Transitions feature that you may try to change the animation.