FlatList React Native - full image not showing in each element - react-native

I am trying to use the FlatList in my expo React Native application. I am able to get the FlatList working but the FULL image is not being displayed for each Item (it appears as though only the top left of the image is being displayed). Each image is 717x717 in dimension. Please can someone advise? Perhaps i am having a styling issue? I would like the images not to be of fixed width and height but dynamic in size which is what i tried to achieve below without success. I have included the link to the images below.
const Inspiration = () => {
const handleSelectedImage = (e) => {
console.log('image selected', e);
};
return (
<>
<CreatedImageModal />
<ModalGeneratingImage />
<ExamplePrompt />
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
data={EXAMPLES}
style={styles.list}
numColumns={2}
keyExtractor={(item) => item.id}
ListHeaderComponent={<Prompt />}
renderItem={({ item }) => (
<Image
resizeMode={'contain'}
onPress={() => handleSelectedImage(item)}
transition={true}
source={item.path}
containerStyle={styles.item}
PlaceholderContent={<ActivityIndicator />}
/>
)}
/>
</>
);
};
const styles = StyleSheet.create({
list: {
width: '100%',
backgroundColor: '#000',
},
item: {
aspectRatio: 1,
width: '100%',
flex: 1,
},
});
const EXAMPLES = [
{
id: '1',
path: require('../assets/img-1_small.png'),
prompt: 'A synthwave style sunset above the reflecting water of the sea, digital art'
},
{
id: '2',
path: require('../assets/img-2_small.png'),
prompt: 'A van Gogh style painting of an American football player'
},
{
id: '3',
path: require('../assets/img-3_small.png'),
prompt: '3D render of a cute tropical fish in an aquarium on a dark blue background, digital art'
},
{
id: '4',
path: require('../assets/img-4_small.png'),
prompt: 'A cartoon of a cat catching a mouse'
},
{
id: '5',
path: require('../assets/img-5_small.png'),
prompt: 'A comic book cover of a superhero wearing headphones'
},
{
id: '6',
path: require('../assets/img-6_small.png'),
prompt: 'A hand-drawn sailboat circled by birds on the sea at sunrise'
},
{
id: '7',
path: require('../assets/img-7_small.png'),
prompt: 'An expressive oil painting of a basketball player dunking, depicted as an explosion of a nebula'
},
{
id: '8',
path: require('../assets/img-8_small.png'),
prompt: 'A hand drawn sketch of a Porsche 911'
},
];
export default Inspiration;
This is the link to the images i am trying to display Examples

You can add resizeMode in Image Component.
<Image
source={item.path}
resizeMode={'contain'}
// Other Props remain same
/>
Hope this will fix your problem.

solved your problem
check this Expo snack Link
Expo Link

you can use the stretch property
const Inspiration = () => {
const handleSelectedImage = (e) => {
console.log('image selected', e);
};
return (
<>
<CreatedImageModal />
<ModalGeneratingImage />
<ExamplePrompt />
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
data={EXAMPLES}
style={styles.list}
numColumns={2}
keyExtractor={(item) => item.id}
ListHeaderComponent={<Prompt />}
renderItem={({ item }) => (
<Image
resizeMode={'stretch'}
onPress={() => handleSelectedImage(item)}
transition={true}
source={item.path}
containerStyle={styles.item}
PlaceholderContent={<ActivityIndicator />}
/>
)}
/>
</>
);
};
const styles = StyleSheet.create({
list: {
width: '100%',
backgroundColor: '#000',
},
item: {
aspectRatio: 1,
width: '100%',
flex: 1,
height: 400
},
});
you add the Height and Width preferences to your image
you can try my way. hope it can help you

Related

How can we render 2 vertical Flatlist inside a single scrollView?

I managed to build it but I'm getting a bad user experience in scrolling the two vertical flatlist inside my scroll view, I'm getting a warning also like
"VirtualizedLists should never be nested inside plain ScrollViews"
transaction and charging session are the two flatlists inside the scrollView
You Can not use Flatlist and Scrollview with the same orientation,you can use Scrollview with Vertical and flatlist is as horizontal.
==> You need to use for same orientation as the using of the map and use the scrollview.
try this approach by using ListHeaderComponent and ListFooterComponent
import * as React from 'react';
import { Text, View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
export default function App() {
const list = [
{ id: '1', title: 'title 1' },
{ id: '2', title: 'title 2' },
{ id: '3', title: 'title 3' },
{ id: '4', title: 'title 4' },
{ id: '5', title: 'title 5' },
{ id: '5', title: 'title 6' },
{ id: '7', title: 'title 7' },
{ id: '8', title: 'title 8' },
];
const renderHeader = () => {
return (
<View>
<Text>render profile here</Text>
</View>
);
};
const renderFooter = () => {
return (
<View>
<Text>render footer here</Text>
</View>
);
};
const renderItem = ({ item }) => {
return (
<View style={{ height: 60, marginVertical: 20, padding:5, backgroundColor:'red' }}>
<Text>{item.title}</Text>
</View>
);
};
return (
<View style={styles.container}>
<FlatList
contentContainerStyle={{margin:10, paddingBottom:50}}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
data={list}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});
you can see result here
https://snack.expo.dev/#sharqiyem/flatlist
You can map your lists into scrollView
Don't forget to give key values for performance. You have only 3-5 items in your lists so you don't have to worry about performance much.
example approach like that
let section1Arr = [{}]
let section2Arr = [{}]
render() {
return (
<ScrollView>
<Text>
Transaction
</Text>
{
section1Arr.map((item, index) => {
return (
<View key={`myKeyString${index}`}>
<Text>
{item.title}
</Text>
</View>
)
})
}
//section2arr same approach
<ScrollView/>
)
}
This is the best approach if you don't want to see "yellow error that "VirtualizedLists should never be nested inside plain ScrollViews"".
BUT you can use nested virtualizedLists not a big deal but don't forget to set "scrollEnabled" to false for inner scrollable views. Actually this is very close thing to mapping approach.
(please give vote if this answer is correct for you)

last FlatList content only display 10% of the item

here i use flatlist grid inside scrollview, the problem is the last row of the grid didn't display the full height of the content, i don't know where the problem is.
note: i use native-base component
const [data, setData] = useState([
{ id: 1, title: "DA’s Backyard" },
{ id: 2, title: "KC’s Backyard" },
{ id: 3, title: "LA’s Backyard" },
{ id: 4, title: "KP’s Backyard" },
{ id: 5, title: "LA’s Backyard" },
{ id: 6, title: "KP’s Backyard" },
]);
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ width: "100%", alignItems: "center" }}
>
<Stack flexWrap={"wrap"} justifyContent="center">
<SelectBox />
<FlatList
mt={"4"}
showsVerticalScrollIndicator={false}
data={data}
keyExtractor={(item, index) => index}
numColumns={2}
renderItem={(data, index) => {
return <PortfolioCard />;
}}
/>
</Stack>
</ScrollView>
Add this please to flat list
<FlatList
mt={"4"}
showsVerticalScrollIndicator={false}
data={data}
keyExtractor={(item, index) => index}
numColumns={2}
renderItem={(data, index) => {
return <PortfolioCard />;
}}
contentContainerStyle={{paddingBottom:50}} // add this
/>

Sticky header on SectionList ReactNative

I need to create a screen Catalog(Categories and Products).
I'm using SectionList from React Native in order to achive this.
I need to make that Categories component stick on the top when you scroll product lists.
Is there any library that could help me with this Catalog screen ?
Please look at the image here..
import React from "react";
import { View, StyleSheet, SectionList } from "react-native";
import Text from "../Text";
const DATA = [
{
title: "Main dishes",
data: ["Pizza", "Burger", "Risotto"],
},
{
title: "Sides",
data: ["French Fries", "Onion Rings", "Fried Shrimps"],
},
{
title: "Drinks",
data: ["Water", "Coke", "Beer"],
},
{
title: "Desserts",
data: ["Cheese Cake", "Ice Cream"],
},
];
const TabCategories = () => (
<View>
<Text>Horizontal list of categories</Text>
</View>
);
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const TestSectionList = (props) => {
return (
<View style={styles.container}>
<Text style={styles.SRC}>Some React Component</Text>
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Item title={item} />}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
StickyHeaderComponent={TabCategories}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {},
SRC: {
fontWeight: "bold",
borderWidth: 1,
borderColor: "#fff",
padding: 10,
},
item: {
padding: 30,
},
header: {
fontWeight: "bold",
fontSize: 20,
},
});
export default TestSectionList;
stickySectionHeadersEnabled
Makes section headers stick to the top of the screen until the next one pushes it up
ListHeaderComponent
Rendered at the very beginning of the list
renderSectionHeader
Rendered at the top of each SECTION
I think this should do:
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Item title={item} />}
ListHeaderComponent={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
renderSectionHeader={TabCategories}
stickySectionHeadersEnabled
/>
You can try this library react-native-tabs-section-list
https://github.com/bogoslavskiy/react-native-tabs-section-list
If you are talking about react-native-section-list, it inherits ScrollView props, you can check in the docs, in props section, so it has stickyHeaderComponent prop which should be exactly what you want.

Display custom image and link to a sectionList item on react native

I'm a newbie on react-native.
I want to build personalized data from array to populate sectionLists.
My actual code, extracted from react-native docs is
import React from "react";
import { StyleSheet, Text, View, SafeAreaView, SectionList, StatusBar } from "react-native";
const DATA = [
{
title: "Main dishes",
data: ["Pizza", "Burger", "Risotto"],
},
{
title: "Sides",
data: ["French Fries", "Onion Rings", "Fried Shrimps"]
},
{
title: "Drinks",
data: ["Water", "Coke", "Beer"]
},
{
title: "Desserts",
data: ["Cheese Cake", "Ice Cream"]
}
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => (
<SafeAreaView style={styles.container}>
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => <Item title={item} />}
renderSectionHeader={({ section: { title } }) => (
<Text style={styles.header}>{title}</Text>
)}
/>
</SafeAreaView>
);
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
marginHorizontal: 16
},
item: {
backgroundColor: "#f9c2ff",
padding: 20,
marginVertical: 8
},
header: {
fontSize: 32,
backgroundColor: "#fff"
},
title: {
fontSize: 24
}
});
export default App;
Here, we have only 2 dimensions to data array. I want to personalize that DATA array sending an image source, and a link to a screen on itemclick, for example.
I mean, I have actually title, data on DATA array. I want to add image and link columns to this DATA array and I want to have a solution to parse it in order to associate the link to props and display an image by its source content on image field.
Could you please tell me how to present that for the array and render it ?
Thanks.
EDIT :
I want to add 2 columns image and link on the DATA array like that :
const DATA = [
{
title: "Main dishes",
data: ["Pizza", "Burger", "Risotto"],
image: [require('../assets/Aquarium.png'), require('../assets/Aquarium.png'), require('../assets/Aquarium.png')]
link: ["Pizza", "Burger", "Risotto"]
},
{
title: "Sides",
data: ["French Fries", "Onion Rings", "Fried Shrimps"]
image: [require('../assets/Aquarium.png'), require('../assets/Aquarium.png'), require('../assets/Aquarium.png')]
link: ["FrenchFries", "OnionRings", "FriedShrimps"]
},
{
title: "Drinks",
data: ["Water", "Coke", "Beer"]
image: [require('../assets/Aquarium.png'), require('../assets/Aquarium.png'), require('../assets/Aquarium.png')],
link: ["Water", "Coke", "Beer"]
},
{
title: "Desserts",
data: ["Cheese Cake", "Ice Cream"]
image: [require('../assets/Aquarium.png'), require('../assets/Aquarium.png')]
link: ["CheeseCake", "IceCream"]
}
];
And I want to change my code like this to present image and link to a stackscreen name but it gives me errors.
return (
<SafeAreaView style={styles.container}>
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) =>
<TouchableWithoutFeedback
activeOpacity={0.4}
onPress={ () => navigation.navigate(item.link)}>
<View style={{flexDirection: 'row', textAlign: 'left', fontSize: 15, backgroundColor:'transparent', marginTop: 15, marginBottom: 15}}>
<Image source={item.image}/>
<Item title={item.title} />
</View>
</TouchableWithoutFeedback>
}
renderSectionHeader={({ section: { title } }) => (
<View>
<Text style={styles.header}>{title}</Text>
</View>
)}
/>
</SafeAreaView>
);
Could you please help me ?

Remove horizontal line from last item in react-native

I have a map which loop all items in the products object and output each new items, What i want is to remove the red line under the "product 003", which is the last item.
Image
const App = () => (
<View style={styles.container}>
{products.map((product, index) => (
<ShoppingList key={index} title={product.title} price={product.price} />
))}
</View>
);
const ShoppingList = props => {
return (
<View style={styles.line}>
<Text>{props.title}</Text>
<Text>{props.price}</Text>
</View>
);
};
const products = [
{
title: 'Product 001',
price: '100000',
},
{
title: 'Product 002',
price: '20000',
},
{
title: 'Product 003',
price: '10000',
},
];
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
},
line: {
padding: 4,
borderBottomColor: 'red',
borderBottomWidth: StyleSheet.hairlineWidth,
},
});
Either use the index provided in the .map loop
{products.map((product, index) => (
(index === products.length) ? <ItemWithoutHorizontalLine /> : <ItemWithHorizontalLine />
))}
or use a VirtualizedList (or any of the child components of VirtualizedList e.g., FlatList) and provide a ItemSeparatorComponent
<FlatList
...
ItemSeparatorComponent={this.renderSeparator}
</FlatList>