问题描述
- Android在ListView中使用CheckBox出现滚动自动选中的问题。
-
1、列表子项对象中有state字段为0表示checkBox选中,为1表示未选中。
2、滚动时会出现自动选中checkBox框的情况,但是选中CheckBox框会进行关注操作。
3、进行了checkBox状态的保存,需要在getView中调用setCheck的方法。
以下是源代码,求高手救急!
package com.yang.gaokao.adapter;import java.util.ArrayList;
import java.util.HashMap;http://ask.csdn.net/questions?type=reward#
import java.util.List;
import java.util.Map;import com.way.util.T;
import com.yang.gaokao.R;
import com.yang.gaokao.constant.ConstantUtil;
import com.yang.gaokao.model.FocusedMajorBaseResBean;
import com.yang.gaokao.model.FocusedMajorResBean;
import com.yang.gaokao.util.Util;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;public class FocusedMajorListAdapter extends BaseAdapter{
private Context mContext; private List<FocusedMajorBaseResBean> list; private Map<Integer, String> isSelected; private Map<Integer, CheckBox> cbHashs; public FocusedMajorListAdapter(Context context, FocusedMajorResBean resBean) { mContext = context; list = resBean.getBody(); cbHashs = new HashMap<Integer, CheckBox>(); //这儿定义isSelected这个map是记录每个listitem的状态,初始状态全部为false。 isSelected = new HashMap<Integer, String>(); for (int i = 0; i < list.size(); i++) { isSelected.put(i, list.get(i).getState()); } } public FocusedMajorListAdapter(Context context, List<FocusedMajorBaseResBean> beans) { mContext = context; list = beans; } public void addData(List<FocusedMajorBaseResBean> data) { if (list == null) { list = new ArrayList<FocusedMajorBaseResBean>(); } list.addAll(data); notifyDataSetChanged(); } public void addDataAtFront(List<FocusedMajorBaseResBean> data) { List<FocusedMajorBaseResBean> old = list; list = new ArrayList<FocusedMajorBaseResBean>(); list.addAll(data); list.addAll(old); notifyDataSetChanged(); } public void replaceData(List<FocusedMajorBaseResBean> data) { this.list = data; notifyDataSetChanged(); } public List<FocusedMajorBaseResBean> getList() { return list; } @Override public int getCount() { return list == null ? 0 : list.size(); } @Override public Object getItem(int position) { return list == null ? null : list.get(position); } @Override public long getItemId(int position) { return position; } private CheckBox cbFocus; @Override public View getView( final int position, View convertView, ViewGroup parent) { Holder holder = null; if( convertView == null ){ convertView = LayoutInflater.from(mContext).inflate( R.layout.j_item_focused_major_list, null); holder = new Holder(); holder.tvSpecialtyName = (TextView) convertView.findViewById(R.id.specialtyName); holder.tvSpecialtyCode = (TextView) convertView.findViewById(R.id.specialtyCode); holder.tvDegreeName = (TextView) convertView.findViewById(R.id.degreeName); holder.tvSchoolingPeriod = (TextView) convertView.findViewById(R.id.schoolingPeriod); convertView.setTag(holder); }else{ holder = (Holder) convertView.getTag(); } cbFocus = (CheckBox) convertView.findViewById(R.id.btnFocus); cbHashs.put(position,cbFocus); final FocusedMajorBaseResBean itemBean = list.get(position); holder.tvSpecialtyName.setText(Util.convertNullToOhter(itemBean.getName())); holder.tvSpecialtyCode.setText("专业代码:"+Util.convertNullToOhter(itemBean.getSpecialtyCode())); holder.tvDegreeName.setText("授予学位:" + Util.convertNullToOhter(itemBean.getDegreeName()) ); holder.tvSchoolingPeriod.setText("修学年限:"+ Util.convertNullToOhter(itemBean.getSchoolingPeriod()) ); String state = Util.convertNullToZero(itemBean.getState()); //在初始化CheckBox状态和设置状态变化监听事件之前,先把状态变化监听事件设置为null if ( isSelected.get(position).equals(ConstantUtil.FOCUS_YES) ) { cbHashs.get(position).setText("已关注"); cbHashs.get(position).setChecked(true); }else { cbHashs.get(position).setText("关注"); cbHashs.get(position).setChecked(false); } cbHashs.get(position).setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { String user_id = mContext.getSharedPreferences(ConstantUtil.USER_SHARE_PREFERENCES, Context.MODE_PRIVATE).getString(ConstantUtil.USER_ID,""); if ( isChecked ) { //关注 isSelected.put(position, ConstantUtil.YES); cbHashs.get(position).setText("已关注");
// T.showShort(mContext, "关注");
// Util.requestMyCollect(mContext, user_id, itemBean.getId(),
// ConstantUtil.COLECT_TYPE_MAJ, ConstantUtil.COLECT_IS_ADD, null);
}else {
//取消关注
isSelected.put(position, ConstantUtil.NO);
cbHashs.get(position).setText("关注");
// T.showShort(mContext, "取消关注");
// Util.requestMyCollect(mContext, user_id, itemBean.getId(),
// ConstantUtil.COLECT_TYPE_MAJ, ConstantUtil.COLECT_IS_UPDATE, null);
}
}
} );return convertView; } public class Holder{ TextView tvSpecialtyName,tvSpecialtyCode,tvDegreeName,tvSchoolingPeriod; }
}
解决方案
Android ListView中使用CheckBox等的混乱问题
关于listview中checkbox的选中问题
解决方案二:
Android ListView中使用CheckBox等的混乱问题
关于listview中checkbox的选中问题
解决方案三:
建议为指定控件,设置tag,再根据tag提取,达到一一对应。
解决方案四:
1、将cbFocus也作为Holder的成员。
2、为FocusedMajorBaseResBean这个类增加一个成员变量isSelected,表示是否选中了。
3、setOnCheckedChangeListener(),每次选择/取消选择后,修改List list中对应元素的isSelected属性:list.get(position).isSelected=true; 或 list.get(position).isSelected=false。
4、在getView() 中根据FocusedMajorBaseResBean的isSelected属性,判断cbFocus的状态。
5、不需要下面两个变量纪录选择的信息了:
private Map<Integer, String> isSelected;
private Map<Integer, CheckBox> cbHashs;
6、我修改后的代码如下,由于我没有你的一些类,所以需要你自己验证:
public class FocusedMajorListAdapter extends BaseAdapter {
private Context mContext;
private List<FocusedMajorBaseResBean> list;
public FocusedMajorListAdapter(Context context, FocusedMajorResBean resBean) {
mContext = context;
list = resBean.getBody();
}
public FocusedMajorListAdapter(Context context,
List<FocusedMajorBaseResBean> beans) {
mContext = context;
list = beans;
}
public void addData(List<FocusedMajorBaseResBean> data) {
if (list == null) {
list = new ArrayList<FocusedMajorBaseResBean>();
}
list.addAll(data);
notifyDataSetChanged();
}
public void addDataAtFront(List<FocusedMajorBaseResBean> data) {
List<FocusedMajorBaseResBean> old = list;
list = new ArrayList<FocusedMajorBaseResBean>();
list.addAll(data);
list.addAll(old);
notifyDataSetChanged();
}
public void replaceData(List<FocusedMajorBaseResBean> data) {
this.list = data;
notifyDataSetChanged();
}
public List<FocusedMajorBaseResBean> getList() {
return list;
}
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
@Override
public FocusedMajorBaseResBean getItem(int position) {
return list == null ? null : list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.j_item_focused_major_list, null);
holder = new Holder();
holder.cbFocus = (CheckBox) convertView.findViewById(R.id.checkbox);
holder.tvSpecialtyName = (TextView) convertView
.findViewById(R.id.specialtyName);
holder.tvSpecialtyCode = (TextView) convertView
.findViewById(R.id.specialtyCode);
holder.tvDegreeName = (TextView) convertView
.findViewById(R.id.degreeName);
holder.tvSchoolingPeriod = (TextView) convertView
.findViewById(R.id.schoolingPeriod);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
final FocusedMajorBaseResBean itemBean = list.get(position);
holder.tvSpecialtyName.setText(Util.convertNullToOhter(itemBean
.getName()));
holder.tvSpecialtyCode.setText("专业代码:"
+ Util.convertNullToOhter(itemBean.getSpecialtyCode()));
holder.tvDegreeName.setText("授予学位:"
+ Util.convertNullToOhter(itemBean.getDegreeName()));
holder.tvSchoolingPeriod.setText("修学年限:"
+ Util.convertNullToOhter(itemBean.getSchoolingPeriod()));
if (itemBean.isSelected) {
holder.cbFocus.setText("已关注");
holder.cbFocus.setChecked(true);
} else {
holder.cbFocus.setText("关注");
holder.cbFocus.setChecked(false);
}
holder.cbFocus
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
String user_id = mContext.getSharedPreferences(
ConstantUtil.USER_SHARE_PREFERENCES,
Context.MODE_PRIVATE).getString(
ConstantUtil.USER_ID, "");
// 设置是否选择了,然后刷新控件
getItem(position).isSelected = isChecked;
if (isChecked) {
holder.cbFocus.setText("已关注");
holder.cbFocus.setChecked(true);
} else {
holder.cbFocus.setText("关注");
holder.cbFocus.setChecked(false);
}
}
});
return convertView;
}
public class Holder {
CheckBox cbFocus;
TextView tvSpecialtyName, tvSpecialtyCode, tvDegreeName,
tvSchoolingPeriod;
}
}
解决方案五:
原因,listview 的 getview是复用的。也就是你在翻滚页面时,如果也就是
} else {
holder = (Holder) convertView.getTag();
}
这里。
所以结果就是要每次将所有初始化数据都要写成
if()
else
补上初始值 即可
解决方案六:
holder.cbFocus.setChecked这个函数的调用会触发onCheckedChanged