ListView之checkbox錯位問題解決


本節引言:

作為ListView經典問題之一,如果你嘗試過自訂ListView的item,在上面帶有一個checkbox的話,那麼 當你的item數超過了一頁的話,就會出現這個問題,下面我們來分析下出現這種問題的原因,以及如何來 解決這個問題!


1.問題發生的原因:

這是網路上找來的一幅關於ListView getView方法呼叫機制的一個圖

1.jpg

上圖中有一個Recycler的東東,平常我們ListView上可見的Item處於記憶體中,而且他的Item則放在 這個Recycler中,第一次載入item時,目前頁面中的convertView都為NULL,當滾出螢幕,這是時候ConvertView不為空,所以新的一項會復用這個ConvertView! 我們可以寫個簡單的例子,跟著下log,下面是一些運行後的Log圖!

2.png

從圖中看出,Postion從12開始,ConvertView就不為空了,具體這裡代表的是什麼, 我也不知道,目測要走原始碼...我們知道這裡ConvertView會快取就好,就是因為這個原因 造成的checkbox錯位,所以第一個解決方法就是,不重複使用這個ConvertView,或者 說每次getView都將這個ConvertView設定為null,但如果需要顯示的Item數量龐大的話, 這個方法會顯得非常臃腫,一般實際開發我們使用的是下面的解決方法:找個東東來保存當前Item CheckBox的狀態,初始化的時候進行判斷,設定是否選中!


2.解決方法範例:

好的儲存這個Checkbox的方法有很多,你可以放到一個HashMap<Integer, Boolean>中, 每次初始化的時候依照postion取出對應的boolean值,然後再進行checkbox的狀態設定; 而筆者的做法則是在entity類別中加入了一個boolean值來判斷,以下是筆者一個專案中 抽取的程式碼,程式碼比較簡單,相信你看完會秒懂的~

Entity類別:Person.java

public class Person 實作可序列化{
    private String name;
    private String number;
      {
        super();
#        this.name = name;
          }

    public String getName( ) {
        return name;
##    }

    public void setName(String name) {##  public String getNumber( ) {
        返回號碼;
#    }

    public void setNumber(String number) {##   public boolean getCheckStatus( ) {
return checkStatus;
#    }

#    public void setCheckStatus(boolean checkStatus) {
    . }

實作的Adapter類別:ContactListAdapter.java

#
公共類別ContactListAdapter擴充BaseAdapter實作CompoundButton.OnCheckedChangeListener{

    私有List; mData;
    private Context mContext;

    public ContactListAdapter(List data, Context context) {.# text;
    }

    // 定義刷新資料的方法
    public void changeData(List data) {
        m
##    @Override
    public int getCount() {
        return mData.size();
    }
#      return mData.get(位置);
#    }

    @Override
    public long getItemId(int position) {
        返回位置;
    }

    @Override
    public View getView (int position, View convertView, ViewGroup parent) {
        final int index =position;
   == null) {
            convertView = LayoutInflater.from(mContext). inflate (
                    R.layout.item_contact, parent, false);#           viewHolder.ly = (RelativeLayout) convertView
              
            viewHolder.txtName = (TextView) convertView
                    .findViewById ) convertView
                     .findViewById(R.id.   cbxStatus = (CheckBox) convertView
                    .findViewById(R.id ##            viewHolder.cbxStatus.setTag(index);
        } 其他 {
viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.cbxStatus.setOnCheckedChanListList Data.get(position).getcheckStatus());
        viewHolder.txtName.setText(mData.get(index).getName());
        viewHolder.txt. }

    @Over
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
      if (isChecked)
            mData. get (index).setCheckStatus(true);
        else
            mData.get(index).setCheckStatus(false);
    }


#    私有類 ViewHolder {
RelativeLayout ly ;
        TextView txtName;
        TextView txtNumber;
    }
}

嘿嘿,非常簡單,另外別忘了一點:checkbox監聽器的方法要加入在初始化Checkbox狀態的程式碼之前哦~


本節引言:

好的,本節跟大家講解了ListView的一個經典問題,ListView中checkbox錯位的 問題解決,只需簡單的新增一個記錄checkbox選擇狀態的值,然後重寫checkbox 點選事件的時候,先做判斷~謝謝~


#