it-swarm.com.ru

Как динамически обновить ListView на Android

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

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

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------
159
Hamy

Во-первых, вам нужно создать макет 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 с надписью Nice выше. Чтобы заставить этот блок что-то делать, нам нужно взять входные данные из него и сделать этот фильтр фильтрующим список. Хотя многие пытались сделать это вручную, большинствоListViewAdapter классы поставляются с объектом Filter, который можно использовать для автоматической фильтрации. Нам просто нужно передать входные данные из EditText в Filter. Оказывается, это довольно легко. Чтобы выполнить быстрый тест, добавьте эту строку в вызов onCreate()

adapter.getFilter().filter(s);

Обратите внимание, что вам нужно будет сохранить свое ListAdapter в переменную, чтобы эта работа работала - я ранее сохранил свой ArrayAdapter<String> в переменную с именем 'adapter'.

Следующим шагом является получение входных данных от EditText. Это на самом деле занимает немного мысли. Вы можете добавить OnKeyListener() к своему EditText. Однако этот слушатель получает только некоторые ключевые события. Например, если пользователь вводит "wyw", предиктивный текст, скорее всего, порекомендует "eye". Пока пользователь не выберет "wyw" или "eye", ваше OnKeyListener не получит ключевое событие. Некоторые могут предпочесть это решение, но я нахожу это разочаровывающим. Я хотел каждое ключевое событие, поэтому у меня был выбор фильтрации или не фильтрации. Решением является TextWatcher. Просто создайте и добавьте TextWatcher к EditText и передайте ListAdapterFilter запрос фильтра при каждом изменении текста. Не забудьте удалить TextWatcher из 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);
}
286
Hamy

запуск программы вызовет принудительное закрытие.

Я поменял линию:

Android: ID = "@ + building_list/search_box"

с

Android: ID = "@ + идентификатор/search_box"

может ли это быть проблема? Для чего нужен "@ + building_list"?

10
j7nn7k

у меня была проблема с фильтрацией, результаты были отфильтрованы, но не восстановлено!

поэтому перед фильтрацией (началом активности) я создал резервную копию списка .. (просто еще один список, содержащий те же данные)

при фильтрации фильтр и listadapter подключаются к первичному списку.

но сам фильтр использовал данные из резервного архива.

в моем случае это гарантировалось, что список обновлялся немедленно, и даже при удалении символов-терминов поиска список успешно восстанавливался в каждом случае :)

спасибо за это решение в любом случае.

4
cV2