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>
Spowoduje to poprawne ułożenie wszystkiego, z ładnym tekstem edycji nad ListView. Następnie utwórz ListActivity w normalny sposób, ale dodaj setContentView()
wywołanie do onCreate()
metody, abyśmy używali naszego niedawno zadeklarowanego układu. Pamiętaj, że zidentyfikowaliśmy ListView
specjalnie, z android:id="@android:id/list"
. Dzięki temu ListActivity
wie, 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());
}
Uruchomienie aplikacji powinno teraz pokazać poprzednią ListView
, z ładnym pudełkiem powyżej. Aby zmusić to pole do zrobienia czegoś, musimy pobrać z niego dane wejściowe i uczynić z tego filtru listę. Chociaż wiele osób próbowało zrobić to ręcznie, większość ListView
Adapter
klas zawiera Filter
obiekt, którego można użyć do automatycznego filtrowania. Musimy tylko rury wejście od EditText
do Filter
. Okazuje się, że jest to całkiem proste. Aby przeprowadzić szybki test, dodaj tę linię do onCreate()
rozmowy
adapter.getFilter().filter(s);
Zauważ, że będziesz musiał zapisać swoje ListAdapter
w zmiennej, aby to działało - zapisałem moje ArrayAdapter<String>
z wcześniej w zmiennej o nazwie „adapter”.
Następnym krokiem jest pobranie danych wejściowych z pliku EditText
. To wymaga trochę namysłu. Możesz dodać OnKeyListener()
do swojego EditText
. Jednak ten odbiornik odbiera tylko niektóre kluczowe zdarzenia . Na przykład, jeśli użytkownik wpisze „wyw”, przewidywany tekst prawdopodobnie zaleci słowo „oko”. Dopóki użytkownik nie wybierze „wyw” lub „eye”, OnKeyListener
nie otrzymasz kluczowego zdarzenia. Niektórzy mogą preferować to rozwiązanie, ale uznałem to za frustrujące. Chciałem każdego kluczowego zdarzenia, więc miałem wybór, czy filtrować, czy nie. Rozwiązaniem jest TextWatcher
. Po prostu utwórz i dodaj a TextWatcher
do EditText
i przekaż ListAdapter
Filter
żądanie filtru za każdym razem, gdy zmieni się tekst. Pamiętaj, aby usunąć TextWatcher
in 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);
}