AutoCompleteTextView onItemClick позиция элемента или идентификатор с помощью HashMap - PullRequest
7 голосов
/ 21 апреля 2010

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

Я бы хотел поместить пары HashMap с id => name в AutoCompleteTextView и получить идентификатор выбранного элемента. Когда я щелкаю по выводу отфильтрованного набора автозаполнения, я хочу заполнить список под окном автозаполнения, которое мне также удалось получить.

Сделано до сих пор:

  • автозаполнение хорошо работает для простого ArrayList, все данные отфильтрованы правильно
  • Событие onItemClick срабатывает правильно после нажатия
  • parent.getItemAtPosition (position) возвращает правильное строковое представление выбранного элемента

Событие onItemClick (родительский объект AdapterView, View v, позиция int, длинный идентификатор) не работает так, как мне бы хотелось. Как я могу выяснить нефильтрованную позицию массива выбранного элемента? Меня не интересует позиция отфильтрованного.

Дополнительные вопросы:

  • Как обрабатывать HashMaps или коллекции в AutoCompleteTextView
  • Как получить правильный itemId в событии onItemClick

Я провел очень обширное исследование по этому вопросу, но не нашел никакой ценной информации, которая бы отвечала на мои вопросы.

1 Ответ

0 голосов
/ 11 июня 2011

Как обрабатывать HashMaps или коллекции в AutoCompleteTextView

Вы можете установить свой собственный адаптер. В вашем адаптере это зависит от вас, где вы получите свои данные в данной позиции.

Как получить правильный itemId в событии onItemClick

В своем настраиваемом адаптере вы определяете фильтр, и этот фильтр устанавливает предлагаемые элементы. У вас есть два разных списка, один с исходными значениями, а другой с отфильтрованными элементами. Я имею в виду что-то вроде этого.

private class AutoCompleteItemAdapter extends ArrayAdapter<YourItemClass> implements Filterable {

    private NameFilter      mFilter;
    List<YourItemClass> suggestions;
    List<YourItemClass> mOriginalValues;

    public AutoCompleteItemAdapter(Context context, int resource, List<YourItemClass> suggestions) {
        super(context, resource, suggestions);
        this.suggestions = suggestions;
        this.mOriginalValues = suggestions;
    }

    public void updateData(List<YourItemClass> suggestions) {
               mLock.lock();
               try{
                   this.suggestions = suggestions;
                       this.mOriginalValues = suggestions;
            finally{
                mLock.unlock();
            }
        }

    @Override
    public int getCount() {
        mLock.lock();
        try {
            return suggestions.size();
        } finally {
            mLock.unlock();
        }
    }

    @Override
    public YourItemClass getItem(int position) {
        return mOriginalValues.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // draw your item here...
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new NameFilter();
        }
        return mFilter;
    }

    private class NameFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                mLock.lock();
                try {
                    mOriginalValues = new ArrayList<YourItemClass>(suggestions);
                } finally {
                    mLock.unlock();
                }
            }

            if (prefix == null || prefix.length() == 0) {
                mLock.lock();
                try {
                    ArrayList<YourItemClass> list = new ArrayList<YourItemClass>(mOriginalValues);
                    results.values = list;
                    results.count = list.size();
                } finally {
                    mLock.unlock();
                }
            } else {
                String prefixString = prefix.toString().toLowerCase();

                final List<YourItemClass> values = mOriginalValues;
                final int count = values.size();

                final ArrayList<YourItemClass> newValues = new ArrayList<YourItemClass>(count);

                //              FILTERING
                //
                    // add your hits to the newValues collection
                //
                //
                results.values = newValues;
                results.count = newValues.size();
            }
            return results;
        }


        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mLock.lock();
            try {
                if (results == null || results.values == null) return; 
                suggestions = new ArrayList<YourItemClass>();
                suggestions = (List<YourItemClass>) results.values;
                if (results.count > 0) {
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            } finally {
                mLock.unlock();
            }
        }
    }
}

Теперь это может вызвать некоторые проблемы с параллелизмом, как мы уже упоминали, адаптер может запросить размер списка и вывести большее значение, что может вызвать проблемы в функции getView. (fi .: Попытка нарисовать 5 элементов с базовыми данными имеет только 4, потому что мы сделали другую фильтрацию) Таким образом, мы использовали AutoCompleteTextView, и пока он работает отлично, нет проблем. Я только что упомянул, что я все еще обеспокоен, и у меня есть смутное ощущение, что есть лучшее решение для этого.

В прослушивателе onClick вы используете возвращенное значение (из отфильтрованного списка) в качестве ключа на карте и получаете соответствующее значение. Вы можете думать, что ваш список вы используете индекс для HashMap. После этого вы можете использовать Map, чтобы нарисовать свой элемент или получить свои собственные данные.

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