По-перше, вам потрібно створити макет 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
, з приємним полем вгорі. Для того, щоб це поле зробило щось, нам потрібно взяти з нього вхід і зробити цей вхід фільтрувати список. Хоча багато людей намагалися зробити це вручну, більшість ListView
Adapter
класів мають Filter
об’єкт, який можна використовувати для автоматичної фільтрації. Нам просто потрібно подати вхід з вхідного EditText
пристрою Filter
. Виявляється, це досить просто. Щоб виконати швидкий тест, додайте цю лінію до свого onCreate()
дзвінка
adapter.getFilter().filter(s);
Зверніть увагу, що вам потрібно буде зберегти вашу ListAdapter
змінну, щоб зробити цю роботу - я зберег свій ArrayAdapter<String>
раніше від змінної під назвою "адаптер".
Наступним кроком є отримання вхідних даних від EditText
. Це насправді потребує трохи думки. Ви можете додати OnKeyListener()
свій EditText
. Однак цей слухач отримує лише деякі ключові події . Наприклад, якщо користувач вводить "wyw", передбачуваний текст, ймовірно, рекомендує "око". Поки користувач не обере або "око", або "око", ви OnKeyListener
не отримаєте ключову подію. Деякі можуть віддати перевагу цьому рішенню, але я вважаю це неприємним. Я хотів кожну ключову подію, тому у мене був вибір фільтрувати чи не фільтрувати. Рішення - а TextWatcher
. Просто створіть і додайте TextWatcher
до EditText
, і передайте ListAdapter
Filter
запит на фільтр щоразу, коли текст змінюється. Чи не забудьте видалити 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);
}