错误-两个复选框在 ListView 中同时得到检查

Error-Two checkboxes get checks at the same time in a ListView

我正在开发带有复选框的 ListView。我的问题有点奇怪,每当我检查 ListView 中的任何项目时,另一个项目也会被检查。我将选中项目的 ID 存储在 setOnCheckedChangeListener 事件的 HashMap 中。我记录了 HashMap 结果,它存储在那些被点击的项目 ID 上,而不是随机检查的项目 ID 上。

我真的需要你的帮助。

这是我的 BaseAdapter 代码:

public class StrengthOfDemandAdapter extends BaseAdapter {
    ArrayList<Products> list;
    //private LayoutInflater layoutInflater;
    private static HashMap<Integer, String> selectedSODBrandsMap = new HashMap<Integer, String>();
    private SQLiteDatabase database;
    private SQLiteOpenHelper dbHelper;
    //private static ArrayList<String> selectSODBRandNames = new ArrayList<String>();
    private Context con;
    private int imageNo;

    public StrengthOfDemandAdapter(Context context, ArrayList<Products> list, int imageNumber) {
        this.list = list;
        this.con = context;
        this.imageNo = imageNumber;
        //layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        dbHelper = new DBHelper(con);
        database = dbHelper.getWritableDatabase();
    }

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

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

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

    @Override
    public View getView(final int i, View convertView, ViewGroup viewGroup) {
        View v = convertView;
        final ViewHolder mHolder;

        //Log.i("SIZE", "getView: "+list.size());
        if(v == null){
            //Log.i("INFO 2", "openDialog: "+((Products)list.get(i)).getProductID()+", "+((Products)list.get(i)).getProductName());
            LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.strengthofdemandlistview, null);
            mHolder = new ViewHolder();

            mHolder.mCheckBox = (CheckBox) v.findViewById(R.id.SODCheckBox);


            v.setTag(mHolder);
        }else {
            mHolder = (ViewHolder) v.getTag();
            //mHolder.mCheckBox.setOnCheckedChangeListener(null);
        }
        //mHolder.mCheckBox.setFocusable(false);
        mHolder.mCheckBox.setText(((Products)list.get(i)).getProductName());
        mHolder.mCheckBox.setTag(((Products)list.get(i)).getProductID());

        mHolder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    //Log.i("YES", "onCheckedChanged: YES"+((Products)list.get(i)).getProductName());
                    selectedSODBrandsMap.put(((Products)list.get(i)).getProductID(), ((Products)list.get(i)).getProductName());
                }else {
                    //Log.i("NO", "onCheckedChanged: NO"+((Products)list.get(i)).getProductName());
                    selectedSODBrandsMap.remove(((Products)list.get(i)).getProductID());
                }
            }
        });


        return v;
    }

    private class ViewHolder {
        private CheckBox mCheckBox;

    }

    public static HashMap<Integer, String> sendSelectedSODBrandsMap(){
        return selectedSODBrandsMap;
    }

}

这是因为listview的回收机制。

将您的适配器代码更改为

public class StrengthOfDemandAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener {

    private SparseBooleanArray mCheckStates;
    ArrayList<Products> list;
    //private LayoutInflater layoutInflater;
    private static HashMap<Integer, String> selectedSODBrandsMap = new HashMap<Integer, String>();
    private SQLiteDatabase database;
    private SQLiteOpenHelper dbHelper;
    //private static ArrayList<String> selectSODBRandNames = new ArrayList<String>();
    private Context con;
    private int imageNo;

    public StrengthOfDemandAdapter(Context context, ArrayList<Products> list, int imageNumber) {
        this.list = list;
        this.con = context;
        this.imageNo = imageNumber;
        //layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        dbHelper = new DBHelper(con);
        database = dbHelper.getWritableDatabase();
        mCheckStates = new SparseBooleanArray(list.size());
    }

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

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

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

    @Override
    public View getView(final int i, View convertView, ViewGroup viewGroup) {
        View v = convertView;
        final ViewHolder mHolder;

        //Log.i("SIZE", "getView: "+list.size());
        if(v == null){
            //Log.i("INFO 2", "openDialog: "+((Products)list.get(i)).getProductID()+", "+((Products)list.get(i)).getProductName());
            LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.strengthofdemandlistview, null);
            mHolder = new ViewHolder();

            mHolder.mCheckBox = (CheckBox) v.findViewById(R.id.SODCheckBox);


            v.setTag(mHolder);
        }else {
            mHolder = (ViewHolder) v.getTag();
            //mHolder.mCheckBox.setOnCheckedChangeListener(null);
        }
        //mHolder.mCheckBox.setFocusable(false);

        Product product = getItem(i);
        mHolder.mCheckBox.setText(product.getProductname());
        holder.mCheckBox.setTag(position);
        holder.mCheckBox.setChecked(mCheckStates.get(position, false));
        holder.mCheckBox.setOnCheckedChangeListener(this);

        return v;
    }

    private class ViewHolder {
        private CheckBox mCheckBox;

    }

   public boolean isChecked(int position) {
        return mCheckStates.get(position, false);
    }

    public void setChecked(int position, boolean isChecked) {
        mCheckStates.put(position, isChecked);

    }

    public void toggle(int position) {
        setChecked(position, !isChecked(position));

    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView,
                                 boolean isChecked) {

        mCheckStates.put((Integer) buttonView.getTag(), isChecked);

    }

    public static HashMap<Integer, String> sendSelectedSODBrandsMap(){
        return selectedSODBrandsMap;
    }

}

key是SparseBooleanArray mCheckStates;,用来记住index处的checked item。