如何在Android上动态更新ListView

时间:2009-11-15 08:38:19

标签: android listview filter android-widget

在Android上,我如何根据用户输入过滤ListView,其中显示的项目是根据TextView值动态更新的?

我正在寻找类似的东西:

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------

3 个答案:

答案 0 :(得分:286)

首先,您需要创建一个包含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,但在setContentView()方法中添加onCreate()调用,以便我们使用最近声明的布局。请记住,我们使用ListView专门为android:id="@android:id/list" ID。这允许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获取输入。这实际上需要一些思考。您可以在OnKeyListener()添加EditText。但是,此侦听器仅接收一些键事件。例如,如果用户输入“wyw”,预测文本可能会推荐“眼睛”。在用户选择“wyw”或“eye”之前,您的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); } !这是最终的解决方案:

{{1}}

答案 1 :(得分:10)

运行程序将导致力关闭。

我划过界限:

  

机器人:ID = “@ + building_list / search_box”

  

机器人:ID = “@ + ID / search_box”

那可能是问题吗?什么是'@ + building_list'?

答案 2 :(得分:4)

我有过滤问题, 结果已被过滤,但未恢复

所以在过滤(活动开始)之前我创建了一个列表备份.. (只是另一个列表,包含相同的数据)

在过滤时,过滤器和listadapter连接到主列表。

但过滤器本身使用了备份列表中的数据。

这确保了我的情况,列表立即更新,甚至在删除搜索术语字符时,列表在每种情况下都成功恢复:)

无论如何,谢谢你的解决方案。