选中 - 未选中在 ListView 中不起作用 - React Native
Checked - Unchecked doesn't working in ListView - React Native
朋友我会在listView中集成checked-unchecked。这样当用户单击选中然后将数据存储在数组中并且未选中时我将删除数据。它工作正常,但是 UI 不会在选中后更新 - 未选中。
<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>
然后在 check/uncheck 按钮上,我将 add/remove 来自数组的对象,
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);
}
主要问题:想根据 selectedList 数组更新图像 checked/unchecked,如何更新 listView 中的项目。
在 selectedWorker 方法中做什么。
GIF :
您需要向您的 ListItem 添加一个键,该键基于项目的唯一 ID,以便 React 可以区分呈现的项目。
当您使用数组的索引作为键时,React 会优化并且无法正确呈现。在这种情况下会发生什么可以用一个例子来解释。
假设 React 呈现一个包含 10 个项目的数组并呈现 10 个组件。假设第 5 项随后被删除。在下一次渲染中,React 将接收一个包含 9 个项目的数组,因此 React 将渲染 9 个组件。这将显示为第 10 个组件被删除,而不是第 5 个,因为 React 无法根据索引区分项目。
因此始终使用唯一标识符作为从项目数组呈现的组件的键。
您正在 List 中使用 Flatelist,两者都是列表项的组成部分。您可以使用 List 或 Flatelist,但不能同时使用。
希望对你有所帮助..
我尽量把Demo做成你想要的样子。
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>
)
}
朋友我会在listView中集成checked-unchecked。这样当用户单击选中然后将数据存储在数组中并且未选中时我将删除数据。它工作正常,但是 UI 不会在选中后更新 - 未选中。
<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>
然后在 check/uncheck 按钮上,我将 add/remove 来自数组的对象,
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);
}
主要问题:想根据 selectedList 数组更新图像 checked/unchecked,如何更新 listView 中的项目。
在 selectedWorker 方法中做什么。
GIF :
您需要向您的 ListItem 添加一个键,该键基于项目的唯一 ID,以便 React 可以区分呈现的项目。
当您使用数组的索引作为键时,React 会优化并且无法正确呈现。在这种情况下会发生什么可以用一个例子来解释。
假设 React 呈现一个包含 10 个项目的数组并呈现 10 个组件。假设第 5 项随后被删除。在下一次渲染中,React 将接收一个包含 9 个项目的数组,因此 React 将渲染 9 个组件。这将显示为第 10 个组件被删除,而不是第 5 个,因为 React 无法根据索引区分项目。
因此始终使用唯一标识符作为从项目数组呈现的组件的键。
您正在 List 中使用 Flatelist,两者都是列表项的组成部分。您可以使用 List 或 Flatelist,但不能同时使用。 希望对你有所帮助..
我尽量把Demo做成你想要的样子。
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>
)
}