How can a fuzzy search be implemented in an Android ListView?

To achieve a fuzzy search in ListView, you need to use an adapter to manage the data and dynamically filter the data based on the input query condition.

Here is a simple example of implementing a fuzzy search:

  1. Set up a ListView and an EditText for inputting search criteria.
  2. Create a data list to store all the data.
  3. Create an adapter (which inherits from BaseAdapter) to bind data to a ListView.
  4. In the getFilter() method of the adapter, create a Filter object to perform filtering operations.
  5. The performFiltering(CharSequence constraint) method in the Filter object is used to filter data based on the input query.
  6. In the publishResults method of the Filter object, update the data in the adapter and call the notifyDataSetChanged() method to refresh the ListView.

Here is a simple example code:

public class MainActivity extends AppCompatActivity {

    private ListView listView;
    private EditText editText;
    private CustomAdapter adapter;

    private List<String> dataList;
    private List<String> filteredDataList;

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

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

        // 初始化数据列表
        dataList = new ArrayList<>();
        dataList.add("Apple");
        dataList.add("Banana");
        dataList.add("Cherry");
        dataList.add("Grape");
        dataList.add("Lemon");
        dataList.add("Orange");
        dataList.add("Peach");
        dataList.add("Strawberry");
        dataList.add("Watermelon");

        filteredDataList = new ArrayList<>();
        filteredDataList.addAll(dataList);

        // 创建适配器并绑定数据
        adapter = new CustomAdapter();
        listView.setAdapter(adapter);

        editText.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) {
                // 根据输入的查询条件进行过滤
                adapter.getFilter().filter(s);
            }

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

    private class CustomAdapter extends BaseAdapter implements Filterable {

        private Filter filter;

        @Override
        public int getCount() {
            return filteredDataList.size();
        }

        @Override
        public Object getItem(int position) {
            return filteredDataList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(MainActivity.this).inflate(android.R.layout.simple_list_item_1, parent, false);
            }

            TextView textView = convertView.findViewById(android.R.id.text1);
            textView.setText(filteredDataList.get(position));

            return convertView;
        }

        @Override
        public Filter getFilter() {
            if (filter == null) {
                filter = new Filter() {
                    @Override
                    protected FilterResults performFiltering(CharSequence constraint) {
                        FilterResults results = new FilterResults();
                        List<String> filteredList = new ArrayList<>();

                        if (TextUtils.isEmpty(constraint)) {
                            filteredList.addAll(dataList);
                        } else {
                            String filterPattern = constraint.toString().toLowerCase().trim();

                            for (String item : dataList) {
                                if (item.toLowerCase().contains(filterPattern)) {
                                    filteredList.add(item);
                                }
                            }
                        }

                        results.values = filteredList;
                        results.count = filteredList.size();

                        return results;
                    }

                    @Override
                    protected void publishResults(CharSequence constraint, FilterResults results) {
                        filteredDataList.clear();
                        filteredDataList.addAll((List<String>) results.values);
                        notifyDataSetChanged();
                    }
                };
            }

            return filter;
        }
    }
}

In the mentioned code, every time the user inputs a search query, the onTextChanged() method of EditText is triggered. Subsequently, the filtering operation is executed by calling the adapter’s getFilter().filter(s) method. The filtered results are then updated in the adapter’s filteredDataList and the notifyDataSetChanged() method is called to refresh the ListView.

bannerAds