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

Android聊天应用SearchView无法过滤用户问题求助

问题

我在Android Studio开发的聊天应用里有一个展示所有注册用户的Fragment,想添加SearchView功能,根据输入的部分/完整名称、邮箱过滤用户,但无论输入什么查询内容,始终显示所有用户,且无运行时错误。

相关代码

菜单创建代码

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){

    inflater.inflate(R.menu.menu_main, menu);

    MenuItem item = menu.findItem(R.id.action_search);

    SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {


            if (!TextUtils.isEmpty(query.trim())){
                searchUsers(query);
            }
            else {
                getAllUsers();
            }
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {

            if (!TextUtils.isEmpty(query.trim())){
                searchUsers(query);
            }
            else {
                getAllUsers();
            }
            return false;
        }
    });

    super.onCreateOptionsMenu(menu, inflater);
}

搜索用户代码

private void searchUsers(String query) {

    final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");

    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            usersList.clear();
            for (DataSnapshot dataSnapshot: snapshot.getChildren()){
                ModelUsers modelUsers = dataSnapshot.getValue(ModelUsers.class);

                if (!modelUsers.getUid().equals(firebaseUser.getUid())){

                    if ((modelUsers.getName().toLowerCase()).contains(query.toLowerCase()) ||
                            (modelUsers.getEmail().toLowerCase()).contains(query.toLowerCase()))
                    {
                        usersList.add(modelUsers);

                    } else {

                    }


                }

                adapterUsers = new AdapterUsers(getActivity(), usersList);

                adapterUsers.notifyDataSetChanged();

                recyclerView.setAdapter(adapterUsers);
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    });

}
修复方案

问题出在两个核心点:

  1. 重复注册持续监听器:每次调用searchUsers都用addValueEventListener,会新增一个永久监听数据变化的监听器,旧监听器不会自动移除,导致后续数据更新时覆盖过滤后的列表。应该改用addListenerForSingleValueEvent,仅读取一次数据完成过滤。
  2. Adapter更新时机错误:在遍历用户的循环内部创建并设置Adapter,会导致每遍历一个用户就更新一次列表,最终过滤逻辑被多次更新的操作打乱。必须把Adapter的初始化和设置放在循环结束后。

修复后的searchUsers代码:

private void searchUsers(String query) {

    final FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");

    // 改用单次数据读取监听器,避免重复监听
    ref.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            usersList.clear();
            String lowerQuery = query.toLowerCase(); // 提前转小写,避免重复计算
            for (DataSnapshot dataSnapshot: snapshot.getChildren()){
                ModelUsers modelUsers = dataSnapshot.getValue(ModelUsers.class);

                // 增加判空,防止空指针
                if (modelUsers != null && !modelUsers.getUid().equals(firebaseUser.getUid())){
                    if (modelUsers.getName().toLowerCase().contains(lowerQuery) ||
                            modelUsers.getEmail().toLowerCase().contains(lowerQuery))
                    {
                        usersList.add(modelUsers);
                    }
                }
            }
            // 循环结束后统一更新Adapter
            adapterUsers = new AdapterUsers(getActivity(), usersList);
            recyclerView.setAdapter(adapterUsers);
            // 若Adapter已初始化,也可直接调用notifyDataSetChanged,无需重复新建
            // adapterUsers.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // 可添加错误提示,比如Toast.makeText(getActivity(), "加载失败", Toast.LENGTH_SHORT).show();
        }
    });
}

额外优化建议:

  • 如果getAllUsers方法也使用了addValueEventListener,同样要改成addListenerForSingleValueEvent
  • 可以复用已创建的Adapter,避免每次搜索都新建实例,提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 18:35:15