RecyclerView中使用CheckBox出現勾選混亂的解決方案
做安卓的,應該都有使用過ListView或RecyclerView,並且可能都有遇到過在這個兩個控制元件中使用CheckBox的時候出現勾選錯亂的問題。這是因為ListView或RecyclerView都使用了複用機制,當在ListView或RecyclerView中的每一項都新增一個CheckBox時,勾選當前頁面的幾個CheckBox會發現下面還有其他的CheckBox也被勾選了,今天我們就來討論如何解決這個問題。
首先建立一個一個專案,然後在activity_main中新增一個ListView或RecyclerView控制元件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/xgsg_background_gray"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:background="@color/xgsg_background_gray"
android:scrollbars="vertical"/>
</LinearLayout>
接下來為這個RecyclerView建立一個item佈局檔案,命名為item_recyclerview,並新增一個CheckBox空間,程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="horizontal">
<CheckBox
android:id="@+id/check"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:background="@null"
android:button="@drawable/check_state"
android:layout_width="20dp"
android:layout_height="20dp" />
</LinearLayout>
接下來就是編輯MainActivity,findViewById找到佈局中的控制元件,然後準備資料,為其設定Adapter等,
這些都是使用ListView或RecyclerView的基本流程,使用過ListView或RecyclerView的朋友,應該很清楚,這裡我就不再廢話了,下面就直接講重點吧。
解決CheckBox的選擇錯亂,只需要兩步。
一、定義一個全域性變數陣列public boolean[] flag;//把flag陣列定義為全域性變數
用於儲存CheckBox的選擇狀態。
二、我們在設定Adapter繼承RecyclerView.Adapter的時候只需在onBindViewHoder方法編寫這個幾句程式碼
複用CheckBox的時候都會去呼叫一次CheckBox的選擇監聽,所以我們第一次先把監聽狀態設定為空,直接從儲存好的選中狀態陣列中獲取設定它的選擇狀態,然後在重新設定它的選擇監聽把操作後的選擇狀態重新儲存選中狀態陣列中,這樣我們每次獲取到的就都是最新的選擇狀態。
myViewHolder.checkBox.setOnCheckedChangeListener(null);//先設定一次CheckBox的選中監聽器,傳入引數null
myViewHolder.checkBox.setChecked(flag[position]);//用陣列中的值設定CheckBox的選中狀態
//再設定一次CheckBox的選中監聽器,當CheckBox的選中狀態發生改變時,把改變後的狀態儲存在陣列中
myViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
flag[position] = b;
}
});
完整程式碼如下:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
MyViewHolder myViewHolder = (MyViewHolder) holder;
myViewHolder.checkBox.setText(content.get(position));
myViewHolder.checkBox.setOnCheckedChangeListener(null);//先設定一次CheckBox的選中監聽器,傳入引數null
myViewHolder.checkBox.setChecked(flag[position]);//用陣列中的值設定CheckBox的選中狀態
//再設定一次CheckBox的選中監聽器,當CheckBox的選中狀態發生改變時,把改變後的狀態儲存在陣列中
myViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
flag[position] = b;
}
});
}
擴充套件:如果是從外界要來操作CheckBox的選擇狀態也很簡單,我們已經把CheckBox的選擇狀態值都儲存到了一個全域性陣列中,所以外界只要操作該陣列的狀態值就可以了,然後重新重新整理一下資料介面卡就可以了。