错误-两个复选框在 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。
我正在开发带有复选框的 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。