I have just started working on a React Native project and I got stuck. I need to display a listof images from an API. The API only gives image urls that I can use like this:
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://avatars0.githubusercontent.com/u/13102253?s=460&v=4'}}
/>
The image count is dynamic but I want to display only 3 images per row. How can I achieve this?
You can use ListView in which you can style it by wrapping it into row like this
and page size will take care of arranging into row
<ListView
contentContainerStyle={styles.list}
dataSource={this.props.yourData} //datasource either props/state only
pageSize={3}
renderRow={(data, rowID, sectionID) => (
<Image
style={{width: 50, height: 50}}
source={{uri: data.path}}/>)} //path here is url that you receive
const styles = StyleSheet.create({
list: {
flexDirection: "row",
flexWrap: "wrap"
}})
The React-Native FlatList is exactly what you need. It accepts a numColumns prop which in your case should be 3.
<FlatList
numColumns={3}
data={yourImagesArray}
renderItem={<YourImageComponent >}
/>
Each iteration of the data array (which I called here yourImagesArray) is passed to the renderItem (which I called here YourImageComponent) as a data prop. So the render function of YourImageComponent should be something like this:
render() {
const { data } = this.props;
return (
<Image source={{ uri: data.uri }} style={{ width: 50, height: 50 }} />
);
}
Related
I am trying to build a react-native app, and I want to build a layout where I have components in a vertical manner and a transaction history, I am stuggling with the component to view transaction history which I am populating from a dummy data, I am faced with an error "VirtualizedLists should never be nested inside...". Even when I am not using ScrollViews. I have tried a couple of stackoverflow answers but it is still the Error (Not warning). Here is my Code:
`
import React from 'react';
import {View, Text, FlatList, TouchableOpacity, Image} from 'react-native';
import {colors, SIZES, fonts, icons} from '../global';
const TransactionHistory = ({customContainerStyle, history}) => {
const renderItem = ({item}) => (
<TouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
paddingVertical: SIZES.base,
}}
onPress={() => console.log(item)}>
<Image
source={icons.transaction}
style={{
width: 30,
height: 30,
tintColor: colors.primary,
}}
/>
<View style={{flex: 1, marginLeft: SIZES.radius}}>
<Text style={{...fonts.android.h3}}>{item.description}</Text>
<Text style={{color: colors.gray, ...fonts.android.body4}}>
{item.date}
</Text>
</View>
</TouchableOpacity>
);
return (
<View
style={{
marginTop: SIZES.padding,
marginHorizontal: SIZES.padding,
padding: 20,
borderRadius: SIZES.radius,
backgroundColor: colors.white,
...customContainerStyle,
}}>
<Text style={{...fonts.android.h2}}>Transaction History</Text> //Transaction History Heading
<FlatList
contentContainerStyle={{marginTop: SIZES.radius}}
scrollEnabled={false}
data={history}
keyExtractor={item => `${item.id}`}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
ItemSeparatorComponent={() => {
return (
<View
style={{
width: '100%',
height: 1,
backgroundColor: colors.lightGray,
}}></View>
);
}}
/>
</View>
);
};
export default TransactionHistory;
`
What I tried?
One of the answers was to change the ScrollView tag to View, but I already used the view tag and not ScrollView.
Change ScrollEnabled to be False. This was false initially.
According to this solution (React-Native another VirtualizedList-backed container). I used I created the Flatlist outside of the View and used ListFooterComponent to call it. Still the same Error.
Expected Outcome:
I am Meant to have the populated data after the Transaction History Heading. Please let me know, if there is any solution to this, or another way to fufill the task. Thanks
I had a similar issue once where I was using a ScrollView in a shared Container parent component. Maybe worth checking again to see if TransactionHistory isn't nested under and ScrollView parent somewhere on the Screen.
Once I figured it was nested under a ScrollView, I essentially removed the Container and added the header and footer component around my SectionList using the ListHeaderComponent and ListFooterComponent props on the SectionList achieving the same functionality of having a ScrollView parent.
Example:
<SectionList
renderSectionHeader={renderSectionHeader}
sections={data}
ListHeaderComponent={Header}
renderItem={renderItem}
contentContainerStyle={{ paddingBottom: bottom }}
/>
More info here
I'm hoping to get help building an Image Grid in React Native.
I'm trying to create an image grid with mapped data from an array. The mapping part is working fine but the images are not being place the way I want.
This is what I'm looking for (images placed where red squares are):
This is my code so far:
<ScrollView style={{flex: 1, backgroundColor: 'yellow',
}} >
{data.map(image => (
<View style={styles.viewpic}>
<Image style={styles.image} source={{uri:image.url }}/>
</View>
))}
</ScrollView>
</SafeAreaView>
This is my CSS:
viewpic: {
flex: 1,
flexWrap:'wrap',
justifyContent: 'center',
flexDirection: 'row',
backgroundColor: 'blue',
},
image: {
justifyContent: 'center',
height: 115,
width: 115,
margin:6,
backgroundColor: 'red',
}
This is what I'm currently getting:
So far I tried every single CSS combo I could think but nothing has worked so far.
I also tried FLATLIST but to be honest I wasn't able to properly convert my current code to "fit" the requirements of Flatlists.
Thanks everyone for your help!
Cheers!
it's an HTML mistake.
In fact, you put the flex-wrap style for each element, that's why you have one element per line.
You have to put all the elements inside the flex-wrap div and it will works. I hope it will help you
<View style={styles.viewpic}>
{data.map(image => (
<Image style={styles.image} source={{uri:image.url }}/>
))}
</View>
I was able to find the answer!
I combined 2 tutorials + a few tricks and got it done!
First I built my image grid using "FlatList". I found a great tutorial with the step by step here(not my page, not affiliated):Youtube Tutorial
At the beginning I was getting the same result until I added "numColumns={ }"
Here's the code:
...
const numberOfCols = 3
...
return(
.
<View>
<FlatList
data={data}
keyExtractor={(item, index)=>{return item.date}}
numColumns={numberOfCols}
renderItem={({item, index})=>(
<View style={styles.viewpic}>
<Image style={styles.image} source={{uri:item.url}}/>
</View>
)}
/>
Then I used a bit of the strategy from this tutorial (not my page, not affiliated) :
Youtube Tutorial
I still need to adjust the css so it looks better but I'm happy with it so far.
Here is the final result:
My code below accepts inputPhotoLocation as a prop. inputPhotoLocation contains a list of image source locations (which have been retrieved from a file containing a list). I need a way to pass these to my image source. I have been able to pass the locations directly in the text box with success.
function SelectionBoxComponent({inputPhotoLocation, inputText, onPress}) {
return (
<TouchableWithoutFeedback onPress={onPress}>
<View style={styles.box}>
<View style={styles.circularPhoto}>
<Image style={{height:"100%", width:"100%", borderRadius:70,
borderWidth:0, source={require(inputPhotoLocation)}}} ></Image> {/* Here I need to insert the list items */}
</View>
<AppText style={styles.textStyle} onPress={console.log(inputText)} >
{inputText}</AppText>
</View>
</TouchableWithoutFeedback>
My inputPhotoLocation prop contains this:
./assets/GroupImages/football.jpg
../assets/GroupImages/valley.jpg
../assets/GroupImages/usa.jpg
../assets/GroupImages/playstation.jpg
../assets/GroupImages/pc.jpg
I am able to pass these locations as text outputs successfully. However, I can't figure out how to pass these in the image source.
<Image
style={{
height: '100%',
width: '100%',
borderRadius: 70,
borderWidth: 0,
{/* The source prop is not a style prop */}
source={require(inputPhotoLocation)
}}></Image>
<Image
{/* The source prop is Image prop */}
source={require(inputPhotoLocation)
style={{
height: '100%',
width: '100%',
borderRadius: 70,
borderWidth: 0
}}></Image>
I am building a react native app using mock data. I am able to render some of the mock data in a flatlist but the image will not render. In the react native devtools it shows the image url but no style is shown even though I have the style in the Stylesheet element.
import React, { Component } from "react";
import { StyleSheet, Text, View, Image, ListView } from "react-native";
class BookItem extends Component {
render(){
return (
<View style = {styles.bookItem}>
<Image style = {styles.cover} /> //is this the issue?
<View style = {styles.info}>
<Text style = {styles.author}>{this.props.author}</Text>
<Text style = {styles.title}>{this.props.title}</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
bookItem: {
flexDirection: "row",
backgroundColor: "#FFFFFF",
borderBottomColor: "#AAAAAA",
borderBottomWidth: 2,
padding: 5,
height: 175
},
cover: {
flex: 1,
height: 150,
resizeMode: "contain"
},
info: {
flex: 3,
alignItems: "flex-end",
flexDirection: "column",
alignSelf: "center",
padding: 20
},
author: { fontSize: 18 },
title: {fontSize: 18, fontWeight: "bold"}
});
export default BookItem
Im not sure if I am using the Image element in react native properly. This could be the issue. For the most part it shows the data in the devtools
You have to use image with source property. If you want to to add a just background you should use just View with background style.
Look at the official doc from here
Example is at the below.
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
You mentioned a flatlist but the code sample you provided does not have a flatlist.
Refer to the documentation for more information.
https://facebook.github.io/react-native/docs/image.html
Here are the examples provided in the documentation.
<Image
source={require('/react-native/img/favicon.png')}
/>
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/docs/assets/favicon.png'}}
/>
<Image
style={{width: 66, height: 58}}
source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}
/>
Could you maybe mock up your problem for us?
https://snack.expo.io/
Two things: Image component needs a source prop to render an image and second, try not to use flex with images. Usually they need width AND height property manually set to render properly.
Change the value for resizeMode to cover instead of contain. This has resolved the same issue for me.
I had the same problem, i suggest you update react-native to version 0.63.3
It will probably cause errors, in which case you could use this React-Native upgrade helper.
https://react-native-community.github.io/upgrade-helper/
I want to create a view like this one:
I am using a Flatlist in which all the data is coming including these thumbnails. This thumbnail is a array of objects from where I fetch image's name and display.
I want to use this inside a FlatList where all my data is coming or I just need a dummy code to implement this feature in react native
Right now I am trying to implement it like this:
<View style={{flexDirection:'row'}}>
{data.gallery.map((each,index)=>{
console.log('thubnails ******* ', each);
<Image source={{uri: Connection.getMedia()+each.name}} style={{height:Constants.BaseStyle.DEVICE_HEIGHT/100 * 10, width:Constants.BaseStyle.DEVICE_WIDTH/100 * 10}} resizeMode='stretch' />
})}
</View>
Inside data.gallary all the thumbnails are present and data is coming from props.
Sample code from the above details.
Inside render:
<FlatList
data={this.props.sampleData} // sample data should be a array of objects
renderItem={this.renderImage}
/>
renderImage function:
renderImage = ({ item }) => (
<Image source={{ uri: Connection.getMedia()+item.name }}
style={{height:Constants.BaseStyle.DEVICE_HEIGHT/100 * 10,
width:Constants.BaseStyle.DEVICE_WIDTH/100 * 10}}
resizeMode='stretch'
/>
);
You can also use Dimensions for getting device height and width.