前言
隨着安卓開發的深入瞭解,越來越發現,很多看似簡單的東西,在沒有思路的情況下,盲目去寫,會發現寫的最後連自己都感覺各種漏洞和問題,
其實這個也是我的親身經歷, 當初我在面對Listview和Checkbox控件的嵌套問題的時候,我發現我處理的很差,很多問題,而且有特別不好改,主要原因是自己的思路沒有建立起來,去借鑑別人的代碼,導致我很長時間都不敢再去動那個頁面.
最近偶然一次機會,別人問到過這個問題,我也是硬着頭皮重新去回憶這個問題,突然發現,以前還是經驗太少,不敢去面對自己出現的問題,現在我也跟大家分享一下我的心理歷程和關於這個問題解決的心得.
問題點:
第一個:關於Listview和Checkbox的複用問題
如果大家是第一次遇到這個問題的話,沒有一個好的思路,確實是難以下手,在心理上就已經被嚇怕了,其實是沒有必要的,越是這樣情況下,你越是要冷靜,慢慢去理清頭緒.
我們知道,listview的複用問題很常見,在這裏我重點說下思路,要知道每個item裏面都有一個chekcbox,如果我有20個item,我選中的第一個item的checkbox,那麼下面一定會有一個item會跟第一個item進行復用,對吧?那怎麼辦呢?
別急,爲什麼會產生這個問題,我們可以從三個地方思考:
第一個,能不能不讓條目複用?每一個都獨一無二?
第二個,能不能讓checkbox不復用,item還是複用?
第三個,checkbox的選中狀態也是一種數據,我能不能讓數據不復用?
其實,第一種情況,肯定不可取的,因爲不進行復用,如果條目多了,會導致OOM.這可得不償失.所以第一種情況是不可取的.
第二種情況,checkbox不復用,這種說法是不成立的,因爲checkbox依附item中,沒法做到讓其中單獨複用!
其實大家一看就知道第三種,就有很多種思路了把?就是讓每個checkbox的選中狀態的值都是唯一的,這樣就不會導致複用的時候出現選一個而選多個的情況了!
下面我貼出我自己的寫的一個例子,供大家參考!!
private class MyAdapter extends MyBaseAdapter<String> {
HashMap<Integer, Boolean> hashMap = new HashMap<>();
public MyAdapter(List dataList) {
super(dataList);
initMap(dataList);
}
/**
*初始化map集合,將所有checkbox默認設置爲false
*/
private void initMap(List dataList) {
if (!dataList.isEmpty()) {
for (int i = 0; i < dataList.size(); i++) {
hashMap.put(i, false);}
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(UIUtils.getContext(), R.layout.item_listview, null);
holder.mtv = (TextView) convertView.findViewById(R.id.textview);
holder.mCheckbox = (CheckBox) convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mtv.setText(mDataList.get(position));
holder.mCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox checkbox = (CheckBox) v;
if (checkbox.isChecked()) {
hashMap.put(position,true);//每個position爲唯一索引,進行存和取
}else{
hashMap.put(position,false);//每個position爲唯一索引,進行存和取
}
}
});
holder.mCheckbox.setChecked(hashMap.get(position)); //設置checkbox的狀態
return convertView;
}
public class ViewHolder {
CheckBox mCheckbox;
TextView mtv;
}
}
item的佈局很簡單,就是一個checkbox和textview,以上主要實現的邏輯是:
所有的checkbox狀態都用一個map集合存起來,
在頁面加載時候,在適配器的構造函數中需要對map集合進行初始化(所有的checkbox默認選中是false)
當你點擊checkbox的時候,我們去重新設置checkbox的狀態,然後獲取,這樣就能夠完美的解決複用問題了
第二個關於Listview和Checkbox的單選,多選問題
我們剛剛解決了複用問題,相信大家對這個問題已經不再無從下手了.關於Listview和Checkbox的多選問題,其實上面的代碼,完全不懂就已經是可以多選了,因此,可能對某些需求來講,多選可能是一個bug,(哈哈,開個玩笑!)
我們重點說一下checkbox的單選問題.其實這個問題也不難,看看你不能夠想通了,單選其實就是你在點擊某個checkbox的時候,讓上次選中的狀態全部變成false的狀態對吧?那麼我們何必在點擊選中的時候,就將每個checkbox的狀態全部置爲false呢?這樣,不管你選中還不選中,都能做到單向選擇啦!!
因此我們只需要在這裏加上2行代碼就可以完美解決了!!!
holder.mCheckbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox checkbox = (CheckBox) v;
initMap(mDataList); //清空之前所有的選擇
notifyDataSetChanged(); //刷新適配器
if (checkbox.isChecked()) {
hashMap.put(position,true);
}else{
hashMap.put(position,false);
}
}
});
第三個:關於Listview和Checkbox會搶佔焦點的問題(也就是Checkbox的點擊事件被攔截)
如果有人會遇到這個問題,其實只要加一個屬性就好了.就可以完美的解決checkbox點擊和listview的點擊事件會干擾的問題.
我們需要在item的根佈局加上一個屬性!!
android:descendantFocusability=”blocksDescendants”
就可以完美解決了!!
好了,關於Listview和Checkbox嵌套的問題就講到這裏,如果我說的這個方法能夠幫助到你, 那麼請給我點個贊把!如果我當前有寫的不好的地方,歡迎指出!
最後,感覺大家閱讀本篇文章!