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

使用自定义Adapter时SearchView仅显示ListView同一条记录,ArrayAdapter正常

Fixing Duplicate Records in SearchView with Custom ArrayAdapter

Hey there, let's sort out why your custom EMP_LEAVE_ADAPTER is showing duplicate records in the SearchView while the default ArrayAdapter works perfectly!

The Root Cause

The issue comes down to how your custom adapter interacts with ArrayAdapter's built-in filtering system. When you use a SearchView, ArrayAdapter relies on its internal dataset to handle filtering. But your adapter was maintaining its own itemname array that didn't sync with the filtered dataset managed by the parent class. This mismatch meant the adapter kept pulling data from your static array instead of the updated filtered list, leading to repeated entries.

Solution 1: Use the Parent Class's Dataset (Simplest Fix)

Remove your custom itemname array and use the parent ArrayAdapter's built-in methods to access data. This ensures you're always working with the correct filtered dataset.

Here's the revised adapter code:

import com.example.mis_internee.atendence_app_android.R;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class EMP_LEAVE_ADAPTER extends ArrayAdapter<String> {
    private final Activity context;

    public EMP_LEAVE_ADAPTER(Activity context, String[] itemname) {
        super(context, R.layout.mylist, itemname);
        this.context = context;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Reuse existing views to boost performance
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            rowView = inflater.inflate(R.layout.emp_leave_adpater_layout, parent, false);
        }

        TextView txtTitle = rowView.findViewById(R.id.item);
        ImageView image = rowView.findViewById(R.id.icon);

        // Use getItem() from the parent class to get filtered data
        txtTitle.setText(getItem(position));
        return rowView;
    }
}

Key changes:

  • Removed the custom itemname array
  • Added view reuse (avoids inflating new views every time, improves performance)
  • Used getItem(position) to fetch data directly from the parent's filtered dataset

Solution 2: Custom Filter Logic (If You Need Full Control)

If you need to maintain your own dataset for specific logic, you'll have to override the getFilter() method to handle filtering correctly. Here's how:

import com.example.mis_internee.atendence_app_android.R;
import android.app.Activity;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class EMP_LEAVE_ADAPTER extends ArrayAdapter<String> implements Filterable {
    private final Activity context;
    private final String[] originalItemNames;
    private List<String> filteredItemNames;

    public EMP_LEAVE_ADAPTER(Activity context, String[] itemname) {
        super(context, R.layout.mylist, itemname);
        this.context = context;
        this.originalItemNames = itemname.clone();
        this.filteredItemNames = new ArrayList<>(Arrays.asList(itemname));
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
        if (rowView == null) {
            LayoutInflater inflater = context.getLayoutInflater();
            rowView = inflater.inflate(R.layout.emp_leave_adpater_layout, parent, false);
        }

        TextView txtTitle = rowView.findViewById(R.id.item);
        ImageView image = rowView.findViewById(R.id.icon);

        txtTitle.setText(filteredItemNames.get(position));
        return rowView;
    }

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

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

                if (constraint == null || constraint.length() == 0) {
                    // No filter applied: use original data
                    filteredList.addAll(Arrays.asList(originalItemNames));
                } else {
                    String filterPattern = constraint.toString().toLowerCase().trim();
                    // Match items against the filter
                    for (String item : originalItemNames) {
                        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) {
                filteredItemNames = (List<String>) results.values;
                notifyDataSetChanged();
            }
        };
    }
}

This version maintains a separate original dataset and filtered list, with explicit filter logic to update the list and notify the adapter of changes.

内容的提问来源于stack exchange,提问作者Kamran Ijaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:34:59