Изменить фильтр AutoCompleteTextView с "startsWith" на "Contains"?

Я хотел бы изменить фильтр по умолчанию в AutoCompleteTextView. Фильтрация по умолчанию находит все строки, которые начинаются с данного маркера. Мой проект требует, чтобы фильтрация нашла все строки, содержащие данный токен.

это возможно?

4 ответов


Я нашел решение для этого, благодаря Google и поиск в течение двух дней. Как предложил @torque203, я реализовал свой собственный адаптер. Сначала определите новый XML-файл для пользовательского элемента в адаптере:

autocomplete_item.в XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:paddingTop="16dp"
        android:paddingBottom="16dp"
        android:id="@+id/lbl_name" />
</RelativeLayout>

создать новый класс для ваших имен:

имена

public class Names {
    public String name;
}

NamesAdapter

public class NamesAdapter extends ArrayAdapter<Names> {

    Context context;
    int resource, textViewResourceId;
    List<Names> items, tempItems, suggestions;

    public NamesAdapter(Context context, int resource, int textViewResourceId, List<Names> items) {
        super(context, resource, textViewResourceId, items);
        this.context = context;
        this.resource = resource;
        this.textViewResourceId = textViewResourceId;
        this.items = items;
        tempItems = new ArrayList<Names>(items); // this makes the difference.
        suggestions = new ArrayList<Names>();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.autocomplete_item, parent, false);
        }
        Names names = items.get(position);
        if (names != null) {
            TextView lblName = (TextView) view.findViewById(R.id.lbl_name);
            if (lblName != null)
                lblName.setText(names.name);
        }
        return view;
    }

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

    /**
     * Custom Filter implementation for custom suggestions we provide.
     */
    Filter nameFilter = new Filter() {
        @Override
        public CharSequence convertResultToString(Object resultValue) {
            String str = ((Names) resultValue).name;
            return str;
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            if (constraint != null) {
                suggestions.clear();
                for (Names names : tempItems) {
                    if (names.name.toLowerCase().contains(constraint.toString().toLowerCase())) {
                        suggestions.add(names);
                    }
                }
                FilterResults filterResults = new FilterResults();
                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
                return filterResults;
            } else {
                return new FilterResults();
            }
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            List<Names> filterList = (ArrayList<Names>) results.values;
            if (results != null && results.count > 0) {
                clear();
                for (Names names : filterList) {
                    add(names);
                    notifyDataSetChanged();
                }
            }
        }
    };
}

SearchActivity (или ваша основная деятельность)

....
   List<Names> namesList =  //your names list;
   NamesAdapter namesAdapter = new NamesAdapter(
                    SearchActivity.this,
                    R.layout.activity_search,
                    R.id.lbl_name,
                    namesList
            );
            //set adapter into listStudent
            autoCompleteTextView.setAdapter(namesAdapter);
            autoCompleteTextView.showDropDown();
...

Да, это возможно.

Первый способ:

вы должны создать пользовательский адаптер, который реализует и фильтрация.

на фильтр чем может реализовать вашу логику фильтра" содержит".

и установить этот адаптер как адаптер к AutoCompleteTextView.

второй вариант:

Если вы уже используете ArrayAdapter. Вы можете просто переопределить его getFilter() метод.


просто чтобы расширить приятный ответ Caffe Latte:

1)autoCompleteTextView.showDropDown(); не требуется.

2) для извлечения входного объекта можно использовать:

//retrieve the input in the autoCompleteTextView
        autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            //parent The AdapterView where the click happened.
            //view The view within the AdapterView that was clicked (this will be a view provided by the adapter)
            //position The position of the view in the adapter
            //id The row id of the item that was clicked.
            public void onItemClick(AdapterView<?> parent, View view, int position, long rowId) {
                String selection =parent.getItemAtPosition(position).toString();
                Toast.makeText(parent.getContext(),"" + selection,Toast.LENGTH_SHORT).show();
            }
        });

объект, полученный от родителя, должен иметь реализованный метод toString ().


// попробуйте это

autoCompleteText.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View arg1, int position, long arg3) {
        YourCustomModel YourFilterdSelectedModel = (YourCustomModel) adapterView.getItemAtPosition(position);
        autoCompleteText.setText(str);
    }
});

£ Это сработало для меня