亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

ListView的View回收引起的checkbox狀態改變監聽等問題解決方案

2020-04-11 12:32:59
字體:
來源:轉載
供稿:網友
之前講到了自定義Adapter傳遞給ListView時,因為ListView的View回收,需要注意當ListView列表項中包含有帶有狀態標識控件的問題。詳情可見之前發的帖[url=自定義Adapter實現ListView帶多選框等狀態控件的注意事項 //www.49028c.com/article/33425.htm
還是這個問題,講一個我遇到的因為兩行代碼位置相反引起的問題。
我的ListView中每行View包含一個ImageView、TextView、CheckBox。當ListView中有一個或一個一行CheckBox被選中就讓ListView上面的Button顯示,否則就隱藏。因此,需要對每行View中的CheckBox設置監聽。我使用CheckBox中的OnCheckedChangeListener監聽器,當CheckBox的狀態發生改變的時候就會觸發這個監聽器。先看下我自定義給ListView的Adapter的getView方法中的一些關鍵代碼:
這是getView方法中使用到的內部類:
復制代碼 代碼如下:

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

這是getView方法中利用ListView回收機制循環利用View的代碼:
復制代碼 代碼如下:

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();
}

接下來是對其中checkbox設置顯示狀態和監聽器的代碼:
復制代碼 代碼如下:

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

之前說過了,因為ListView的回收,需要使用一個數組或list來記錄每項數據中checkbox的狀態。這里,state是與ListView列表等長的boolean數組,用于記錄每個position(也就是每個列表項數據的id)標識的數據上checkbox應該顯示的狀態,初始的狀態都是false。構造checkbox監聽器的時候需要傳遞當前View的position,以及整個列表checkbox的狀態數組state。以下是checkBox狀態改變監聽器的代碼:
復制代碼 代碼如下:

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的整型,用于記錄被選中多選框的數量。searchButton是根據checkbox而決定顯示還是隱藏的按鈕。

以上整個邏輯功能的實現代碼。開頭說了,這是一個我因為ListView的回收機制和兩行代碼位置相反引起的問題。兩行代碼的位置相反將導致完全不同的結果,所指的就是設置checkbox監聽器和狀態的兩行代碼,起初我的順序為:
復制代碼 代碼如下:

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

這樣的順序出現的問題是,當我拉動列表后,因為拉動被隱藏的列表項狀態將被更改為false。這很不可思議,因為我已經分離了一個狀態數組來記錄每個checkbox的狀態,想來想去只有一個可能,就是狀態數組中的值改變了,而改變狀態數組的值位置就在于OnCheckedChangeListener中。Debug了幾個小時,才想通了問題就在于這兩行代碼為位置順序。

起因還是得講到ListView的回收機制。假如我的ListView最多只能顯示10個View,那么起初就會調用十次getView構造十個全新的View(包括對其中的checkbox設置監聽器)。當我將列表往下拉出現第11個列表項的時候,頂部第一個列表項被隱藏,同樣會再調用一次getView,不過此時getView的參數將返回剛剛被隱藏的第一個列表項的View,并對這個View更改數據作為即將出現的第11個View。問題就出在這里,我把checkbox.setChecked()方法調用放在了設置監聽器前面,此時因為更改了checkbox的狀態,勢必引起觸發狀態更改的監聽器。注意!由于第11個View是用被隱藏的第1個View回收來的,雖然還沒有執行下一行設置監聽器的代碼,但實際上它已經擁有了一個狀態監聽器,這個監聽器是這個View還是作為第一個View時設置。那個時候的監聽器設置更改的第一項的數據,而不是第11項數據。因此,理所當然不能正確更改第11項數據,反而更改了無辜的第1項數據。如果我把兩行代碼順序反過來,先更改監聽器,再設置狀態,引發的監聽器自然也就是新的監聽器,邏輯也就對了。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品精品久久久久久| 久久国产精品电影| 日韩在线观看网址| 国产日韩欧美影视| 日韩免费观看在线观看| 国产精品久久久久久久app| 91在线高清免费观看| 永久免费看mv网站入口亚洲| 欧美性猛交xxxx富婆弯腰| 国产中文字幕亚洲| 日韩午夜在线视频| 国产精品精品一区二区三区午夜版| 欧美日韩国产色视频| 亚洲日韩欧美视频| 日韩在线视频播放| 欧美日韩福利在线观看| 成人免费网站在线观看| 精品国产一区二区三区久久狼黑人| 久久精品视频亚洲| 91亚洲人电影| 九九热这里只有精品免费看| 欧美国产亚洲精品久久久8v| 自拍偷拍亚洲一区| 欧美国产日本高清在线| 国产精品久久久久久久久久新婚| 亚洲一区二区三区四区在线播放| 最近2019中文字幕mv免费看| 成人观看高清在线观看免费| 日韩精品中文字幕在线观看| 性欧美在线看片a免费观看| 国产精品亚洲第一区| 久久精品久久久久| 久久久99免费视频| 日韩在线免费视频观看| 亚洲精品电影在线观看| 国产精品小说在线| 日韩精品一二三四区| 青青草原成人在线视频| 亚洲欧洲自拍偷拍| 丝袜亚洲另类欧美重口| 亚洲男人天堂视频| 午夜精品一区二区三区在线| 国产精品久久婷婷六月丁香| 91在线视频成人| 久久99青青精品免费观看| 国内精品小视频在线观看| www.欧美精品一二三区| 国产精品免费视频xxxx| 欧美精品一区二区免费| 中文字幕在线亚洲| 久久视频中文字幕| 岛国av在线不卡| 亚洲天堂男人天堂女人天堂| 国产精品99久久久久久www| 久久艹在线视频| 欧美精品videos另类日本| 欧美午夜电影在线| 欧美性猛交xxxx免费看漫画| 亚洲乱码国产乱码精品精天堂| 国产精品久久久久999| 91精品久久久久久久久久久久久| 久99久在线视频| 疯狂做受xxxx高潮欧美日本| 国产精品视频自在线| 亚洲第一精品久久忘忧草社区| 热99久久精品| 亚洲一级一级97网| 久久躁日日躁aaaaxxxx| 日韩在线视频二区| 欧美在线激情网| 综合国产在线视频| 欧美日韩国产一中文字不卡| 久久这里只有精品视频首页| 亚洲自拍偷拍区| 午夜精品久久久久久久白皮肤| 98精品国产高清在线xxxx天堂| 午夜精品三级视频福利| 欧美激情亚洲精品| 热久久这里只有| 国产精品v日韩精品| 性欧美激情精品| 久精品免费视频| 国产欧美欧洲在线观看| 国产又爽又黄的激情精品视频| 国产精品观看在线亚洲人成网| 日韩经典中文字幕在线观看| 欧美在线播放视频| 国产精品色午夜在线观看| 精品无人国产偷自产在线| 久久这里只有精品99| 国产成人一区二区三区| 欧美中文字幕视频在线观看| 欧洲s码亚洲m码精品一区| 欧美精品激情blacked18| 91av福利视频| 色偷偷噜噜噜亚洲男人的天堂| 78m国产成人精品视频| 中文字幕在线日韩| 欧美疯狂做受xxxx高潮| 欧美成年人在线观看| 成人国产在线激情| 91丨九色丨国产在线| 国产精品永久在线| 久久99国产综合精品女同| 欧美日韩国产一区二区| 国产色婷婷国产综合在线理论片a| 亚洲香蕉av在线一区二区三区| 91av视频导航| 国产精品爽黄69| 国产精品亚洲精品| 日韩视频免费看| 美女av一区二区| 亚洲人成77777在线观看网| 成人写真视频福利网| 日韩成人免费视频| 久久久久久久久国产精品| 欧美亚洲国产成人精品| 九九热精品视频在线播放| 在线中文字幕日韩| 国产精品精品一区二区三区午夜版| 亚洲第一国产精品| 亚洲日本中文字幕免费在线不卡| 在线观看日韩av| 亚洲天天在线日亚洲洲精| 国产精品视频yy9099| 欧美自拍视频在线| 欧美一区二三区| 亚洲精品电影网| 国产精品青草久久久久福利99| 亚洲欧洲日产国码av系列天堂| 欧美成人精品xxx| 亚洲免费视频一区二区| 欧美激情一区二区三区成人| 亚洲精品一区av在线播放| 亚洲欧美制服第一页| 国产精品7m视频| 久久久久久久激情视频| 日韩网站免费观看高清| 亚洲综合精品伊人久久| 欧美成年人网站| 色无极影院亚洲| 亚洲综合小说区| 国产女人18毛片水18精品| 色综合视频一区中文字幕| 日韩女优在线播放| 6080yy精品一区二区三区| 欧美福利视频在线观看| 91国内精品久久| 韩国精品美女www爽爽爽视频| 国产精品久久久久久久久久新婚| 国产精品7m视频| 国产精品黄页免费高清在线观看| 日韩av最新在线观看| 亚洲视频一区二区三区| 2025国产精品视频| 国产精品99久久久久久www| 91视频免费在线| 欧美韩国理论所午夜片917电影| 精品综合久久久久久97| 欧美大片欧美激情性色a∨久久| 国产精品一二区| 日韩经典中文字幕| 亚洲人成绝费网站色www| 红桃视频成人在线观看|