Zunächst müssen Sie ein XML-Layout erstellen, das sowohl einen EditText als auch eine ListView enthält.
<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>
Dadurch wird alles richtig dargestellt, mit einem schönen EditText über der ListView. Erstellen Sie als Nächstes eine ListActivity wie gewohnt, fügen Sie jedoch einen setContentView()
Aufruf in die onCreate()
Methode ein, damit wir unser kürzlich deklariertes Layout verwenden. Denken Sie daran, dass wir die ListView
speziell mit identifiziert haben android:id="@android:id/list"
. Dadurch können wir ListActivity
wissen, welche ListView
wir in unserem deklarierten Layout verwenden möchten.
@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());
}
Wenn Sie die App jetzt ausführen, sollte Ihre vorherige App ListView
mit einem schönen Feld oben angezeigt werden. Damit diese Box etwas tut, müssen wir die Eingabe daraus entnehmen und diese Eingabe die Liste filtern lassen. Während viele Leute versucht haben, dies manuell zu tun, enthalten die meisten ListView
Adapter
Klassen ein Filter
Objekt, mit dem die Filterung automatisch durchgeführt werden kann. Wir müssen nur die Eingabe von der EditText
in die leiten Filter
. Es stellt sich heraus, dass das ziemlich einfach ist. Fügen Sie diese Leitung zu Ihrem onCreate()
Anruf hinzu, um einen Schnelltest durchzuführen
adapter.getFilter().filter(s);
Beachten Sie, dass Sie Ihre ListAdapter
in einer Variablen speichern müssen, damit dies funktioniert. Ich habe meine ArrayAdapter<String>
von früher in einer Variablen namens "Adapter" gespeichert .
Der nächste Schritt besteht darin, die Eingabe von der zu erhalten EditText
. Dies erfordert tatsächlich ein wenig Nachdenken. Sie könnten eine OnKeyListener()
zu Ihrer hinzufügen EditText
. Dieser Listener empfängt jedoch nur einige Schlüsselereignisse . Wenn ein Benutzer beispielsweise "wyw" eingibt, empfiehlt der Vorhersagetext wahrscheinlich "eye". Bis der Benutzer entweder "wyw" oder "eye" wählt, erhalten Sie OnKeyListener
kein Schlüsselereignis. Einige mögen diese Lösung bevorzugen, aber ich fand sie frustrierend. Ich wollte jedes Schlüsselereignis, also hatte ich die Wahl, zu filtern oder nicht zu filtern. Die Lösung ist a TextWatcher
. Erstellen Sie einfach und fügen Sie TextWatcher
zu dem EditText
, und der Pass ListAdapter
Filter
einer Filteranforderung ändert dich der Text jedes Mal. Denken Sie daran, das TextWatcher
In zu entfernen OnDestroy()
! Hier ist die endgültige Lösung:
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);
}