關於Listview和Checkbox控件嵌套出現的各種問題

前言

隨着安卓開發的深入瞭解,越來越發現,很多看似簡單的東西,在沒有思路的情況下,盲目去寫,會發現寫的最後連自己都感覺各種漏洞和問題,
其實這個也是我的親身經歷, 當初我在面對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嵌套的問題就講到這裏,如果我說的這個方法能夠幫助到你, 那麼請給我點個贊把!如果我當前有寫的不好的地方,歡迎指出!
最後,感覺大家閱讀本篇文章!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章