You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除Firestore数据后ListView无法刷新的问题求助

问题:ListView删除Firestore数据后无法刷新界面

我在NotesLVAdapter中添加了OnLongClickListener,长按ListView列表项会弹出菜单,点击删除选项可将对应项从Firestore数据库移除,但删除后ListView不会刷新,该项依然停留在界面上。使用notifyDataSetChanged()添加新项时有效,但删除操作时完全没效果。


相关代码

ListView所在Activity代码

private ArrayList<String> notes = new ArrayList<String>();
private ArrayAdapter<String> arrayAdapter;

private ListView listView;
private FirebaseFirestore db;
private static final String TAG="ALMA";
private ArrayList<Notes> allNotes;

private ArrayList<Notes> noNotes= new ArrayList<>();
private String mail;
private FloatingActionButton floatingbtn;

private NotesLVAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notes_lv);

    listView = (ListView) findViewById(R.id.listView);

    floatingbtn = (FloatingActionButton) findViewById(R.id.floatingActionButton);
    floatingbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(NotesLV.this, CreateNote.class);
            startActivity(intent);
        }
    });


    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    mail = user.getEmail().toString();

    allNotes = new ArrayList<>();
    db = FirebaseFirestore.getInstance();
    adapter = new NotesLVAdapter(NotesLV.this, allNotes);
    listView.setAdapter(adapter);
}


public void loadNotesToListView(){
    allNotes.clear();
    adapter.notifyDataSetChanged();
    Log.d(TAG,"loading");
    db.collection("Folder").document(mail).collection("Notes").orderBy("date",Query.Direction.DESCENDING).get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
            if (!queryDocumentSnapshots.isEmpty())
            {
                List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments();
                Log.d(TAG, "List size: " + list.size());
                for (DocumentSnapshot d : list) {
                    Notes notes = d.toObject(Notes.class);
                    d.getId();
                    allNotes.add(notes);
                    Log.d(TAG, "added");
                }
                adapter = new NotesLVAdapter(NotesLV.this, allNotes);
                listView.setAdapter(adapter);
                Log.d(TAG, "adapter was set");

            }
            else
            {
                Log.d(TAG,"No data found in query");
                Toast.makeText(NotesLV.this, "No data found in Database", Toast.LENGTH_SHORT).show();
            }
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(NotesLV.this, "Fail to load data..", Toast.LENGTH_SHORT).show();
        }
    });

}
@Override
protected void onResume() {
    super.onResume();
    adapter.notifyDataSetChanged();
    loadNotesToListView();
}

Adapter代码

private FirebaseFirestore db;
private String mail;

public NotesLVAdapter(Context context, ArrayList<Notes> notes) {
    super(context, 0, notes);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View listItemView = convertView;

    if (listItemView==null) {
        listItemView = LayoutInflater.from(getContext()).inflate(R.layout.activity_notes_d,parent, false);
    }

    Notes notes = getItem(position);
    db= FirebaseFirestore.getInstance();
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    mail= user.getEmail().toString();
    TextView tvNTitle = (TextView) listItemView.findViewById(R.id.tvNoteName);
    tvNTitle.setText(notes.getNoteName());
    TextView tvNDate = (TextView) listItemView.findViewById(R.id.tvDate);
    tvNDate.setText(notes.getSavedDate());
    ImageView imageBoss=(ImageView)listItemView.findViewById(R.id.imgBoss);
    String pic="";
    
    listItemView.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view) {
            Log.d("ALMA","clicked");
            Intent intent = new Intent(view.getContext(), CreateNote.class);
            intent.putExtra("title",tvNTitle.getText().toString());
            intent.putExtra("content",notes.getContent().toString());
            intent.putExtra("reminder",notes.needReminder());
            intent.putExtra("saved date",notes.getSavedDate().toString());
            intent.putExtra("date",notes.getDate().toString());
            view.getContext().startActivity(intent);
        }
    });

    listItemView.setOnLongClickListener(new AdapterView.OnLongClickListener() {
        @Override
        public boolean onLongClick(View view) {
            PopupMenu popupMenu=new PopupMenu(view.getContext(), view);
            popupMenu.setGravity(Gravity.END);
            popupMenu.getMenuInflater().inflate(R.menu.notes_popup_menu,popupMenu.getMenu());
            popupMenu.show();
            popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){

                @Override
                public boolean onMenuItemClick(MenuItem menuItem) {
                    int id=menuItem.getItemId();

                    if(id==R.id.menu_edit) {
                        Intent intent = new Intent(view.getContext(), CreateNote.class);
                        intent.putExtra("title",tvNTitle.getText().toString());
                        intent.putExtra("content",notes.getContent().toString());
                        intent.putExtra("reminder",notes.needReminder());
                        intent.putExtra("date",notes.getDate().toString());
                        view.getContext().startActivity(intent);
                    }
                    if(id==R.id.menu_delete){
                        db.collection("Folder").document(mail).collection("Notes").document(notes.getNoteName()+", "+notes.getSavedDate()).delete()
                                .addOnCompleteListener(new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        if (task.isSuccessful()) {
                                            Log.d("ALMA","deleted");
                                        } else {
                                            Log.d("ALMA","didnt delete");
                                        }
                                    }
                                });
                    }
                    return true;
                }
            });
            return true;
        }
    });

    return listItemView;
}

问题原因及解决方案

1. 核心问题

删除Firestore数据后,仅修改了云端数据,但本地数据源allNotes未移除对应项,也未调用notifyDataSetChanged()通知Adapter更新界面;同时loadNotesToListView方法每次都会重新创建Adapter实例,导致原Adapter引用失效。

2. 修复步骤

步骤1:在Adapter删除回调中更新本地数据源并通知刷新

修改Adapter中删除逻辑,在云端删除成功后,移除本地数据源的对应项并通知Adapter:

if(id==R.id.menu_delete){
    db.collection("Folder").document(mail).collection("Notes").document(notes.getNoteName()+", "+notes.getSavedDate()).delete()
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    Log.d("ALMA","deleted");
                    // 移除本地数据源中的当前项
                    remove(notes);
                    // 通知Adapter刷新界面
                    notifyDataSetChanged();
                } else {
                    Log.d("ALMA","didnt delete");
                }
            }
        });
}

步骤2:优化loadNotesToListView的Adapter复用逻辑

不再每次创建新Adapter,复用已初始化的Adapter实例,仅更新数据源后通知刷新:

public void loadNotesToListView(){
    allNotes.clear();
    Log.d(TAG,"loading");
    db.collection("Folder").document(mail).collection("Notes").orderBy("date",Query.Direction.DESCENDING).get()
        .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
            @Override
            public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                if (!queryDocumentSnapshots.isEmpty())
                {
                    List<DocumentSnapshot> list = queryDocumentSnapshots.getDocuments();
                    Log.d(TAG, "List size: " + list.size());
                    for (DocumentSnapshot d : list) {
                        Notes notes = d.toObject(Notes.class);
                        allNotes.add(notes);
                        Log.d(TAG, "added");
                    }
                    // 复用现有Adapter,直接通知刷新
                    adapter.notifyDataSetChanged();
                    Log.d(TAG, "data refreshed");

                }
                else
                {
                    Log.d(TAG,"No data found in query");
                    Toast.makeText(NotesLV.this, "No data found in Database", Toast.LENGTH_SHORT).show();
                    adapter.notifyDataSetChanged(); // 空数据时也要通知刷新
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Toast.makeText(NotesLV.this, "Fail to load data..", Toast.LENGTH_SHORT).show();
            }
        });

}

步骤3:调整onResume中的重复刷新逻辑

移除重复的loadNotesToListView调用,避免界面频繁闪烁:

@Override
protected void onResume() {
    super.onResume();
    // 仅通知Adapter刷新即可,无需每次重新拉取数据
    adapter.notifyDataSetChanged();
}

可选优化:使用Firestore实时监听

如果需要界面实时同步云端数据,可使用addSnapshotListener替代get(),数据变化时自动更新界面:

// 在Activity的onCreate中添加实时监听
db.collection("Folder").document(mail).collection("Notes").orderBy("date",Query.Direction.DESCENDING)
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
            if (error != null) {
                Log.w(TAG, "Listen failed.", error);
                return;
            }
            allNotes.clear();
            for (DocumentSnapshot doc : value) {
                Notes notes = doc.toObject(Notes.class);
                allNotes.add(notes);
            }
            adapter.notifyDataSetChanged();
        }
    });

内容的提问来源于stack exchange,提问作者Alma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:47:08