CheckBox gets unchecked on scroll in a custom listview

前端 未结 4 1053
野趣味
野趣味 2020-11-29 12:13

I know that this question has been asked over and over again but still I\'ve not been a able to find a suggestion that really helps me. The checkbox is unchecked whenever th

相关标签:
4条回答
  • 2020-11-29 12:43

    You should place setChecked() after setOnCheckedChangeListener().

    0 讨论(0)
  • 2020-11-29 12:45

    getView() is called whenever a previously invisible list item needs to be drawn. Since you recreate itemChecked[] each time this method is called you will have the new checkbox unchecked and a different Array for each resulting View. (final in Java does not make that field unique like in C) Simplest way to solve that is to make itemChecked a classmember and set / restore checkbox state based on that one.

    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;
        }
    }
    
    0 讨论(0)
  • 2020-11-29 12:56

    Here is an example. Read the comments in the getView(...) of the adapter provided below.


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

    hope it helps abit.

    0 讨论(0)
  • 2020-11-29 13:03

    In mycase, I solved this issue as follows :

    @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;
    }
    
    0 讨论(0)
提交回复
热议问题