带有上下文操作模式的RecyclerView可以删除项目问题

时间:2016-10-16 14:31:14

标签: android android-recyclerview

我已在我的应用中实施了此教程https://www.youtube.com/watch?v=F8eQ_3pmT6Y以删除recylerview项目。  当我长按某个项目时,工具栏上会出现删除图标,每行都会显示一个复选框以选择要删除的项目。但问题是,当我检查第一个复选框时,也会选中第十个复选框,复选框2选中第11个复选框,依此类推。 有没有人知道它为什么会发生。这是我的适配器和活动代码对不起,如果它是长的

public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.contentViewHolder> {
    ArrayList<Heyvon> heyvons = new ArrayList<>();
    MainActivity mainActivity;
    Context context;

    public ContentAdapter(Context context, ArrayList<Heyvon> heyvons) {
        this.context = context;
        this.heyvons = heyvons;
        mainActivity = (MainActivity) context;
    }

    @Override
    public contentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view, parent, false);
        contentViewHolder contentViewHolder = new contentViewHolder(view, mainActivity);

        return contentViewHolder;
    }

    @Override
    public void onBindViewHolder(contentViewHolder holder, int position) {
        holder.imageView.setImageResource(heyvons.get(position).getPics());
        holder.name.setText(heyvons.get(position).getName());
        holder.ghaza.setText(heyvons.get(position).getGhaza());
        if (!mainActivity.isInActionMode) {
            holder.checkBox.setVisibility(View.GONE);
        } else {
            holder.checkBox.setVisibility(View.VISIBLE);
        }
    }

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

    public void updateAdapter(ArrayList<Heyvon> list) {
        for (Heyvon heyvon : list) {
            heyvons.remove(heyvon);
        }
        notifyDataSetChanged();
    }

    public static class contentViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        ImageView imageView;
        TextView name, ghaza;
        CheckBox checkBox;
        MainActivity mainActivity;
        CardView cardView;

        public contentViewHolder(View itemview, MainActivity mainActivity) {
            super(itemview);
            imageView = (ImageView) itemview.findViewById(R.id.imageView);
            name = (TextView) itemview.findViewById(R.id.tv_names_card);
            ghaza = (TextView) itemview.findViewById(R.id.tv_ghaza_card);
            checkBox = (CheckBox) itemview.findViewById(R.id.checkBox);
            this.mainActivity = mainActivity;
            cardView = (CardView) itemview.findViewById(R.id.cardview);
            cardView.setOnLongClickListener(mainActivity);
            checkBox.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            mainActivity.prepareSelection(view, getAdapterPosition());
        }
    }
}

活动中的代码

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_activity_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.item_delete) {
        isInActionMode = false;
        ContentAdapter contentAdapter = (ContentAdapter) adapter;
        contentAdapter.updateAdapter(selectedlist);
        ClearActionMode();
    } else if (item.getItemId() == android.R.id.home) {
        ClearActionMode();
        adapter.notifyDataSetChanged();
    }
    return true;
}

public void ClearActionMode() {
    isInActionMode = false;
    toolbar.getMenu().clear();
    toolbar.inflateMenu(R.menu.menu_activity_main);
    getSupportActionBar().setDisplayHomeAsUpEnabled(false);
    counter_text_veiw.setVisibility(View.GONE);
    counter_text_veiw.setText("0 item is selected");
    counter = 0;
    selectedlist.clear();
}

@Override
public boolean onLongClick(View view) {
    toolbar.getMenu().clear();
    toolbar.inflateMenu(R.menu.menu_action_mod);
    counter_text_veiw.setVisibility(View.VISIBLE);
    isInActionMode = true;
    adapter.notifyDataSetChanged();
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    return false;
}

public void prepareSelection(View view, int position) {
    if (((CheckBox) view).isChecked()) {
        selectedlist.add(heyvons.get(position));
        counter = counter + 1;
        updateCounter(counter);
    } else {
        selectedlist.remove(heyvons.get(position));
        counter = counter - 1;
        updateCounter(counter);
    }
}

public void updateCounter(int counter) {
    if (counter == 0) {
        counter_text_veiw.setText("0 item is selected");
    } else {
        counter_text_veiw.setText(counter + " item is selected");
    }
}

@Override
public void onBackPressed() {
    if (isInActionMode) {
        ClearActionMode();
        adapter.notifyDataSetChanged();
    } else {
        super.onBackPressed();
    }
}

1 个答案:

答案 0 :(得分:1)

您遇到的问题很可能是由于RecyclerView的回收:当您在列表中选择项目时,CheckBox会更新,但如果您滚动并且所选视图会被回收你会看到一个不同的(不需要的)被检查。在你的情况下,RecyclerView可能是一个Pool,它是9个元素大:第一个视图被循环显示也是第10个,依此类推。

这意味着选中复选框的视图将根据onBindViewHolder()填充列表中其他项目的数据,并显示在屏幕的另一侧,而不是创建新的。显然CheckBox仍被错误检查。

在某些滚动之后,以前选择的项目也可能未选中。

Adapter的{​​{1}}中,您需要根据项目是否实际被选中来重置onBindViewHolder()状态(每次{{1}内的视图都会调用此方法创建或回收):

CheckBox
RecyclerView

您不仅可以使用@Override public void onBindViewHolder(contentViewHolder holder, int position) { holder.imageView.setImageResource(heyvons.get(position).getPics()); holder.name.setText(heyvons.get(position).getName()); holder.ghaza.setText(heyvons.get(position).getGhaza()); if (!mainActivity.isInActionMode) { holder.checkBox.setVisibility(View.GONE); // Uncheck everything holder.checkBox.setChecked(false); } else { holder.checkBox.setVisibility(View.VISIBLE); // Has this item been selected? holder.checkBox.setChecked(mainActivity.isSelected(position)); } } MainActivity或数组跟踪所选对象,还可以跟踪其在Adapter中的位置:

List

prepareSelection应保留所选项目的位置:

Set

private List<Integer> selectedItemsPositions; 的定义如下:

public void prepareSelection(View view, int position) {
    if (((CheckBox) view).isChecked()) {
        selectedlist.add(heyvons.get(position));
        selectedItemsPositions.add(position); // Keep track of the position
        counter = counter + 1;
        updateCounter(counter);
    } else {
        selectedlist.remove(heyvons.get(position));
        selectedItemsPositions.remove(position);
        counter = counter - 1;
        updateCounter(counter);
    }
}