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

RecyclerView搜索功能异常:输入后列表消失的解决方法

解决RecyclerView搜索过滤条目消失的问题

我帮你排查了代码里的几个关键问题,这就是输入内容时RecyclerView条目消失、无法得到过滤结果的核心原因:


1. 搜索过滤的循环逻辑完全错误

你在onTextChanged里创建了空的filter集合,然后循环filter.size()——这时候filter是空的,循环根本不会执行,所以filter一直是空列表,RecyclerView自然显示空内容!应该遍历原始数据集合current,而不是刚创建的空filter。

2. 嵌套Volley请求的数据填充时机&变量错误

你在外部请求里把c添加到current后,嵌套的请求才异步返回设置name,这会导致初始列表的数据不完整;而且代码里c.setName(name);的name变量未定义,应该是获取到的foodie_name。

3. 不必要的重复设置LayoutManager

每次输入文本都重新设置LinearLayoutManager完全没必要,应该在Fragment初始化时设置一次即可。


修改后的代码示例

首先修正搜索监听的逻辑:

private void addTextListener() {
    search.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            String searchText = s.toString().toLowerCase().trim();
            ArrayList<CurrentEntry> filterList = new ArrayList<>();
            
            // 遍历原始数据集合current,而不是空的filter!
            for (CurrentEntry entry : current) {
                // 这里根据你实际要匹配的字段调整,比如entry的name属性
                String entryText = entry.getName().toLowerCase();
                if (entryText.contains(searchText)) {
                    filterList.add(entry);
                }
            }
            
            // 直接更新adapter数据,无需重复设置LayoutManager
            if (adapt != null) {
                adapt.setFilteredList(filterList); // 推荐用adapter内部过滤方法
            } else {
                adapt = new NewAdapter(filterList, getActivity());
                recyclerView.setAdapter(adapt);
            }
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
}

然后修正Volley数据请求的逻辑:

private void getData() {
    String json_req = "json_req";
    String url = getContext().getString(R.string.CURRENT_STATUS);
    JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, url, null, 
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONObject object = new JSONObject(response.toString());
                    JSONArray data = object.getJSONArray("results");
                    current.clear(); // 先清空旧数据,避免重复添加
                    
                    for (int i = 0; i < data.length(); i++) {
                        JSONObject json = data.getJSONObject(i);
                        final CurrentEntry c = new CurrentEntry();
                        
                        // 先设置已知字段
                        c.setPeople(json.getString("my_people"));
                        String temp = json.getString("my_timetime");
                        temp = temp.substring(11);
                        temp = temp.substring(0, temp.length() - 4);
                        c.setEstimate(temp);
                        
                        String userUrl = json.getString("name");
                        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, userUrl, null, 
                            new Response.Listener<JSONObject>() {
                                @Override
                                public void onResponse(JSONObject response) {
                                    try {
                                        String foodie_name = response.getString("username");
                                        c.setName(foodie_name); // 修正变量名错误
                                        adapt.notifyDataSetChanged(); // 单个条目更新后通知adapter
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }, 
                            new Response.ErrorListener() {
                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    error.printStackTrace(); // 打印错误方便调试
                                }
                            }) {
                                @Override
                                public Map<String, String> getHeaders() throws AuthFailureError {
                                    Map<String, String> headers = new HashMap<>();
                                    String credentials = "your_username:your_password"; // 替换为实际凭证
                                    String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
                                    headers.put("Content-type", "application/json");
                                    headers.put("Authorization", auth);
                                    return headers;
                                }
                            };
                        AppController.getInstance().addToRequestQueue(request, "second_req_" + i); // 给每个请求唯一tag
                        
                        current.add(c);
                    }
                    
                    // 初始化adapter
                    adapt = new NewAdapter(current, getActivity());
                    recyclerView.setAdapter(adapt);
                    
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, 
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> headers = new HashMap<>();
                String credentials = "your_username:your_password"; // 替换为实际凭证
                String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
                headers.put("Content-type", "application/json");
                headers.put("Authorization", auth);
                return headers;
            }
        };
    AppController.getInstance().addToRequestQueue(req, json_req);
}

额外优化:给Adapter添加内部过滤方法

让NewAdapter支持直接更新过滤后的列表,避免重复创建adapter:

public class NewAdapter extends RecyclerView.Adapter<NewAdapter.ViewHolder> {
    private List<CurrentEntry> mList;
    private Context mContext;

    public NewAdapter(List<CurrentEntry> list, Context context) {
        this.mList = list;
        this.mContext = context;
    }

    // 添加过滤更新方法
    public void setFilteredList(List<CurrentEntry> filteredList) {
        this.mList = filteredList;
        notifyDataSetChanged();
    }

    // 其他ViewHolder、onCreateViewHolder、onBindViewHolder等方法...
}

初始化时设置LayoutManager

在Fragment的onViewCreated里提前设置一次即可:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    recyclerView = view.findViewById(R.id.your_recycler_view_id);
    // 只设置一次LayoutManager
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    current = new ArrayList<>();
    getData();
    addTextListener();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:06:52