首先,您需要创建一个包含EditText和ListView的XML布局。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<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"/>
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
</LinearLayout>
这将正确地放置所有内容,一个漂亮的EditText在ListView上方。接下来,像通常一样创建ListActivity,但在onCreate()方法中添加setContentView()调用以使用我们最近声明的布局。请记住,我们特别标识了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>
保存到一个名为“adapter”的变量中。
下一步是获取 EditText
中的输入。这实际上需要一些思考。您可以向 EditText
添加 OnKeyListener()
。但是,此侦听器仅接收某些按键事件。例如,如果用户输入“wyw”,则预测文本可能会推荐“eye”。直到用户选择“wyw”或“eye”,您的 OnKeyListener
才会收到按键事件。有些人可能喜欢这种解决方案,但我觉得它很让人沮丧。我想要每个按键事件,所以我可以选择过滤或不过滤。解决方案是使用 TextWatcher
。只需创建并添加一个 TextWatcher
到 EditText
,并在每次文本更改时向 ListAdapter
的 Filter
发送一个过滤请求。记得在 OnDestroy()
中删除 TextWatcher
!这是最终的解决方案:
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);
}