Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android基礎入門教程——2.4.5 ListView之checkbox錯位問題解決

Android基礎入門教程——2.4.5 ListView之checkbox錯位問題解決

編輯:關於Android編程

Android基礎入門教程——2.4.5 ListView之checkbox錯位問題解決

標簽(空格分隔): Android基礎入門教程


本節引言:

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


1.問題發生的原因:

這是網上找來的一幅關於ListView getView方法調用機制的一個圖

title=

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

title=

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


2.解決方法示例:

好的存儲這個Checkbox的方法有很多,你可以放到一個HashMap

public class Person implements Serializable{
    private String name;
    private String number;
    private boolean checkStatus;

    public Person(String name, String number) {
        super();
        this.name = name;
        this.number = number;
        this.checkStatus = false;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public boolean getCheckStatus() {
        return checkStatus;
    }

    public void setCheckStatus(boolean checkStatus) {
        this.checkStatus = checkStatus;
    }

}

實現的Adapter類:ContactListAdapter.java

public class ContactListAdapter extends BaseAdapter {

    private List mData;
    private Context mContext;

    public ContactListAdapter(List data, Context context) {
        mData = data;
        mContext = context;
    }

    // 定義一個刷新數據的方法
    public void changeData(List data) {
        mData = data;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int index = position;
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.item_contact, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.ly = (RelativeLayout) convertView
                    .findViewById(R.id.lyContactListItem);
            viewHolder.txtName = (TextView) convertView
                    .findViewById(R.id.txtName);
            viewHolder.txtNumber = (TextView) convertView
                    .findViewById(R.id.txtNumber);
            viewHolder.cbxStatus = (CheckBox) convertView
                    .findViewById(R.id.cbxStatus);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.cbxStatus
                .setOnCheckedChangeListener(new OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked) {
                        if (isChecked)
                            mData.get(index).setCheckStatus(true);
                        else
                            mData.get(index).setCheckStatus(false);
                    }
                });
        if (mData.get(position).getCheckStatus() == true)
            viewHolder.cbxStatus.setChecked(true);
        else
            viewHolder.cbxStatus.setChecked(false);
        viewHolder.txtName.setText(mData.get(index).getName());
        viewHolder.txtNumber.setText(mData.get(index).getNumber());
        return convertView;

    }

    private class ViewHolder {
        RelativeLayout ly;
        TextView txtName;
        TextView txtNumber;
        CheckBox cbxStatus;
    }
}

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


 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved