Jak dynamicznie aktualizować ListView na Androidzie [zamknięty]

Na Androidzie, jak Mogę wybrać ListView, który filtruje na podstawie danych wejściowych użytkownika, gdzie wyświetlane elementy są dynamicznie aktualizowane na podstawie wartości TextView?

Szukam czegoś takiego:

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------
Author: Hamy, 2009-11-15

3 answers

Najpierw musisz utworzyć układ XML, który ma zarówno EditText, jak i 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>

To wszystko ułoży się poprawnie, z ładnym edytorem nad ListView. Następnie utwórz ListActivity tak, jak normalnie, ale dodaj wywołanie setContentView() w metodzie onCreate(), więc użyjemy naszego ostatnio zadeklarowanego układu. Pamiętaj, że identyfikujemy ListView specjalnie z android:id="@android:id/list". To pozwala ListActivity wiedzieć, którego ListView chcemy użyć w naszym zadeklarowanym układzie.

    @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());
    }

Uruchamianie aplikacji teraz powinieneś pokazać swoją poprzednią ListView, z ładnym pudełkiem powyżej. Aby to pole mogło coś zrobić, musimy pobrać z niego dane wejściowe i sprawić, by Dane wejściowe filtrowały listę. Podczas gdy wiele osób próbowało zrobić to ręcznie, większość ListView Adapter klasy są wyposażone w obiekt Filter, który może być użyty do automatycznego filtrowania. Musimy tylko przekierować wejście z EditText do Filter. Okazuje się, że to całkiem proste. Aby uruchomić szybki test, dodaj tę linię do swojego onCreate() call

adapter.getFilter().filter(s);

Zauważ, że będziesz musiał zapisać swoją ListAdapter do zmiennej, aby to działało - zapisałem swoją ArrayAdapter<String> z wcześniej do zmiennej o nazwie 'adapter'.

Następnym krokiem jest pobranie danych wejściowych z EditText. To wymaga trochę przemyśleń. Możesz dodać OnKeyListener() do swojego EditText. Jednak ten słuchacz odbiera tylko niektóre kluczowe wydarzenia . Na przykład, jeśli użytkownik wprowadzi "wyw", tekst predykcyjny prawdopodobnie poleci "oko". Dopóki użytkownik nie wybierze albo "wyw" lub "oko", twoje OnKeyListener nie otrzyma kluczowego zdarzenia. Niektórzy mogą preferować takie rozwiązanie, ale uważam, że jest to frustrujące. Chciałem każde kluczowe wydarzenie, więc miałem wybór filtrowania lub nie filtrowania. Rozwiązaniem jest TextWatcher. Wystarczy utworzyć i dodać TextWatcher do EditText i przekazać ListAdapter Filter żądanie filtrowania za każdym razem, gdy zmienia się tekst. Pamiętaj, aby usunąć TextWatcher w OnDestroy()! Oto ostateczne rozwiązanie:

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
Author: Hamy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-15 10:52:26

Uruchomienie programu spowoduje zamknięcie siły.

I swaped the line:

Android: id= "@ + building_list / search_box "

Z

Android: id= "@ + id / search_box "

Czy to może być problem? Do czego służy '@ + building_list'?

 10
Author: j7nn7k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-15 11:29:46

Miałem problem z filtrowaniem, że wyniki zostały przefiltrowane, ale nie przywrócone !

Więc przed filtrowaniem (start aktywności) utworzyłem kopię zapasową listy.. (kolejna lista, zawierająca te same dane)

Podczas filtrowania filtr i listadapter są podłączone do listy głównej.

Ale sam filtr wykorzystywał dane z listy kopii zapasowej.

To zapewniło w moim przypadku, że lista została zaktualizowana natychmiast, a nawet po usunięciu wyszukiwanych znaków lista jest przywracana pomyślnie w każdym przypadku:)

Dzięki Za To rozwiązanie w każdym razie.

 4
Author: cV2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-17 08:48:21