Reputation: 353
I made an album that looks sort of like this:
<ScrollView>
<Image1
<Text1>
smth
</Text1> />
<Image2
<Text2>
smthElse
</Text2> />' ... and so on 20 times.
I have 5 albums, which I access with tabs on top. The problem is that sometimes when I switch between the tabs, some images are blank and don't load. The images are all required like this:
source={require('../assets/Image1.png')}
I want them to be required from the app and not via uri.
I thought the problem is because of the memory and on weaker phones it's possible that they don't always load, because I use a ScrollView and it loads all the images at once. I read that a ListView quite solve my problem, but I can't figure out how to make a ListView that renders 20 specific images with a specific text for each one.
If anyone can give me some clues it would be much appreciated.
Thank you !
Upvotes: 0
Views: 6391
Reputation: 805
In order to use <ListView>
You can require all the images on your .js file. On the top of your .js file you can do is
index.js
import React, { Component } from 'react';
import {Listview} from 'react-native'; //Import your other imports ofcourse
// Require all your images here
const image1 = require('../assets/Image1.png')
const image2 = require('../assets/Image2.png')
//.. And so on
export default class ClassName extends Component{
//...
}
Next is create an array object and add it to your constructor on your index.js like so
index.js
import React, { Component } from 'react';
import {Listview} from 'react-native'; //Import your other imports ofcourse
// Require all your images here
const image1 = require('../assets/Image1.png')
const image2 = require('../assets/Image2.png')
var data = [{title:"You image title", image: image1}, {title:"Your Image title",image: image2}]
export default class ClassName extends Component{
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(data),
};
}
}
Next Create a Row.js
Row.js
import React from 'react'
import { StyleSheet, Dimensions, Platform, Image, View, Text } from 'react-native';
const Row = (props) => (
<View style={{flex:1, flexDirection: 'row'}}> //Don't forget this
<Image source={props.image}>
<Text>{props.title}</Text>
</Image>
</View>
)
export default Row
Lastly Import your Row.js file on your index.js and add the <ListView>
on your render()
index.js
import React, { Component } from 'react';
import {View,Listview} from 'react-native'; //Import your other imports ofcourse
import Row from './Row'; //If it's on the same folder
// Require all your images here
const image1 = require('../assets/Image1.png')
const image2 = require('../assets/Image2.png')
var data = [{title:"You image title", image: image1}, {title:"Your Image title",image: image2}]
export default class ClassName extends Component{
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(data),
};
}
render(){
<View>
<ListView
style={{flex:1}} //Don't forget this too
dataSource={this.state.dataSource}
renderRow={(data) => <Row {...data} />}
/>
</View>
}
}
Hope this helps you. Cheers!
Upvotes: 1
Reputation: 437
In response to your question how to use a ListView to render 20 images. We are using a SectionList for rendering multiple photos. I will share the snippets below to get you started.
SectionList
<SectionList
contentContainerStyle={styles.sectionListContainer}
renderItem={this.renderItem}
renderSectionHeader={this.renderHeader}
sections={this.state.ImageData}
/>
this.renderItem
renderItem(data) {
return (
<View key={data.item.key} style={{ flex: 1 }}>
<View style={{ flex: 1, flexDirection: "row", flexWrap: "wrap" }}>
<Image
style={styles.foodPhoto}
source={{ uri: `data:image/jpg;base64,${data.item.photo}`}}
/>
</View>
</View>
)
}
To format the this.state.ImageData it took us a bit of fiddling to get the formatting/schema right for the SectionList. The format itself is documented at RN documentation. Hope that this helps!
Upvotes: 0