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

如何使用SearchView按字符而非精确词语过滤ListView?

嘿,这个需求其实很好实现,核心就是给你的ListView做一个支持模糊匹配、不区分大小写的自定义过滤器就行,我给你一步步讲清楚怎么做:

核心思路

默认的适配器过滤器一般是精确匹配或者前缀匹配,咱们要自己写一个过滤器,遍历原始数据,判断每个条目是否包含输入的关键词(同时忽略大小写),把符合条件的结果返回给ListView。

完整代码实现

1. 自定义适配器(带模糊过滤器)

咱们基于ArrayAdapter扩展一个带自定义过滤逻辑的适配器,这样最省心:

import android.content.Context;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import java.util.ArrayList;
import java.util.List;

public class FuzzySearchAdapter extends ArrayAdapter<String> {
    // 保存原始完整数据,避免过滤时丢失
    private final List<String> originalData;
    // 保存过滤后的结果数据
    private List<String> filteredData;

    public FuzzySearchAdapter(Context context, List<String> data) {
        super(context, android.R.layout.simple_list_item_1, data);
        this.originalData = new ArrayList<>(data);
        this.filteredData = new ArrayList<>(data);
    }

    // 重写getFilter,返回咱们自定义的过滤器
    @Override
    public Filter getFilter() {
        return new Filter() {
            // 这个方法在后台线程执行,不要操作UI
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                List<String> tempResults = new ArrayList<>();

                // 如果没有输入关键词,直接返回全部数据
                if (constraint == null || constraint.length() == 0) {
                    tempResults.addAll(originalData);
                } else {
                    // 把关键词转成小写,统一匹配规则
                    String searchQuery = constraint.toString().toLowerCase().trim();
                    // 遍历原始数据,检查每个条目是否包含关键词(同样转小写)
                    for (String item : originalData) {
                        if (item.toLowerCase().contains(searchQuery)) {
                            tempResults.add(item);
                        }
                    }
                }

                results.values = tempResults;
                results.count = tempResults.size();
                return results;
            }

            // 这个方法在主线程执行,更新UI数据
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                filteredData.clear();
                filteredData.addAll((List<String>) results.values);
                // 通知ListView数据更新
                notifyDataSetChanged();
            }
        };
    }
}

2. 在Activity中关联SearchView和ListView

接下来在你的Activity里初始化数据、View和适配器,再给SearchView设置监听:

import android.os.Bundle;
import android.widget.ListView;
import android.widget.SearchView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;

public class SearchActivity extends AppCompatActivity {

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

        // 1. 初始化你的数据源
        List<String> nameList = new ArrayList<>();
        nameList.add("mitesh");
        nameList.add("vidhi");
        nameList.add("ravi");
        nameList.add("Ravi P");
        nameList.add("Tushar prajapati");

        // 2. 绑定View
        SearchView searchView = findViewById(R.id.search_view);
        ListView listView = findViewById(R.id.list_view);

        // 3. 设置自定义适配器
        FuzzySearchAdapter adapter = new FuzzySearchAdapter(this, nameList);
        listView.setAdapter(adapter);

        // 4. 给SearchView设置查询监听,实时过滤
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // 提交搜索时触发
                adapter.getFilter().filter(query);
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // 输入内容变化时实时过滤
                adapter.getFilter().filter(newText);
                return false;
            }
        });

        // 可选:设置SearchView的提示文字
        searchView.setQueryHint("输入关键词搜索...");
    }
}
额外说明
  • 如果你的ListView展示的是自定义对象(不是String),只需要修改performFiltering里的判断逻辑就行,比如:if (user.getName().toLowerCase().contains(searchQuery))
  • 为什么要保存originalData?因为每次过滤都需要从原始完整数据里筛选,避免过滤后的数据被二次过滤导致数据丢失
  • 性能方面:如果你的数据集特别大(比如几千条以上),可以考虑用更高效的匹配算法,或者用异步任务优化,但一般中小数据集这个方案完全够用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:46:19