CheckBox在自定义列表视图中滚动时未选中

时间:2012-02-16 10:07:42

标签: android listview checkbox unchecked

我知道这个问题已被一遍又一遍地问过,但我仍然无法找到真正帮助我的建议。每当列表向下滚动时,都会取消选中该复选框。是的我正在使用布尔数组来存储值,但这仍然无法解决问题。这是我的代码。请为此建议一个解决方案。谢谢。

 public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
        final ViewHolder holder;
final boolean[] itemChecked=new boolean[30];

    LayoutInflater inflater =  context.getLayoutInflater();  
    if(convertView==null)  
    {  
        convertView = inflater.inflate(R.layout.custom_list, null);
        holder = new ViewHolder();  
        holder.txtViewTitle = (TextView) convertView.findViewById(R.id.title_text);  
        holder.txtViewDescription = (TextView) convertView.findViewById(R.id.description_text);  
        holder.cb=(CheckBox) convertView.findViewById(R.id.cb);
        convertView.setTag(holder);  

    }  

    else  
    {
        holder=(ViewHolder)convertView.getTag();  

     }  

    holder.cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub
                 itemChecked[position] = isChecked;
                 if(itemChecked[position])
                 {
                     holder.cb.setChecked(true);
                 }
                 else
                 {
                     holder.cb.setChecked(false);
                 }
      holder.txtViewTitle.setText(title[position]);  
    holder.txtViewDescription.setText(description[position]);  
    holder.cb.setChecked(itemChecked[position]);
  holder.txtViewDescription.setFocusable(false);
  holder.txtViewTitle.setFocusable(false);

return convertView;  

}  

}

4 个答案:

答案 0 :(得分:11)

只要需要绘制以前不可见的列表项,就会调用 getView()。由于每次调用此方法时都会重新创建itemChecked[],因此您将取消选中新复选框,并为每个生成的View显示不同的数组。 (Java中的final不会像C中那样使该字段独一无二) 解决这个问题的最简单方法是使itemChecked成为一个类成员,并根据该成员设置/恢复复选框状态。

public class MyListAdapter extends ArrayAdapter<Object> {
    private final boolean[] mCheckedState;
    private final Context mContext;

    public MyListAdapter(Context context, int resource, int textViewResourceId, List<Object> objects) {
        super(context, resource, textViewResourceId, objects);
        mCheckedState = new boolean[objects.size()];
        mContext = context;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // simplified to just a Checkbox
        // ViewHolder and OnCheckedChangeListener stuff left out 
        CheckBox result = (CheckBox)convertView;
        if (result == null) {
            result = new CheckBox(mContext);
        }
        result.setChecked(mCheckedState[position]);
        return result;
    }
}

答案 1 :(得分:3)

这是一个例子。阅读getView中的注释(...) 下面提供的适配器。


class TaskObject {
        private int pid;
        private String processName;
        private boolean toKill;
///getters/setters
        public boolean isToKill() {
            return toKill;
        }    
        public void setToKill(boolean toKill) {
            this.toKill = toKill;
        }
       ................................
    }

class TaskListAdapter extends BaseAdapter {

    private static final String TAG = "adapter";

    ArrayList<TaskObject> list;
    Context context;

    public TaskListAdapter(Context context) {
        Log.d(TAG, "created new task list adapter");
        this.context = context;
        if (list == null) {
            list = new ArrayList<TaskObject>();
        }
    }

    public void addTask(TaskObject taskObject) {
        list.add(taskObject);
    }

    public void clearTasks() {
        list.clear();
        Log.d(TAG, "list size:" + list.size());
        this.notifyDataSetChanged();
    }

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

    public TaskObject getItem(int position) {
        return list.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {        
        RelativeLayout rl = new RelativeLayout(context);
        TextView textPid = new TextView(context);
        textPid.setText(Integer.toString(getItem(position).getPid()));
        TextView textName = new TextView(context);
        textName.setText(getItem(position).getProcessName()); 

       /////Here is your and it will set back your checked item after scroll
         CheckBox chckKill = new CheckBox(context);
            if(getItem(position).isToKill())
            {
                    chckKill.setChecked(true);
            }
       ////////////////////////////////////////////////////////////////////           

            chckKill.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                //is chkIos checked?
             if (((CheckBox) v).isChecked()) {
                 getItem(position).setToKill(true);
                }
              }
            });
            chckKill.setTag(getItem(position).getPid());
        /////////NOT LAYOUTED USE LAYOUT
            rl.addView(chckKill);
            rl.addView(textName);
            rl.addView(textPid);
            return rl;
        }    

希望它有助于升技。

答案 2 :(得分:2)

在我的案例中,我解决了这个问题如下:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    ViewHolder holder = null;

    TextView title = null;
    ImageView thumbnail = null;
    CheckBox checkBox = null;

    Content rowData = GridViewActivity.contents.get(position);

    if (null == convertView) {
        convertView = mInflater.inflate(R.layout.grid_item, null);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    }
    holder = (ViewHolder) convertView.getTag();

    title = holder.getContentTitle();
    title.setText(rowData.getTitle());

    thumbnail = holder.getThumbnail();
    thumbnail.setImageResource(rowData.getIcon());

    checkBox = holder.getCheckBox();
    checkBox.setTag(position);

    checkBox.setChecked(rowData.isCheckBox());

    checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            int getPosition = (Integer) buttonView.getTag();
            GridViewActivity.notifyCheckChanges(getPosition,
                    buttonView.isChecked());
        }
    });

    return convertView;
}

答案 3 :(得分:0)

您应将<li>放在<Link>之后。