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

Android中Filter搜索无结果时显示提示文本的实现方案咨询

这其实很容易实现,核心就是根据过滤后的列表是否为空来切换提示文本的可见性,我给你一步步拆解:

实现步骤

首先,先在你的布局文件里添加那个无结果提示的TextView(默认隐藏,避免初始状态干扰):

<TextView
    android:id="@+id/no_result_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="No Results Found"
    android:visibility="gone"
    android:gravity="center"
    android:textSize="18sp"
    android:padding="16dp"/>

接下来,在你的Activity/Fragment里初始化必要的变量:

private TextView noResultFoundTextView;
private ArrayList<YourModel> originalDataList; // 存原始的完整数据,不要修改它
private ArrayList<YourModel> filteredDataList; // 存过滤后的结果
private YourAdapter yourAdapter;

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

    // 初始化原始数据(替换成你自己的数据源加载逻辑)
    originalDataList = loadYourOriginalData();
    filteredDataList = new ArrayList<>(originalDataList);

    // 初始化适配器并绑定到RecyclerView/ListView
    yourAdapter = new YourAdapter(filteredDataList);
    RecyclerView recyclerView = findViewById(R.id.your_recycler_view);
    recyclerView.setAdapter(yourAdapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    // 初始化无结果提示文本
    noResultFoundTextView = findViewById(R.id.no_result_text);
}

然后处理搜索菜单和SearchView的监听,完善你已有的代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.search_menu, menu);
    MenuItem searchItem = menu.findItem(R.id.search_menu);
    SearchView searchView = (SearchView) searchItem.getActionView();

    // 设置搜索文本变化的实时监听
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            applyFilter(query);
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            applyFilter(newText);
            return true;
        }
    });

    return super.onCreateOptionsMenu(menu);
}

接下来分两种场景实现过滤逻辑:

场景1:使用RecyclerView自定义Filter(推荐)

如果你的适配器是RecyclerView.Adapter,自定义Filter是更规范的做法:

public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
    private ArrayList<YourModel> filteredList;
    private ArrayList<YourModel> originalList;
    private TextView noResultTextView; // 传入无结果提示文本的引用

    // 构造方法,传入列表和提示文本
    public YourAdapter(ArrayList<YourModel> list, TextView noResultTextView) {
        this.filteredList = list;
        this.originalList = new ArrayList<>(list);
        this.noResultTextView = noResultTextView;
    }

    // ... 省略ViewHolder、onCreateViewHolder、onBindViewHolder等常规方法

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String searchQuery = constraint.toString().toLowerCase().trim();
                ArrayList<YourModel> tempList = new ArrayList<>();

                if (searchQuery.isEmpty()) {
                    // 搜索为空时显示全部数据
                    tempList.addAll(originalList);
                } else {
                    // 遍历原始列表,匹配符合条件的项
                    for (YourModel item : originalList) {
                        // 这里替换成你自己的匹配逻辑,比如匹配名称、描述等字段
                        if (item.getTitle().toLowerCase().contains(searchQuery)) {
                            tempList.add(item);
                        }
                    }
                }

                FilterResults results = new FilterResults();
                results.values = tempList;
                return results;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                filteredList.clear();
                filteredList.addAll((ArrayList<YourModel>) results.values);
                notifyDataSetChanged();

                // 核心逻辑:根据过滤后的列表是否为空切换提示文本的可见性
                noResultTextView.setVisibility(filteredList.isEmpty() ? View.VISIBLE : View.GONE);
            }
        };
    }

    // ViewHolder类
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // 初始化你的ViewHolder控件
        public ViewHolder(View itemView) {
            super(itemView);
        }
    }
}

注意:初始化适配器时要把提示文本传进去:

yourAdapter = new YourAdapter(filteredDataList, noResultFoundTextView);

然后在applyFilter方法里调用过滤:

private void applyFilter(String query) {
    yourAdapter.getFilter().filter(query);
}

场景2:直接在Activity里处理过滤(适合ListView或简单场景)

如果是用ListView或者不想自定义Filter,也可以直接在Activity里写过滤逻辑:

private void applyFilter(String query) {
    filteredDataList.clear();
    String lowerCaseQuery = query.toLowerCase().trim();

    if (lowerCaseQuery.isEmpty()) {
        filteredDataList.addAll(originalDataList);
    } else {
        for (YourModel item : originalDataList) {
            if (item.getTitle().toLowerCase().contains(lowerCaseQuery)) {
                filteredDataList.add(item);
            }
        }
    }

    yourAdapter.notifyDataSetChanged();

    // 控制提示文本的显示隐藏
    noResultFoundTextView.setVisibility(filteredDataList.isEmpty() ? View.VISIBLE : View.GONE);
}
关键注意点
  • 一定要保留原始完整数据列表,不要在过滤时修改它,否则清空搜索框时无法恢复全部数据
  • 匹配逻辑建议转成小写(或大写),避免大小写敏感的问题
  • 搜索框清空时,过滤后的列表会回到原始数据,此时提示文本会自动隐藏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:25:23