问题
friend I Will integrated checked - unchecked in listView. So that When user click on checked then store the data in Array and unchecked then i will remove the data. Its working fine, But the UI Will not updated after checked - unchecked.
<List containerStyle={{marginTop : 0 , borderBottomWidth : 0 , borderBottomColor : 'black', borderTopWidth : 0}}>
<FlatList
data={this.state.list}
renderItem={({ item }) => (
<ListItem containerStyle={{height: 80, backgroundColor : 'transparent', borderBottomWidth : 0, borderTopWidth : 0}}
title={
<View style={styles.titleView}>
<Text style={styles.ratingText}>{item.iWorkerID.vFirstName}</Text>
</View>
}
rightIcon={
<TouchableOpacity onPress = {() => this.selectedWorker(item)} style={{width: 30, height: 30 , marginTop : 10, marginRight : 30}}>
<Image style = {{width: 30, height: 30}} source={this.state.selectedList.includes(item) ? require("./Images/uncheckd.png") : require("./Images/checked.png")}/>
{/* {this.state.selectedList.includes(item) && <Image style = {{width: 30, height: 30}} source={require("./Images/uncheckd.png")}/>}
{!this.state.selectedList.includes(item) && <Image style = {{width: 30, height: 30}} source={require("./Images/checked.png")}/>} */}
</TouchableOpacity>
}
avatar={<Avatar
rounded
medium
containerStyle={{marginLeft: 30}}
source={{uri: Globle.IMAGE_URL+item.vProfileImage}}
activeOpacity={0.7}
/>}
/>
)}
/>
</List>
And on the check/uncheck button, I will add/remove object from array,
selectedWorker = (data) =>{
console.log('data is ', data);
if (!this.state.selectedList.includes(data)) {
// this.setState({ selectedList : [...this.state.selectedList , data]})
this.state.selectedList.push(data);
} else {
var index = this.state.selectedList.indexOf(data);
if (index > -1) {
this.state.selectedList.splice(index, 1);
}
}
this.setState({list : this.state.list})
console.log('selected list' , this.state.selectedList);
}
Main Issue : Want to update image checked/unchecked according to selectedList array, How can i Update item in listView.
What to do inside selectedWorker method.
GIF :
回答1:
you are using Flatelist inside List, Both are a component to listing items. you can use List or Flatelist, not both. I hope it will help you..
I try to make Demo similar to that you want.
constructor(props) {
super(props)
this.state = {
list: [
{
id: 1,
name: "Harpal Singh Jadeja",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
},
{
id: 2,
name: "Kirit Mode",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
},
{
id: 3,
name: "Rajiv Patil",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
},
{
id: 4,
name: "Chetan Doctor",
avtar: "https://cdn.pixabay.com/photo/2016/08/08/09/17/avatar-1577909_960_720.png"
}]
};
};
renderListItem = (index, item) => {
return (
<View style={styles.notification_listContainer}>
<Image source={{uri: item.avtar, cache: 'force-cache'}}
style={circleStyle}/>
<View style={{flex: 1, paddingLeft: 10, justifyContent: 'center'}}>
<Label roboto_medium
align='left'
color={Color.TEXT_PRIMARY}
numberOfLines={1}>
{item.name}
</Label>
<Label roboto_medium
small
align='left'
color={Color.TEXT_SECONDARY}
mt={8}>
Programmer
</Label>
</View>
<View style={{justifyContent: 'center'}}>
<TouchableHighlight
style={{
backgroundColor: item.isSelected ? Color.BLACK : Color.TEXT_SECONDARY,
alignItems: 'center',
justifyContent: 'center',
height: 40,
width: 40,
borderRadius: 20
}}
onPress={this.onSelectWorker.bind(this, index, item)} underlayColor={Color.BLACK}>
<Icon name='done'
size={20}
color={Color.WHITE}/>
</TouchableHighlight>
</View>
</View>
);
};
onSelectWorker = (index, item) => {
console.log("Selected index : ", index);
let tempList = this.state.list;
tempList[index].isSelected = tempList[index].isSelected ? false : true
this.setState({
list: tempList
});
};
render() {
return (
<View style={styles.notification_Container}>
<FlatList
data={this.state.list}
renderItem={
({index, item}) => this.renderListItem(index, item)
}
keyExtractor={item => item.id}
extraData={this.state}
/>
</View>
)
}
回答2:
You need to add a key to your ListItem which is based on a unique id of the item, so that React can distinguish between the items rendered.
When you use index of an array as a key, React will optimize and not render properly. What happens in such a scenario can be explained with an example.
Suppose React renders an array of 10 items and renders 10 components. Suppose the 5th item is then removed. On the next render React will receive an array of 9 items and so React will render 9 components. This will show up as the 10th component getting removed, instead of the 5th, because React has no way of differentiating between the items based on index.
Therefore always use a unique identifier as a key for components that are rendered from an array of items.
来源:https://stackoverflow.com/questions/46658124/checked-unchecked-doesnt-working-in-listview-react-native