React-Native中ListView 多选,单选
程序员文章站
2022-07-02 23:35:33
...
日常工作中,需要对ListView的item进行相关操作。单选,多选是很常见的操作。http://www.jianshu.com/p/c6991a241b4f
其中难点就在于,要更新datasource中的数据,请(每次都重新)调用cloneWithRows方法(如果用到了section,则对应cloneWithRowsAndSections方法)。数据源中的数据本身是不可修改的,所以请勿直接尝试修改。clone方法会自动提取新数据并进行逐行对比(使用rowHasChanged方法中的策略),这样ListView就知道哪些行需要重新渲染了。
二:Coding
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
Switch,
TouchableOpacity,
Dimensions
} from 'react-native';
var items=[
{
id:1,
name:'ListView:默认选中',
checked:true,
},
{
id:2,
name:'ListView:默认不选中',
checked:false,
},
{
id:3,
name:'ListView:默认不选中',
checked:false,
},
{
id:4,
name:'ListView:默认不选中',
checked:false,
}
];
export default class NormalListView extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
//此代码是核心
this.data = items;
this.state = {
dataSource: ds.cloneWithRows(this.data),
selectItem:[],
pickerSingle:true,
pickerMore:false,
};
}
render() {
return (
<ListView
renderHeader={()=>this._header()}
style={styles.mainView}
dataSource={this.state.dataSource}
renderRow={(rowData) => this.renderRow(rowData)}
/>
);
}
_header=()=>{
const mainView=this.state.pickerSingle?styles.btn:styles.textMsg;
const mainPicker=this.state.pickerSingle?styles.textMsg:styles.btn;
return <View style={styles.headMain}>
<TouchableOpacity onPress={()=>this._change()}>
<Text style={mainView}>单选</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>this._change()}>
<Text style={mainPicker}>多选</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._commit}>
<Text style={styles.textMsg}>提交</Text>
</TouchableOpacity>
</View>
}
_commit=()=>{
if(this.state.pickerSingle){
this.pickerSingle();
}else{
this.pickerMore();
}
}
_change=()=>{
this.setState({
selectItem:[],
pickerSingle:!this.state.pickerSingle,
pickerMore:!this.state.pickerMore,
})
}
pickerMore=()=>{
var hasItem=false;
//先判断是否已经点击,若没有则判断默认值
if(this.state.selectItem.length==0){
var datas = this.data.slice();
for (let i = 0; i < datas.length; i++) {
if (datas[i].checked == true) {
hasItem=true;
this.setState({
selectItem:datas[i]
},()=>{
alert(JSON.stringify(this.state.selectItem));
})
}
}
if(this.state.selectItem.length==0&&hasItem==false){
alert('selectItem为空');
}
}else {
alert(JSON.stringify(this.state.selectItem));
}
}
pickerSingle=()=>{
var hasItem=false;
//先判断是否已经点击,若没有则判断默认值
if(this.state.selectItem.length==0){
var datas = this.data.slice();
for (let i = 0; i < datas.length; i++) {
if (datas[i].checked == true) {
hasItem=true;
this.setState({
selectItem:datas[i],
},()=>{
alert(JSON.stringify(this.state.selectItem));
})
}
}
if(this.state.selectItem.length==0&&hasItem==false){
alert('selectItem为空');
}
}else {
alert(JSON.stringify(this.state.selectItem));
}
}
renderRow=(rowData)=>{
return <View style={styles.item}>
<View style={styles.mainFlex}>
<Text style={styles.itemMsg}>{rowData.name}</Text>
<Switch value={rowData.checked} onValueChange={
()=>{
this.selectedImage(rowData)
}
}/>
</View>
<View style={styles.viewLine} />
</View>
}
selectedImage=(rowData)=>{
var array = this.data.slice();
var item=[];
//区分多选,单选
if(this.state.pickerSingle){
for (let i = 0; i < array.length; i++) {
if (array[i].checked) {
array[i] = {...array[i], checked: false,name:'ListView:不选中'};
}
}
for (let i = 0; i < array.length; i++) {
if (array[i] === rowData) {
array[i] = {...rowData, checked: true ,name:'ListView:选中'};
item=array[i];
}
}
}else{
for (let i = 0; i < array.length; i++) {
if (array[i].id==rowData.id) {
if(array[i].checked){
array[i] = {...rowData, checked: false, };
item=this.removeByValue(this.state.selectItem,array[i].id);
if(!item){
item=[];
}
}else{
array[i] = {...rowData, checked: true ,name:'ListView:选中'};
item=this.state.selectItem.concat(array[i]);
}
}
}
}
this.data = array;
this.setState({
selectItem:item,
dataSource: this.state.dataSource.cloneWithRows(array),
});
}
removeByValue=(arr, val) =>{
if(arr.length>0){
for(var i=0; i<arr.length; i++) {
if(arr[i].id == val) {
return arr.splice(i, 1);
}
}
}
}
}
const styles=StyleSheet.create({
item:{
justifyContent:'center',
marginBottom:20,
marginTop:20,
},
mainView:{
paddingTop:20,
},
itemMsg:{
textAlign:'center',
},
viewLine:{
marginTop:20,
height:1,
backgroundColor:'#9b9b9b'
},
mainFlex:{
flexDirection:'row',
justifyContent:'space-between',
},
headMain:{
flexDirection:'row',
justifyContent:'space-between',
padding:20,
},
btn:{
backgroundColor:'#9a9a9a',
padding:20,
textAlign:'center',
justifyContent:'center',
},
textMsg:{
padding:20,
textAlign:'center',
justifyContent:'center',
}
})