从RecyclerView中删除后,如何解决项目重复问题?

时间:2019-08-27 20:39:26

标签: java android android-recyclerview

我当前正在开发一个应用程序,并且我正在使用RecyclerView适配器,在使用侦听器的适配器中,按钮可以在每个回收站项目中使用。现在,我可以选择删除回收站项目,如果该项目是RecyclerView中的最后一个项目,那么一切都很好。但是,如果它在开头或中间,则会被其旁边的项目替换,并且该项目重复。

现在这是活动的代码

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
mDbAdapter = new NotesDbAdapter(this);
mDbAdapter.open();
listNotes = mDbAdapter.getResults();
mNotesAdapter = new NotesAdapter(this, mDbAdapter.fetchAllNotes(),listNotes);
mNotesAdapter.notifyDataSetChanged();
mRecyclerView = findViewById(R.id.listView_notes);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(mNotesAdapter);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

这是适配器代码:

构造函数:

public NotesAdapter(Context ctx, Cursor cursor, ArrayList<Note> listNotes){
    this.mCtx = ctx;
    this.mCursor = cursor;
    this.mListNotes = listNotes;
}

还有onBindViewHolder

//BIND DATA TO VIEWS
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    if (!mCursor.moveToPosition(position)) {
        return;
    }

    String noteT = mCursor.getString(mCursor.getColumnIndex(NotesDbAdapter.COL_TITLE));
    String noteC = mCursor.getString(mCursor.getColumnIndex(NotesDbAdapter.COL_CONTENT));
    holder.noteTitle.setText(noteT);
    holder.noteDescription.setText(noteC);
    holder.noteCard_settingsButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mDbAdapter = new NotesDbAdapter(mCtx);
            mDbAdapter.open();
            Toast.makeText(mCtx,"The position is:"+holder.getAdapterPosition(),Toast.LENGTH_SHORT).show();
            PopupMenu popup = new PopupMenu(mCtx, view);
            MenuInflater inflater = popup.getMenuInflater();
            inflater.inflate(R.menu.menu_popup, popup.getMenu());
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.popup_edit:
                            Toast.makeText(mCtx,"You pressed edit note", Toast.LENGTH_SHORT).show();
                            return true;
                        case R.id.popup_delete:
                            deleteItem(holder.getAdapterPosition());
                            Toast.makeText(mCtx, "Delete note", Toast.LENGTH_SHORT).show();
                            return true;
                    }
                    return false;
                }
            });
            popup.show();
        }
    });
}

其他功能如下。

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

@Override
public long getItemId(int position) {
    return position;
}

private void deleteItem(int position) {
    mDbAdapter.deleteNoteById(mListNotes.get(position).getId());
    mListNotes.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeRemoved(position, 1);
}

public class ViewHolder extends RecyclerView.ViewHolder{
    TextView noteTitle;
    TextView noteDescription;
    CardView cardView;
    Button noteCard_settingsButton;

    public ViewHolder(View view) {
        super(view);
        noteTitle = view.findViewById(R.id.note_titleView);
        noteDescription = view.findViewById(R.id.note_contentView);
        cardView = view.findViewById(R.id.notes_cardView);
        noteCard_settingsButton = view.findViewById(R.id.note_card_settings_button);
    }
}

因此,我希望便笺将被完全移除,之后的便笺应向下移动。

3 个答案:

答案 0 :(得分:1)

似乎您没有更新mCursor函数中使用的onBindViewHolder。尽管您正在更新mListNotes,但仍在游标中填充RecyclerView的每个项目中的数据,并且从列表中删除项目时游标没有被更新。

我宁愿建议从您的ArrayList(即mListNotes)而不是onBindViewHolder中的光标获取数据。如下所示修改构造函数。

// Remove the mCursor completely.
// Looks like you do not need that. 
public NotesAdapter(Context ctx, ArrayList<Note> listNotes){
    this.mCtx = ctx;
    this.mListNotes = listNotes;
} 

然后在您的onBindViewHolder中提取mListNotes中的数据。

@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    String noteT = mListNotes.get(position).getTitle();
    String noteC = mListNotes.get(position).getContent();

    holder.noteTitle.setText(noteT);
    holder.noteDescription.setText(noteC);
    holder.noteCard_settingsButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mDbAdapter = new NotesDbAdapter(mCtx);
            mDbAdapter.open();
            Toast.makeText(mCtx,"The position is:"+holder.getAdapterPosition(),Toast.LENGTH_SHORT).show();
            PopupMenu popup = new PopupMenu(mCtx, view);
            MenuInflater inflater = popup.getMenuInflater();
            inflater.inflate(R.menu.menu_popup, popup.getMenu());
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.popup_edit:
                            Toast.makeText(mCtx,"You pressed edit note", Toast.LENGTH_SHORT).show();
                            return true;
                        case R.id.popup_delete:
                            deleteItem(holder.getAdapterPosition());
                            Toast.makeText(mCtx, "Delete note", Toast.LENGTH_SHORT).show();
                            return true;
                    }
                    return false;
                }
            });
            popup.show();
        }
    });
}

我希望能解决您的问题。

如果要将光标保留在适配器中,请确保传递给适配器的光标也已更新。

答案 1 :(得分:0)

可能是由于

notifyItemRemoved(position);
notifyItemRangeRemoved(position, 1);

您只需要拨打电话notifyItemRemoved(position);

答案 2 :(得分:0)

尝试以下代码:

private void deleteItem(int position) {
    mDbAdapter.deleteNoteById(mListNotes.get(position).getId());
    mListNotes.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(0, mListNotes.size()); //change here
}