Android 为什么在自定义AutocompleteTextview适配器中调用performFiltering()两次

Android 为什么在自定义AutocompleteTextview适配器中调用performFiltering()两次,android,autocompletetextview,custom-adapter,Android,Autocompletetextview,Custom Adapter,我创建了一个自定义的AutoCompleteTextView适配器。第一次调用performFiltering()时,它会过滤结果并返回FilterResults的实例(具有正确的值)。PublishResults()方法随后由系统调用,该系统调用notifyDataSetChanged() 在调用notifyDataSetChanged()之后,将立即再次调用PerformFilter方法。返回结果后,它不会再次调用PublishResults() 我还应该注意,过滤后的结果不会传递到Auto

我创建了一个自定义的AutoCompleteTextView适配器。第一次调用performFiltering()时,它会过滤结果并返回FilterResults的实例(具有正确的值)。PublishResults()方法随后由系统调用,该系统调用notifyDataSetChanged()

在调用notifyDataSetChanged()之后,将立即再次调用PerformFilter方法。返回结果后,它不会再次调用PublishResults()

我还应该注意,过滤后的结果不会传递到AutoComplete小部件。相反,整个原始数据集显示在下拉列表中。值得注意的是,尽管我将小部件的阈值设置为2,但在输入第一个字符后会调用performFiltering()

所以我的问题是:(1)为什么在notifyDataSetChanged()之后第二次调用performFiltering(),(2)为什么在达到阈值之前调用performFiltering(),(3)过滤结果未进入下拉列表的最常见原因是什么

import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.BaseAdapter;
import android.widget.Filterable;
import android.widget.Filter;
import android.widget.TextView;

import java.util.ArrayList;

/**
 * Created by John on 12/31/2016.
 */

public class myContactsAutoCompleteAdapter extends BaseAdapter
                                            implements Filterable {

    Context context;
    private LayoutInflater inflator;
    private ArrayList<Contacts.ContactDataRow> contactsList;
    private ArrayList<Contacts.ContactDataRow> suggestions = new ArrayList<>();

    public myContactsAutoCompleteAdapter(Context ctx, ArrayList<Contacts.ContactDataRow> data ) {
        this.context = ctx;
        this.contactsList = data;
        this.inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflator.inflate(R.layout.contacts_listview_item, null);
            viewHolder = new ViewHolder();
            viewHolder.txt_name = (TextView) convertView.findViewById(R.id.txt_contact_name);
            viewHolder.txt_phone = (TextView) convertView.findViewById(R.id.txt_contact_phone);
            viewHolder.txt_phonetype = (TextView) convertView.findViewById(R.id.txt_contact_type);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.txt_name.setText(contactsList.get(position).displayName);
        viewHolder.txt_phone.setText(contactsList.get(position).phone);
        viewHolder.txt_phonetype.setText(contactsList.get(position).phoneType);

        return convertView;
    }

    private static class ViewHolder {
        TextView txt_name;
        TextView txt_phone;
        TextView txt_phonetype;
    }

    @Override
    public Filter getFilter() {
        return new ContactsAutocompleteFilter();
    }

    private class ContactsAutocompleteFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults filterResults = new FilterResults();

            if (constraint != null && constraint.length() >= 2) {
                suggestions.clear();

                //Check for similarities in data from constraint
                for (Contacts.ContactDataRow row : contactsList) {
                    if (row.displayName.toLowerCase().contains(constraint.toString().toLowerCase())) {
                        suggestions.add(row);
                    }
                }

                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
            }

            return filterResults;

        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }
}
导入android.content.Context;
导入android.util.Log;
导入android.view.view;
导入android.view.ViewGroup;
导入android.view.LayoutInflater;
导入android.widget.BaseAdapter;
导入android.widget.Filterable;
导入android.widget.Filter;
导入android.widget.TextView;
导入java.util.ArrayList;
/**
*由John于2016年12月31日创建。
*/
公共类myContactsAutoCompleteAdapter扩展了BaseAdapter
可过滤的{
语境;
私人充气机;
私人ArrayList联系人列表;
私有ArrayList建议=新建ArrayList();
公共myContactsAutoCompleteAdapter(上下文ctx、ArrayList数据){
this.context=ctx;
this.contactsList=数据;
this.inflator=(LayoutInflater)context.getSystemService(context.LAYOUT\u INFLATER\u SERVICE);
}
@凌驾
public int getCount(){
返回contactsList.size();
}
@凌驾
公共对象getItem(int位置){
返回联系人列表。获取(位置);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
持票人持票人;
if(convertView==null){
convertView=充气机。充气(R.layout.contacts\u listview\u项,空);
viewHolder=新的viewHolder();
viewHolder.txt\u name=(TextView)convertView.findViewById(R.id.txt\u contact\u name);
viewHolder.txt_phone=(TextView)convertView.findViewById(R.id.txt_contact_phone);
viewHolder.txt_phonetype=(TextView)convertView.findViewById(R.id.txt_contact_type);
convertView.setTag(viewHolder);
}否则{
viewHolder=(viewHolder)convertView.getTag();
}
viewHolder.txt_name.setText(contactsList.get(position.displayName);
viewHolder.txt_phone.setText(contactsList.get(position.phone));
viewHolder.txt_phonetype.setText(contactsList.get(position.phonetype));
返回视图;
}
私有静态类视图持有者{
TextView txt_名称;
TextView txt_手机;
TextView txt_电话类型;
}
@凌驾
公共过滤器getFilter(){
返回新联系人以完成筛选();
}
私有类ContactsAutocompleteFilter扩展了筛选器{
@凌驾
受保护的筛选器结果性能筛选(CharSequence约束){
FilterResults FilterResults=新的FilterResults();
if(constraint!=null&&constraint.length()>=2){
建议。清晰();
//检查约束中数据的相似性
用于(Contacts.ContactDataRow行:contactsList){
if(row.displayName.toLowerCase().contains(constraint.toString().toLowerCase())){
建议。添加(行);
}
}
filterResults.values=建议;
filterResults.count=建议.size();
}
返回过滤器结果;
}
@凌驾
受保护的void publishResults(CharSequence约束、FilterResults结果){
if(results!=null&&results.count>0){
notifyDataSetChanged();
}否则{
notifyDataSetionValidated();
}
}
}
}

编辑:我更新了它以包括整个适配器类

我已经回答了问题2(基本要求)和问题3(过滤结果未在UI中更新)。但是,对performFiltering()的重复调用仍然未知,并且令人不安。我仍然希望有一个很好的方法来防止这种情况,而不是使用标志来识别和跳过多余的呼叫。我也看到这种情况发生在Galaxy S6上,而不是Nexus 5上