简体   繁体   English

AutoCompleteTextView的自定义筛选器单击时返回错误的字符串

[英]Custom Filter for AutoCompleteTextView returns wrong string on click

I wrote a custom ArrayAdapter with a custom Filter for my AutoCompleteTextView . 我为AutoCompleteTextView编写了带有自定义Filter的自定义ArrayAdapter It shows everything correctly, but when I filter the suggestions and click on an item, it takes the string of the item that was at this position in the suggestion list when ALL items were shown. 它可以正确显示所有内容,但是当我过滤建议并单击某个项目时,当显示所有项目时,它将采用建议列表中此位置的项目字符串。 I made screenshot to clarify what I mean: 我做了截图以澄清我的意思:

在此处输入图片说明

And this is my code: 这是我的代码:

public class AutoCompleteCountryAdapter extends ArrayAdapter<CountryItem> {
private List<CountryItem> countryList;
private List<CountryItem> filteredCountryList = new ArrayList<>();

public AutoCompleteCountryAdapter(@NonNull Context context, @NonNull List<CountryItem> countryList) {
    super(context, 0, countryList);
    this.countryList = countryList;
}

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

@NonNull
@Override
public Filter getFilter() {
    return countryFilter;
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    CountryItem countryItem = filteredCountryList.get(position);
    LayoutInflater inflater = LayoutInflater.from(getContext());

    if (convertView == null) {
        convertView = inflater.inflate(
                R.layout.country_autocomplete_row, parent, false
        );
    }

    TextView textViewName = convertView.findViewById(R.id.text_view_name);
    ImageView imageViewFlag = convertView.findViewById(R.id.image_view_flag);
    textViewName.setText(countryItem.getCountryName());
    imageViewFlag.setImageResource(countryItem.getFlagImage());

    return convertView;
}

private Filter countryFilter = new Filter() {

    private List<CountryItem> suggestions = new ArrayList<>();

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        suggestions.clear();
        FilterResults results = new FilterResults();

        if (constraint == null || constraint.length() == 0) {
            suggestions.addAll(countryList);
        } else {
            String filterPattern = constraint.toString().toLowerCase().trim();

            for (CountryItem item : countryList) {
                if (item.getCountryName().toLowerCase().contains(filterPattern)) {
                    suggestions.add(item);
                }
            }
        }
        results.values = suggestions;
        results.count = suggestions.size();
        return results;
    }

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

    @Override
    public CharSequence convertResultToString(Object resultValue) {
        return ((CountryItem) resultValue).getCountryName();
    }
};
}

I solved it. 我解决了 I have no idea why this did not appear in any tutorial I found (including the Materialdoc one), but you also have to override getItem in the adapter, to pick it's item from the filtered List, not the original List: 我不知道为什么它没有出现在我发现的任何教程中(包括Materialdoc),但是您还必须重写适配器中的getItem,以从过滤后的列表中选择项目,而不是原始列表:

 public CountryItem getItem(int position) {
    return filteredCountryList.get(position);
}

i provide one adapter class that used recylerview adapter for user contact adapter that filter user contact. 我提供了一种适配器类,该适配器类将recylerview适配器用于用户联系适配器,以过滤用户联系。 you can make changes your requirement according into code.. 您可以根据代码更改您的要求。

public class InviteContactAdapter extends RecyclerView.Adapter<InviteContactAdapter.ItemViewHolder> implements Filterable {
private List<UserContact> mContactList = new ArrayList<>();
private List<UserContact> mContectFilter = new ArrayList<>();
private Context mContext;
private CustomFilter mFilter;
public List<String> mEmailList = new ArrayList<>();

public InviteContactAdapter(Context context, List<UserContact> mContactList) {
    mContext = context;
    this.mContactList = mContactList;
    this.mContectFilter = mContactList;
    mFilter = new CustomFilter();
}

public onItemClickListener onItemClickListener;

public void setOnItemClickListener(InviteContactAdapter.onItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.invite_contact_row_layout, viewGroup, false);
    return new ItemViewHolder(view);
}

public interface onItemClickListener {
    void onClick(UserContact contact);
}

@Override
public Filter getFilter() {
    return mFilter;
}

@Override
public void onBindViewHolder(final ItemViewHolder itemViewHolder, int i) {
    final UserContact contact = mContectFilter.get(i);
    itemViewHolder.mTvUserNane.setText(contact.getUserName().trim());
    itemViewHolder.mTvUserEmail.setText(contact.getUserEmail().trim());
    if (contact.isSelect())
        itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
    else
        itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);


    itemViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            if (contact.isSelect()) {
                contact.setSelect(false);
                itemViewHolder.mIvSelect.setImageResource(R.drawable.un_check_contact);
            } else {
                contact.setSelect(true);
                itemViewHolder.mIvSelect.setImageResource(R.drawable.check_contect);
            }
        }
    });

}

@Override
public int getItemCount() {
    return mContectFilter.size();
}

public class ItemViewHolder extends RecyclerView.ViewHolder {
    private TextView mTvUserNane, mTvUserEmail;
    private ImageView mIvSelect;

    public ItemViewHolder(View itemView) {
        super(itemView);
        mTvUserEmail = itemView.findViewById(R.id.icrlTvUserEmail);
        mTvUserNane = itemView.findViewById(R.id.icrlTvUserName);
        mIvSelect = itemView.findViewById(R.id.icrlIvSelect);
    }
}

public List<String> getEmail() {
    mEmailList.clear();
    for (UserContact contact : mContectFilter) {
        if (contact.isSelect()) {
            mEmailList.add(contact.getUserEmail());
        }
    }
    return mEmailList;
}

/**
 * this class for filter data.
 */
class CustomFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        FilterResults results = new FilterResults();
        if (charSequence != null && charSequence.length() > 0) {
            ArrayList<UserContact> filters = new ArrayList<>();
            charSequence = charSequence.toString().toUpperCase();
            for (int i = 0; i < mContactList.size(); i++) {
                if (mContactList.get(i).getUserName().toUpperCase().contains(charSequence) || mContactList.get(i).getUserEmail().toUpperCase().contains(charSequence)) {
                    UserContact contact = new UserContact();
                    contact.setUserName(mContactList.get(i).getUserName());
                    contact.setUserEmail(mContactList.get(i).getUserEmail());
                    filters.add(contact);

                }
            }
            results.count = filters.size();
            results.values = filters;

        } else {
            results.count = mContactList.size();
            results.values = mContactList;
        }
        return results;
    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        mContectFilter = (ArrayList<UserContact>) filterResults.values;
        notifyDataSetChanged();
    }
}

} }

ArrayList<YourModel> arrayList = new ArrayList<>();
arrayList.addAll(yourList);

AutoCompleteAdapter autoCompleteAdapter = new AutoCompleteAdapter(context, arrayList);
autoCompleteTextView.setAdapter(brandAdapter);

autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        YourModel model = (YourModel) autoCompleteAdapter.getItem(position);
        autoCompleteTextView.setText(model.getText());
        autoCompleteTextView.setSelection(model.getText().length());
    }
});

AutoCompleteAdapter.java AutoCompleteAdapter.java

public class AutoCompleteAdapter extends BaseAdapter implements Filterable {

    private Context context;
    private ArrayList<YourModel> originalList;
    private ArrayList<YourModel> suggestions = new ArrayList<>();
    private Filter filter = new CustomFilter();

    public AutoCompleteAdapter(Context context, ArrayList<YourModel> originalList) {
        this.context = context;
        this.originalList = originalList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        try {
            if (convertView == null) {
                convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_filter, parent, false);
            }

            YourModel model = suggestions.get(position);

            AppCompatTextView tvTitle = convertView.findViewById(R.id.tvTitle);
            tvTitle.setText(model.getText());
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return convertView;
    }

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

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

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

    @Override
    public Filter getFilter() {
        return filter;
    }

    private class CustomFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            suggestions.clear();

            if (originalList != null && constraint != null) {
                for (int i = 0; i < originalList.size(); i++) {
                    if (originalList.get(i).getText().toLowerCase().contains(constraint.toString().toLowerCase().trim())) {
                        suggestions.add(originalList.get(i));
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = suggestions;
            results.count = suggestions.size();

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM