1

Perhaps this is a simple question, but I didn't find a solution yet.

I have a RecyclerView with CardView's as elements and each CardView has a CheckBox view inside it.

My intention is to make a list of Todo's, and when the user checks the checkbox, the checked item will move to the end of the list.

Currently my adapter is:

    private class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder>{

    protected class ViewHolder extends RecyclerView.ViewHolder
    {
        TextView todoTextView;
        TextView addedOnTextView;
        TextView dueToDateTextView;
        TextView dueToHourTextView;
        CheckBox checkBox;
        protected ViewHolder(CardView cv)
        {
            super(cv);
            this.todoTextView = (TextView) cv.findViewById(R.id.todo_text);
            this.addedOnTextView = (TextView) cv.findViewById(R.id.added_on);
            this.dueToDateTextView = (TextView) cv.findViewById(R.id.due_to_date);
            this.dueToHourTextView = (TextView) cv.findViewById(R.id.due_to_hour);
            this.checkBox = (CheckBox)cv.findViewById(R.id.checkbox);
        }
    }
    private final String[] COLORS = {"#64B5F6", "#F44336"};
    private ArrayList<Todo> mTodos;

    public Adapter()
    {
        this.mTodos = new ArrayList<>();
    }

    public void addItem(Todo message)
    {
        this.mTodos.add(message);
        notifyItemInserted(getItemCount());
    }

    @Override
    public int getItemCount() {
        return mTodos.size();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        CardView cView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.todolist_item,
                parent, false);
        cView.setCardBackgroundColor(Color.parseColor(COLORS[viewType]));
        ViewHolder hView = new ViewHolder(cView);
        return hView;
    }

    @Override
    public int getItemViewType(int position) {
        return position % 2;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final Todo currentTodo = mTodos.get(position);

        holder.todoTextView.setText(currentTodo.getmTodo());
        holder.dueToDateTextView.setText(currentTodo.getDueToDate());
        holder.dueToHourTextView.setText(currentTodo.getDueToHour());
        holder.addedOnTextView.setText(currentTodo.getAddedStr());
        holder.checkBox.setChecked(currentTodo.isChecked());
        final int myPos = holder.getAdapterPosition();
        holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                currentTodo.setChecked();
                buttonView.setEnabled(false);
                mTodos.add(mTodos.remove(myPos));
                notifyDataSetChanged();
            }
        });
    }

I know this is not the correct way of doing this, and currently I'm getting the next exception:

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling

I know the OnCheckedStateChanged method should be defined in the OnCreateViewHolder method, but there I don't have the position of the current item to move to the end of the list.

Can anyone help me with that task?

dor132
  • 183
  • 1
  • 1
  • 8

1 Answers1

0

You should move your logic in viewHolder :

private class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder>{
    protected class ViewHolder extends RecyclerView.ViewHolder
    {
        TextView todoTextView;
        TextView addedOnTextView;
        TextView dueToDateTextView;
        TextView dueToHourTextView;
        CheckBox checkBox;
        protected ViewHolder(CardView cv)
        {
            super(cv);
            this.todoTextView = (TextView) cv.findViewById(R.id.todo_text);
            this.addedOnTextView = (TextView) cv.findViewById(R.id.added_on);
            this.dueToDateTextView = (TextView) cv.findViewById(R.id.due_to_date);
            this.dueToHourTextView = (TextView) cv.findViewById(R.id.due_to_hour);
            this.checkBox = (CheckBox)cv.findViewById(R.id.checkbox);
            this.checkBox.setOnCheckChangeListener(this);
        }

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Todo currentTodo = mTodos.get(getAdapterPosition());
            if(!onBind) {
                currentTodo.setChecked();
                buttonView.setEnabled(false);
                mTodos.add(mTodos.remove(getAdapterPosition()));
                notifyDataSetChanged();
            }
         }
    }
    private final String[] COLORS = {"#64B5F6", "#F44336"};
    private ArrayList<Todo> mTodos;
    public Adapter()
    {
        this.mTodos = new ArrayList<>();
    }
    public void addItem(Todo message)
    {
        this.mTodos.add(message);
        notifyItemInserted(getItemCount());
    }
    @Override
    public int getItemCount() {
        return mTodos.size();
    }
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        CardView cView = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.todolist_item,
                parent, false);
        cView.setCardBackgroundColor(Color.parseColor(COLORS[viewType]));
        ViewHolder hView = new ViewHolder(cView);
        return hView;
    }
    @Override
    public int getItemViewType(int position) {
        return position % 2;
    }
    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final Todo currentTodo = mTodos.get(position);
        holder.todoTextView.setText(currentTodo.getmTodo());
        holder.dueToDateTextView.setText(currentTodo.getDueToDate());
        holder.dueToHourTextView.setText(currentTodo.getDueToHour());
        holder.addedOnTextView.setText(currentTodo.getAddedStr());
        holder.checkBox.setChecked(currentTodo.isChecked());

    }

I can't try for now , let me know if is helping you.

Sorry for my english.

Cochi
  • 2,199
  • 2
  • 12
  • 15