我当前正在开发一个应用程序,并且我正在使用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);
}
}
因此,我希望便笺将被完全移除,之后的便笺应向下移动。
答案 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
}