从回收器视图中删除时如何修复项目的重复?



我目前正在开发一个应用程序,我正在使用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);
}
}

因此,我希望将注释完全删除,并将其之后的注释向下移动。

看起来您没有更新在onBindViewHolder函数中使用的mCursor。虽然您正在更新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();
}
});
}

我希望这可以解决您的问题。

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

尝试以下代码:

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

这可能是由

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

您只需要呼叫notifyItemRemoved(position);

最新更新