Как динамически обновить ListView на Android [закрыто]
на Android, как я могу a ListView что фильтры на основе пользовательского ввода, где элементы, показанные обновляются динамически на основе TextView значение?
Я ищу что-то вроде этого:
-------------------------
| Text View |
-------------------------
| List item |
| List item |
| List item |
| List item |
| |
| |
| |
| |
-------------------------
3 ответов:
во-первых, вам нужно создать XML-макет, который имеет как EditText, так и ListView.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- Pretty hint text, and maxLines --> <EditText android:id="@+building_list/search_box" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="type to filter" android:inputType="text" android:maxLines="1"/> <!-- Set height to 0, and let the weight param expand it --> <!-- Note the use of the default ID! This lets us use a ListActivity still! --> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" /> </LinearLayout>это будет выложить все правильно, с хорошим EditText над ListView. Затем создайте ListActivity как обычно, но добавьте
setContentView()вызов вonCreate()метод поэтому мы используем наш недавно объявленный макет. Помните, что мы идентифицировалиListViewспециально, сandroid:id="@android:id/list". Это позволяетListActivityчтобы знать, какойListViewмы хотим использовать в нашем объявлены макет.@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getStringArrayList()); }запуск приложения теперь должен показать ваш предыдущий
ListView, С красивую коробку. Чтобы заставить это поле что-то сделать, нам нужно взять вход из него и сделать этот входной фильтр списком. Хотя многие люди пытались сделать это вручную,большинствоListViewAdapterклассы поставляются сFilterобъект, который может быть использован для выполнения фильтрации автоматически. Нам просто нужно передать вход изEditTextнаFilter. Оказывается, что есть довольно легкий. Чтобы выполнить быстрый тест, Добавьте эту строку в свойonCreate()вызовadapter.getFilter().filter(s);обратите внимание, что вам нужно будет сохранить ваш
ListAdapterк переменной, чтобы сделать эту работу - я сохранил мойArrayAdapter<String>ранее в переменную под названием "адаптер".следующий шаг-получить входные данные от
EditText. Это на самом деле занимает немного подумал. Вы можете добавитьOnKeyListener()наEditText. Однако, этот слушатель получает только какие-то ключевые события. Например, если пользователь вводит "wyw", прогнозирующий текст, вероятно, будет рекомендовать "глаз". Пока пользователь выбирает 'wyw' или 'глаз', кодOnKeyListenerне получит ключевое событие. Некоторые могут предпочесть это решение, но я нашел его разочаровывающим. Я хотел каждое ключевое событие, поэтому у меня был выбор фильтрации или не фильтрации. Решение-этоTextWatcher. Просто создайте и добавьтеTextWatcherдоEditTextи передатьListAdapterFilterзапрос фильтра при каждом изменении текста. Не забудьте удалитьTextWatcherinOnDestroy()! Вот окончательное решение:private EditText filterText = null; ArrayAdapter<String> adapter = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.filterable_listview); filterText = (EditText) findViewById(R.id.search_box); filterText.addTextChangedListener(filterTextWatcher); setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getStringArrayList()); } private TextWatcher filterTextWatcher = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } }; @Override protected void onDestroy() { super.onDestroy(); filterText.removeTextChangedListener(filterTextWatcher); }
запуск программы приведет к принудительному закрытию.
Я swaped строку:
android: id= "@ + building_list/search_box"
с
android: id= "@ + id / search_box"
может ли это быть проблемой? Для чего нужен '@+building_list'?
У меня была проблема с фильтрацией, что результаты были отфильтрованы, но не восстановлены!
поэтому перед фильтрацией (запуском активности) я создал резервную копию списка.. (просто еще один список, содержащий те же данные)
при фильтрации фильтр и listadapter подключаются к основному списку.
но сам фильтр использовал данные из резервного списка.
это гарантировало в моем случае, что список был обновлен сразу и даже на удаление search-term-символов список восстанавливается успешно в каждом случае:)
спасибо за это решение в любом случае.
Comments