解决ListView内置选择框复用混乱的问题

一、概述

有时候我们需要实现这样一个ListView,比如购物车中,选中某些物品,买单结账。很多时候使用的就是ListView用于展示物品详情,用户点中某个Item,选择框置位。但是因为ViewHolder的复用,下拉的时候会出现复用的Item在没有选中的情况下,选择框是钩取的,这时候要自定义一个适配器Adapter来解决这个问题。

二、实现

在自定义Adapter时,我们会传入数据源,用于实时更新item的显示,一般数据源是List< Map < String, Object > >类型的数据mData,通过item的位置position可以查找到该item对应的map,通过该map就可以获取相应组件需要显示的值。
操作如:mData.get(position).get("id") //获取第position个item的id

那么解决的思路就是在对应的map中加上相应字段“isClicked”,默认为false,当用户点击了该item,则修改为选中状态true,通过调用listClickAdapter.notifyDataSetChanged(); 来进行更新。

ps:之前想的是直接点中修改ChechBox的状态,不修改mData的数据 ,这样会出现的问题是,触屏滑下去后,再滑上来的时候会出现混乱。原因是再次滑上来的时候,Item是进行重画的,依照的正是mData的数据,假如没有记录CheckBox状态的字段,CheckBox的状态保持复用之前的状态,而不是对应Item的状态。

实现代码(当然可以用ViewHolder进行修改):

public class ListClickAdapter extends BaseAdapter{

    private LayoutInflater mInflater;
    private List> mData;// 存储的EditText值

    public ListClickAdapter(Context context, List> data) {
        mData = data;
        mInflater = LayoutInflater.from(context);
    }

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

    @Override
    public Object getItem(int position) {
        return null;
    }

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

    private Integer index = -1;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = mInflater.inflate(R.layout.item_buynews, null);

        TextView id = (TextView)view.findViewById(R.id.item_nid);
        TextView name = (TextView)view.findViewById(R.id.item_name);
        TextView office = (TextView)view.findViewById(R.id.item_office);
        TextView price = (TextView)view.findViewById(R.id.item_price);
        TextView cycle = (TextView)view.findViewById(R.id.item_cycle);
        TextView content = (TextView)view.findViewById(R.id.item_content);
        CheckBox buy = (CheckBox)view.findViewById(R.id.check_buy);

        id.setText(String.valueOf(mData.get(position).get("id")));
        name.setText(String.valueOf(mData.get(position).get("name")));
        office.setText(String.valueOf(mData.get(position).get("office")));
        price.setText(String.valueOf(mData.get(position).get("price")));
        cycle.setText(String.valueOf(mData.get(position).get("cycle")));
        content.setText(String.valueOf(mData.get(position).get("content")));
        if(mData.get(position).get("isClick") == true) {
            buy.setChecked(true);
        }else {
            buy.setChecked(false);
        }
        return view;
    }
}

客户端调用:

        listClickAdapter = new ListClickAdapter(getActivity(), getData());
        setListAdapter(listClickAdapter);

客户端修改选中状态:

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        TextView etId, etPrice;
        CheckBox checkBox = (CheckBox) v.findViewById(R.id.check_buy);
        etId = (TextView) v.findViewById(R.id.item_nid);
        etPrice = (TextView) v.findViewById(R.id.item_price);

        if(checkBox.isChecked()) { //选中了
            checkBox.setChecked(false); //变成不选
            list1.get(position).put("isClick", false);
            listClickAdapter.notifyDataSetChanged();
        }else { //未选中
            checkBox.setChecked(true); //变成选
            list1.get(position).put("isClick", true);
            listClickAdapter.notifyDataSetChanged();
        }
    }

你可能感兴趣的:(Android学习之路)