【问题标题】:CheckBox gets unchecked on scroll in a custom listviewCheckBox 在自定义列表视图中滚动时未选中
【发布时间】:2012-03-07 17:33:03
【问题描述】:

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

 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;  

}  

}

【问题讨论】:

    标签: android listview checkbox unchecked


    【解决方案1】:
    每当需要绘制以前不可见的列表项时,都会调用

    getView()。由于您每次调用此方法时都重新创建itemChecked[],因此您将取消选中新复选框,并且每个结果视图都有一个不同的数组。 (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;
        }
    }
    

    【讨论】:

    • @Zapi 解决了这个问题。我当时很傻。谢谢。
    • 我已经稍微更新了代码。不过它可能并没有真正起作用:)
    • mCheckedState = new boolean[objects.size()];在这一行中什么是对象??
    • @TechnoCracker 是您用作列表视图源的任何数据的占位符。您可能希望从 Object 更改为更具体的内容,并在 extends ArrayAdapter&lt;Object&gt; 中也这样做。
    • stackoverflow.com/questions/27896997/… 这是我的问题,我也有同样的问题。请帮助我在那个问题...
    【解决方案2】:

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


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

    希望对你有所帮助。

    【讨论】:

    【解决方案3】:

    在我的情况下,我解决了这个问题如下:

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

    【讨论】:

    • 在这个例子中,什么是GridViewActivity??
    【解决方案4】:

    你应该把setChecked()放在setOnCheckedChangeListener()之后。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多