麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統(tǒng) > Android > 正文

ListView的View回收引起的checkbox狀態(tài)改變監(jiān)聽等問題解決方案

2020-04-11 12:32:59
字體:
供稿:網(wǎng)友
之前講到了自定義Adapter傳遞給ListView時(shí),因?yàn)長istView的View回收,需要注意當(dāng)ListView列表項(xiàng)中包含有帶有狀態(tài)標(biāo)識(shí)控件的問題。詳情可見之前發(fā)的帖[url=自定義Adapter實(shí)現(xiàn)ListView帶多選框等狀態(tài)控件的注意事項(xiàng) //www.companysz.com/article/33425.htm
還是這個(gè)問題,講一個(gè)我遇到的因?yàn)閮尚写a位置相反引起的問題。
我的ListView中每行View包含一個(gè)ImageView、TextView、CheckBox。當(dāng)ListView中有一個(gè)或一個(gè)一行CheckBox被選中就讓ListView上面的Button顯示,否則就隱藏。因此,需要對(duì)每行View中的CheckBox設(shè)置監(jiān)聽。我使用CheckBox中的OnCheckedChangeListener監(jiān)聽器,當(dāng)CheckBox的狀態(tài)發(fā)生改變的時(shí)候就會(huì)觸發(fā)這個(gè)監(jiān)聽器。先看下我自定義給ListView的Adapter的getView方法中的一些關(guān)鍵代碼:
這是getView方法中使用到的內(nèi)部類:
復(fù)制代碼 代碼如下:

static class ViewHolder {
public ImageView imageView;
public TextView textView;
public CheckBox checkBox;
}

這是getView方法中利用ListView回收機(jī)制循環(huán)利用View的代碼:
復(fù)制代碼 代碼如下:

public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.searchitem, null);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView
.findViewById(R.id.searchitemimage);
viewHolder.textView = (TextView) convertView
.findViewById(R.id.searchitemtext);
viewHolder.checkBox = (CheckBox) convertView
.findViewById(R.id.searchitemcheckbox);
convertView.setTag(viewHolder);
} else {
// Log.i(CodeUtils.SEARCHTAG, "view is reuse");
viewHolder = (ViewHolder) convertView.getTag();
}

接下來是對(duì)其中checkbox設(shè)置顯示狀態(tài)和監(jiān)聽器的代碼:
復(fù)制代碼 代碼如下:

viewHolder.checkBox
.setOnCheckedChangeListener(new SearchItemOnCheckedChangeListener(
position, state));
viewHolder.checkBox.setChecked(state[position]);

之前說過了,因?yàn)長istView的回收,需要使用一個(gè)數(shù)組或list來記錄每項(xiàng)數(shù)據(jù)中checkbox的狀態(tài)。這里,state是與ListView列表等長的boolean數(shù)組,用于記錄每個(gè)position(也就是每個(gè)列表項(xiàng)數(shù)據(jù)的id)標(biāo)識(shí)的數(shù)據(jù)上checkbox應(yīng)該顯示的狀態(tài),初始的狀態(tài)都是false。構(gòu)造checkbox監(jiān)聽器的時(shí)候需要傳遞當(dāng)前View的position,以及整個(gè)列表checkbox的狀態(tài)數(shù)組state。以下是checkBox狀態(tài)改變監(jiān)聽器的代碼:
復(fù)制代碼 代碼如下:

public class SearchItemOnCheckedChangeListener implements
OnCheckedChangeListener {
private int id;
private Boolean[] state;
public SearchItemOnCheckedChangeListener(int id, Boolean[] state) {
this.id = id;
this.state = state;
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
state[id] = isChecked;
if (isChecked) {
checkedCount++;
}else{
checkedCount--;
}
if (checkCoutn>0) {
searchButton.setVisibility(Button.INVISIBLE);
} else {
searchButton.setVisibility(Button.VISIBLE);
}
}
}
}

這里面checkedCount初始值為0的整型,用于記錄被選中多選框的數(shù)量。searchButton是根據(jù)checkbox而決定顯示還是隱藏的按鈕。

以上整個(gè)邏輯功能的實(shí)現(xiàn)代碼。開頭說了,這是一個(gè)我因?yàn)長istView的回收機(jī)制和兩行代碼位置相反引起的問題。兩行代碼的位置相反將導(dǎo)致完全不同的結(jié)果,所指的就是設(shè)置checkbox監(jiān)聽器和狀態(tài)的兩行代碼,起初我的順序?yàn)椋?
復(fù)制代碼 代碼如下:

viewHolder.checkBox.setChecked(state[position]);
viewHolder.checkBox.setOnCheckedChangeListener(new SearchItemOnCheckedChangeListener(position, state));

這樣的順序出現(xiàn)的問題是,當(dāng)我拉動(dòng)列表后,因?yàn)槔瓌?dòng)被隱藏的列表項(xiàng)狀態(tài)將被更改為false。這很不可思議,因?yàn)槲乙呀?jīng)分離了一個(gè)狀態(tài)數(shù)組來記錄每個(gè)checkbox的狀態(tài),想來想去只有一個(gè)可能,就是狀態(tài)數(shù)組中的值改變了,而改變狀態(tài)數(shù)組的值位置就在于OnCheckedChangeListener中。Debug了幾個(gè)小時(shí),才想通了問題就在于這兩行代碼為位置順序。

起因還是得講到ListView的回收機(jī)制。假如我的ListView最多只能顯示10個(gè)View,那么起初就會(huì)調(diào)用十次getView構(gòu)造十個(gè)全新的View(包括對(duì)其中的checkbox設(shè)置監(jiān)聽器)。當(dāng)我將列表往下拉出現(xiàn)第11個(gè)列表項(xiàng)的時(shí)候,頂部第一個(gè)列表項(xiàng)被隱藏,同樣會(huì)再調(diào)用一次getView,不過此時(shí)getView的參數(shù)將返回剛剛被隱藏的第一個(gè)列表項(xiàng)的View,并對(duì)這個(gè)View更改數(shù)據(jù)作為即將出現(xiàn)的第11個(gè)View。問題就出在這里,我把checkbox.setChecked()方法調(diào)用放在了設(shè)置監(jiān)聽器前面,此時(shí)因?yàn)楦牧薱heckbox的狀態(tài),勢必引起觸發(fā)狀態(tài)更改的監(jiān)聽器。注意!由于第11個(gè)View是用被隱藏的第1個(gè)View回收來的,雖然還沒有執(zhí)行下一行設(shè)置監(jiān)聽器的代碼,但實(shí)際上它已經(jīng)擁有了一個(gè)狀態(tài)監(jiān)聽器,這個(gè)監(jiān)聽器是這個(gè)View還是作為第一個(gè)View時(shí)設(shè)置。那個(gè)時(shí)候的監(jiān)聽器設(shè)置更改的第一項(xiàng)的數(shù)據(jù),而不是第11項(xiàng)數(shù)據(jù)。因此,理所當(dāng)然不能正確更改第11項(xiàng)數(shù)據(jù),反而更改了無辜的第1項(xiàng)數(shù)據(jù)。如果我把兩行代碼順序反過來,先更改監(jiān)聽器,再設(shè)置狀態(tài),引發(fā)的監(jiān)聽器自然也就是新的監(jiān)聽器,邏輯也就對(duì)了。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产一级淫片在线观看 | chinesehd天美原创xxxx | 法国性xxx精品hd专区 | 国产精品视频一区二区三区四 | 精品国产1区2区3区 免费国产 | 久久精品a一级国产免视看成人 | 亚洲成人在线视频网 | 精品国产一区二区三区久久久蜜月 | 欧美jizzhd极品欧美 | 宅男噜噜噜66国产在线观看 | 欧美激情第一区 | 久久99国产精品久久99果冻传媒 | 九九热九九 | 一级免费观看 | 久久艹逼 | 亚洲人成网站免费播放 | 私库av在线免费观看 | 91热久久免费频精品黑人99 | 国产成人在线视频播放 | 亚洲精品一区中文字幕 | 国产成年人在线观看 | 深夜福利视频绿巨人视频在线观看 | 亚洲综合精品 | 成年人免费视频播放 | 91精品国产乱码久久桃 | 爱爱插插视频 | 午夜免费网 | 国产精品入口夜色视频大尺度 | 极品大长腿啪啪高潮露脸 | av手机在线电影 | 操毛片| 激情久久免费视频 | 中文字幕在线观看视频一区 | 日韩一级成人 | 国产一区精品在线观看 | 成人免费视频视频在线观看 免费 | 久久99久久99精品 | 99久久精品免费 | 色97在线| 国内精品久久久久久久久久 | 久在线播放|