RecyclerView 基于复选框将项目移动到末尾

RecyclerView move items to end based on checkbox

也许这是一个简单的问题,但我还没有找到解决方案。

我有一个 RecyclerViewCardView 作为元素,每个 CardView 里面都有一个 CheckBox 视图。

我的目的是制作一个待办事项列表,当用户选中复选框时, 选中的项目将移动到列表的末尾。

目前我的适配器是:

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

我知道这不是正确的做法,目前我正在 下一个例外:

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

我知道OnCheckedStateChanged方法应该定义在OnCreateViewHolder方法中,但是那里我没有当前的位置 要移动到列表末尾的项目。

谁能帮我完成这个任务?

你应该在 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());

    }

暂时无法尝试,如果对您有帮助,请告诉我。

对不起我的英语。