Как динамически обновить ListView на Android [закрыто]



на Android, как я могу a ListView что фильтры на основе пользовательского ввода, где элементы, показанные обновляются динамически на основе TextView значение?



Я ищу что-то вроде этого:



-------------------------
| Text View |
-------------------------
| List item |
| List item |
| List item |
| List item |
| |
| |
| |
| |
-------------------------
797   3  

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 запрос фильтра при каждом изменении текста. Не забудьте удалить TextWatcher in OnDestroy()! Вот окончательное решение:

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

    Ничего не найдено.