Динамическое обновление AutoCompleteTextView всплывающее окно снова после выбора элемента - PullRequest
3 голосов
/ 23 ноября 2011

Я динамически обновляю AutoCompleteTextView и столкнулся с двумя проблемами.

  • когда выбран элемент, возникает новое событие onTextChanged, и, как видно из кода ниже, появляется новый запрос на получение новых необязательных элементов, поэтому событие onTextChanged заставляет автозаполнение снова показывать раскрывающийся список! есть ли чистый способ ее решить?!

  • результаты, которые я получаю из автозаполнения, получены из предыдущего адаптера, прежде чем я вызову notifyDataSetChange (), как я могу это сделать?!

вот код:

AutoCompleteTextView acCountry = (AutoCompleteTextView)layout.findViewById(R.id.autoComplete);
final ArrayAdapter<RMAutoComplete.ListItem> countriesAdapter = new ArrayAdapter<RMAutoComplete.ListItem>(this.context,android.R.layout.simple_dropdown_item_1line);
acCountry.setAdapter(countriesAdapter);
acCountry.addTextChangedListener(new TextWatcher() {

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() > 1)
            {
                new AsyncTask<String, Void, List<RMAutoComplete.ListItem>>(){

                    @Override
                    protected List<ListItem> doInBackground(String... params) {
                        List<ListItem> l = null;
                        try {
                            l = location.getCountryData(params[0]);
                        } catch (Exception e) {
                            Log.e(TAG,"error when getCountryData",e);
                        }
                        return l;
                    }

                    @Override
                    protected void onPostExecute(List<ListItem> countries) {
                        countriesAdapter.clear();
                        if (countries != null)
                            for (ListItem listItem : countries) {
                                countriesAdapter.add(listItem);
                            }
                        countriesAdapter.notifyDataSetChanged();
                    }
                }.execute(s.toString());
            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

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

1 Ответ

3 голосов
/ 04 декабря 2011

Чтобы достичь динамического адаптера, нужно реализовать собственный класс Filter и переопределить методы executeFiltering и publishResults.

В executeFiltering создайте новый экземпляр FilterResults и инициализировать его значения и считать с новыми элементами .. (этот метод работает по умолчанию в новом потоке!) Что-то вроде этого:

@Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults fr = null;
        if (constraint != null)
        {
            List<ListItem> list = getFilterdValues(constraint.toString());

            if (list != null)
            {
                fr = new FilterResults();
                fr.values = list;
                fr.count = list.size();
            }
        }
        return fr;
    }

и в publishResults добавить результат вАдаптер, подобный следующему:

@Override
    protected void publishResults(CharSequence constraint,
            FilterResults results) {
        AutoCompleteAdapter.this.clear();
        if (results != null)
        {
            if (results.values != null)
            {
                List<ListItem> items = (List<ListItem>) results.values;

                    for (ListItem listItem : items) {
                        AutoCompleteAdapter.this.add(listItem);
                    }

                if (items.size() > 0)
                {
                    AutoCompleteAdapter.this.notifyDataSetChanged();
                    return;
                }
            }
        }
        AutoCompleteAdapter.this.notifyDataSetInvalidated();
    }

также и важно, что вам нужно настроить адаптер и переопределить getFilter с помощью собственного нового пользовательского класса Filter, например:

public class AutoCompleteAdapter extends ArrayAdapter<RMAutoComplete.ListItem> 
{


private CustomFilter _customFilter = null;

@Override
public Filter getFilter() {

    if (_customFilter == null)
        _customFilter = new CustomFilter();
    return _customFilter;
}


public AutoCompleteAdapter(Context context, int textViewResourceId) {
    super(context, textViewResourceId);

}

}

надеюсь, это было полезнодля кого-то ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...