RecyclerView根据复选框将项目移至结束

时间:2017-03-15 22:41:37

标签: android checkbox android-recyclerview android-arrayadapter

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

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

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

目前我的适配器是:

    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方法,但是我没有当前的位置 要移动到列表末尾的项目。

任何人都可以帮我完成这项任务吗?

1 个答案:

答案 0 :(得分:0)

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

    }

我现在不能尝试,让我知道是否在帮助你。

抱歉我的英文。