react-native-fast-image/example/ImageGrid.js

142 lines
2.8 KiB
JavaScript
Raw Normal View History

2017-04-13 04:13:44 +00:00
// @flow
import React, { Component } from 'react'
2017-04-18 14:43:35 +00:00
import {
StyleSheet,
View,
FlatList,
Platform,
StatusBar,
Text,
} from 'react-native'
2017-04-13 04:13:44 +00:00
2017-04-18 05:52:09 +00:00
const getImageUrl = (id, width, height) =>
`https://unsplash.it/${width}/${height}?image=${id}`
2017-04-13 04:13:44 +00:00
class ImageGrid extends Component {
constructor(props: Object) {
super(props)
fetch('https://unsplash.it/list')
2017-04-18 05:52:09 +00:00
.then(res => res.json())
.then(this._onFetchImagesSuccess)
2017-04-18 14:43:35 +00:00
.catch(this._onFetchImagesError)
2017-04-13 04:13:44 +00:00
}
state = {
images: [],
itemHeight: 0,
}
2017-04-18 05:52:09 +00:00
_onLayout = e => {
2017-04-13 04:13:44 +00:00
const width = e.nativeEvent.layout.width
this.setState({
itemHeight: width / 4,
})
}
2017-04-18 14:43:35 +00:00
_onFetchImagesError = () => {
this.setState({
error: true,
})
}
2017-04-18 05:52:09 +00:00
_onFetchImagesSuccess = images => {
2017-04-13 04:13:44 +00:00
this.setState({
images,
})
}
_getItemLayout = (data, index) => {
const { itemHeight } = this.state
return { length: itemHeight, offset: itemHeight * index, index }
}
_renderItem = ({ item }) => {
const ImageComponent = this.props.ImageComponent
const uri = getImageUrl(item.id, 100, 100)
return (
2017-04-18 05:52:09 +00:00
<View style={styles.imageContainer}>
<ImageComponent source={{ uri }} style={styles.image} />
2017-04-13 04:13:44 +00:00
</View>
)
}
2017-04-18 05:52:09 +00:00
_extractKey = item => {
2017-04-13 04:13:44 +00:00
return item.id
}
render() {
2017-04-18 14:43:35 +00:00
if (this.state.error) {
return (
<View style={styles.container}>
<Text style={styles.text}>Error fetching images.</Text>
</View>
)
}
2017-04-13 04:13:44 +00:00
return (
<View style={styles.container}>
<FlatList
onLayout={this._onLayout}
style={styles.list}
2017-04-18 05:52:09 +00:00
columnWrapperStyle={[
styles.columnWrapper,
{ height: this.state.itemHeight },
]}
2017-04-13 04:13:44 +00:00
data={this.state.images}
renderItem={this._renderItem}
numColumns={4}
keyExtractor={this._extractKey}
getItemLayout={this._getItemLayout}
/>
<View style={styles.statusBarUnderlay} />
</View>
)
}
}
const MARGIN = 2
const STATUS_BAR_HEIGHT = Platform.OS === 'ios' ? 20 : StatusBar.currentHeight
2017-04-13 04:13:44 +00:00
const styles = StyleSheet.create({
statusBarUnderlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
height: STATUS_BAR_HEIGHT,
backgroundColor: 'white',
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'stretch',
justifyContent: 'center',
},
2017-04-18 14:43:35 +00:00
text: {
textAlign: 'center',
},
2017-04-13 04:13:44 +00:00
list: {
marginTop: STATUS_BAR_HEIGHT,
flex: 1,
},
columnWrapper: {
flex: 1,
flexDirection: 'row',
marginLeft: -MARGIN,
marginRight: -MARGIN,
},
image: {
flex: 1,
width: null,
height: null,
margin: MARGIN,
backgroundColor: '#eee',
},
imageContainer: {
flex: 1,
alignItems: 'stretch',
2017-04-18 05:52:09 +00:00
},
2017-04-13 04:13:44 +00:00
})
export default ImageGrid