Android在ListView中使用CheckBox出现滚动自动选中的问题。 5C

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;
}

}

4个回答

建议为指定控件,设置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

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问