我正在使用Flatlist来渲染图片列表。我想点击一张单独的图片,然后在一个模态中呈现相同图片的更大版本。我似乎无法找到一种方法来确保模式打开时使用我点击的更大版本的图片。
这是我到目前为止所写的内容。
import React, { Component } from 'react';
import { Text, View, FlatList,
Image,
TouchableOpacity,
Modal,
Alert,
} from 'react-native';
class TestPage extends Component {
constructor() {
super();
this.state = {
albums: [],
modalIsOpen: false,
selectedAlbum: { album: null }
};
}
componentWillMount() {
console.log('component did mount');
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then((response) => response.json())
.then((responseData) => {
this.setState({
albums: responseData
});
});
}
selectAlbumPic() {
console.log('her is the selectAlbumPic thing');
}
pictureOpen(item) {
console.log('here is your item ', item.title);
this.setState({
modalIsOpen: !this.state.modalIsOpen,
selectedAlbum: { album: item }
});
console.log('here is your state after the fuction', this.state.selectedAlbum.album);
}
closeModal(item) {
//console.log('here is your seleected album', this.state.selectedAlbum.album.title);
// console.log('close modal is being pressed irght now');
this.setState({
modalIsOpen: false,
selectedAlbum: { album: null }
});
// console.log('here is the album data ', item.album);
}
singleAlbumRender(item) {
const pictureUrl = item.image;
return this.state.selectedAlbum === { album: null } ?
<View style={styles.singleAlbum}>
<TouchableOpacity
onPress={() => {
console.log('hey man');
console.log('here is your state', this.state.selectedAlbum);
this.pictureOpen(item);
}}
>
<Image
source={{ uri: `${pictureUrl}` }}
style={{
width: 50,
height: 50,
}}
/>
</TouchableOpacity>
</View>
:
<View style={styles.singleAlbum}>
<TouchableOpacity
onPress={() => {
console.log('this is the second batch');
this.pictureOpen(item); }}
>
<Image
source={{ uri: `${pictureUrl}` }}
style={{
width: 50,
height: 50,
}}
/>
</TouchableOpacity>
<Modal
animationType="slide"
onRequestClose={() => {}}
visible={this.state.modalIsOpen}
transparent={false}
>
<View>
<TouchableOpacity
onPress={() => {
console.log('this text should close the modal');
console.log(this.state.selectedAlbum.album.image);
this.closeModal(item);
}}
>
<Image
style={{
width: 200,
height: 200,
}}
source={{ uri: `${this.state.selectedAlbum.image}` }}
/>
</TouchableOpacity>
</View>
</Modal>
</View>;
}
renderAlbumList() {
return (<FlatList
data={this.state.albums}
renderItem={({ item }) => {
return (
this.singleAlbumRender(item)
//<Image
// style={{
// width: 50,
// height: 50,
// }}
//source={{ uri: `${pictureStuff}` }}
// />
);
}}
keyExtractor={(item) => item.title}
extraData={this.state.selectedAlbum}
/>);
}
render() {
return (
<View style={styles.mainContainer}>
<View style={styles.viewOne}>
{this.renderAlbumList()}
</View>
</View>
);
}
}
const styles = {
mainContainer: {
flex: 1,
//backgroundColor: 'blue',
justifyContent: 'center',
alignItems: 'center',
},
viewOne: {
// backgroundColor: 'green',
},
singleAlbum: {
backgroundColor: 'yellow',
}
};
export default TestPage;
答案 0 :(得分:1)
这是我想要的代码。我选择将所有内容保存在一个组件中。
import React, { Component } from 'react';
import { Text, View, FlatList,
Image,
TouchableOpacity,
Modal,
Alert,
} from 'react-native';
class TestPage extends Component {
constructor() {
super();
this.state = {
albums: [],
modalIsOpen: false,
selectedAlbum: null
};
}
componentWillMount() {
console.log('component did mount');
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then((response) => response.json())
.then((responseData) => {
this.setState({
albums: responseData,
isLoaded: true,
});
});
}
pictureOpen(item) {
this.setState({
modalIsOpen: !this.state.modalIsOpen,
selectedAlbum: item
});
}
closeModal(item) {
this.setState({
modalIsOpen: false,
selectedAlbum: { album: null }
});
console.log('here is the album data ', item.image);
}
singleAlbumRender(item) {
const pictureUrl = item.image;
return this.state.selectedAlbum === null ?
<TouchableOpacity
onPress={() => {
console.log('hey man no button pressed yet');
console.log('here is your state', this.state.selectedAlbum);
this.pictureOpen(item);
}}
>
<Image
source={{ uri: `${pictureUrl}` }}
style={{
width: 50,
height: 50,
}}
/>
</TouchableOpacity>
:
<View style={styles.singleAlbum}>
<TouchableOpacity
onPress={() => {
console.log('hey man first');
console.log('here is your state', this.state.selectedAlbum);
this.pictureOpen(item);
}}
>
<Image
source={{ uri: pictureUrl }}
style={{
width: 50,
height: 50,
}}
/>
</TouchableOpacity>
</View>;
}
renderAlbumList() {
return (<FlatList
data={this.state.albums}
renderItem={({ item }) => {
return (
this.singleAlbumRender(item)
//<Image
// style={{
// width: 50,
// height: 50,
// }}
//source={{ uri: `${pictureStuff}` }}
// />
);
}}
keyExtractor={(item) => item.title}
extraData={this.state.selectedAlbum}
/>);
}
render() {
return (
<View style={styles.mainContainer}>
<View style={styles.viewOne}>
{this.renderAlbumList()}
</View>
<Modal
animationType="slide"
onRequestClose={() => {}}
visible={this.state.modalIsOpen}
transparent
>
<View>
<TouchableOpacity
onPress={() => {
const selectItem = this.state.selectedAlbum;
console.log('this text should close the modal');
this.closeModal(selectItem);
}}
>
<Image
style={{
width: 200,
height: 200,
}}
source={this.state.selectedAlbum === null
? null
: { uri: this.state.selectedAlbum.image }}
/>
</TouchableOpacity>
</View>
</Modal>
</View>
);
}
}
const styles = {
mainContainer: {
flex: 1,
//backgroundColor: 'blue',
justifyContent: 'center',
alignItems: 'center',
},
viewOne: {
// backgroundColor: 'green',
},
singleAlbum: {
backgroundColor: 'yellow',
}
};
export default TestPage;
答案 1 :(得分:0)
首先,我建议您为相册创建一个新组件,这样可以使代码更简单,更干净,在这个新组件中使用模态。
import React, { Component } from 'react';
import { Text, View, Image, TouchableOpacity, Modal, StyleSheet } from 'react-native';
class ImageModal extends Component {
constructor(props){
super(props);
this.state = {
modalIsOpen: false
}
}
handleModal = () => {
this.setState({
modalIsOpen: !this.state.modalIsOpen,
});
}
render() {
return (
<View>
<View style={styles.singleAlbum}>
<TouchableOpacity
onPress={this.handleModal()}
>
<Image
source={{ uri: `${this.state.selectedAlbum}` }}
style={{
width: 50,
height: 50,
}}
/>
</TouchableOpacity>
</View>
<Modal
animationType="slide"
onRequestClose={() => {}}
visible={this.state.modalIsOpen}
transparent={false}
>
<View>
<TouchableOpacity
onPress={this.handleModal()}
>
<Image
style={{
width: 200,
height: 200,
}}
source={{ uri: `${this.props.album.image}` }}
/>
</TouchableOpacity>
</View>
</Modal>
</View>
);
}
}
const styles = StyleSheet.create({
...
});
export default ImageModal;
然后在main中你需要渲染这个新组件。
import React, { Component } from 'react';
import { View, FlatList, StyleSheet } from 'react-native';
import ImageModal from './ImageModal';
class TestPage extends Component {
constructor() {
super();
this.state = {
albums: [],
isLoad: false
};
}
componentWillMount() {
console.log('component did mount');
fetch('https://rallycoding.herokuapp.com/api/music_albums')
.then((response) => response.json())
.then((responseData) => {
this.setState({
albums: responseData, isLoad: true
});
});
}
singleAlbumRender(item) {
return (
<ImageModal album={item}/>
)
}
render() {
return (
<View style={styles.mainContainer}>
<View style={styles.viewOne}>
{this.state.isLoad ?
<FlatList
data={this.state.albums}
renderItem={(item) => this.singleAlbumRender(item) }
keyExtractor={(item) => item.title}
/> : null }
</View>
</View>
);
}
}
const styles = StyleSheet.create({
...
});
export default TestPage;