如何动态更新Android上的ListView
在Android上,我怎样才能ListView
,根据用户输入过滤,其中显示的项目是基于TextView
值动态更新?
我正在寻找这样的东西:
------------------------- | Text View | ------------------------- | List item | | List item | | List item | | List item | | | | | | | | | -------------------------
首先,您需要创建一个同时具有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" > <!-- 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>
这将把所有的东西放在正确的位置,在ListView上方有一个漂亮的EditText。 接下来,像平常一样创建一个ListActivity,但是在onCreate()
方法中添加一个setContentView()
调用,以便使用我们最近声明的布局。 请记住,我们特意使用android:id="@android:id/list"
ListView
。 这允许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”,则预测文本将可能推荐“眼睛”。 在用户选择“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); }
运行程序将导致一个关闭的力量。
我换了一行:
机器人:ID = “@ + building_list / search_box”
同
机器人:ID = “@ + ID / search_box”
这可能是问题吗? 什么是“@ + building_list”?
我有一个过滤问题,结果已被过滤,但没有恢复 !
所以在过滤(活动开始)之前,我创建了一个列表备份..(只是另一个列表,包含相同的数据)
在过滤时,过滤器和listadapter连接到主列表。
但过滤器本身使用备份列表中的数据。
这保证了我的情况,即时更新列表,甚至在删除搜索字词时,列表在每种情况下都能成功恢复:)
无论如何感谢这个解决方案。