如何在 Android 上动态更新 ListView [英] How to dynamically update a ListView on Android

查看:40
本文介绍了如何在 Android 上动态更新 ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

On Android, how can I a ListView that filters based on user input, where the items shown are updated dynamically based on the TextView value?

我正在寻找这样的东西:

I'm looking for something like this:

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

推荐答案

首先,您需要创建一个包含 EditText 和 ListView 的 XML 布局.

First, you need to create an XML layout that has both an EditText, and a 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>

这将正确布置所有内容,在 ListView 上方有一个漂亮的 EditText.接下来,像往常一样创建一个 ListActivity,但在 onCreate() 方法中添加一个 setContentView() 调用,以便我们使用我们最近声明的布局.请记住,我们特别使用 android:id="@android:id/list"ListView 进行了 ID.这允许 ListActivity 知道我们想在我们声明的布局中使用哪个 ListView.

This will lay everything out properly, with a nice EditText above the ListView. Next, create a ListActivity as you would normally, but add a setContentView() call in the onCreate() method so we use our recently declared layout. Remember that we ID'ed the ListView specially, with android:id="@android:id/list". This allows the ListActivity to know which ListView we want to use in our declared layout.

    @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() 调用

Running the app now should show your previous ListView, with a nice box above. In order to make that box do something, we need to take the input from it, and make that input filter the list. While a lot of people have tried to do this manually, most ListView Adapter classes come with a Filter object that can be used to perform the filtering automagically. We just need to pipe the input from the EditText into the Filter. Turns out that is pretty easy. To run a quick test, add this line to your onCreate() call

adapter.getFilter().filter(s);

请注意,您需要将 ListAdapter 保存到一个变量中才能完成这项工作 - 我已将我之前的 ArrayAdapter 保存到一个名为adapter"的变量中'.

Notice that you will need to save your ListAdapter to a variable to make this work - I have saved my ArrayAdapter<String> from earlier into a variable called 'adapter'.

下一步是从 EditText 获取输入.这实际上需要一些思考.您可以将 OnKeyListener() 添加到您的 EditText.然而,这个监听器只接收一些关键事件.例如,如果用户输入wyw",则预测文本可能会推荐eye".在用户选择 'wyw' 或 'eye' 之前,您的 OnKeyListener 将不会收到按键事件.有些人可能更喜欢这个解决方案,但我发现它令人沮丧.我想要每个关键事件,所以我可以选择过滤或不过滤.解决方案是 TextWatcher.只需创建一个 TextWatcher 并将其添加到 EditText 中,并在每次输入文本时向 ListAdapter Filter 传递一个过滤器请求变化.记得移除 OnDestroy() 中的 TextWatcher!这是最终的解决方案:

Next step is to get the input from the EditText. This actually takes a bit of thought. You could add an OnKeyListener() to your EditText. However, this listener only receives some key events. For example, if a user enters 'wyw', the predictive text will likely recommend 'eye'. Until the user chooses either 'wyw' or 'eye', your OnKeyListener will not receive a key event. Some may prefer this solution, but I found it frustrating. I wanted every key event, so I had the choice of filtering or not filtering. The solution is a TextWatcher. Simply create and add a TextWatcher to the EditText, and pass the ListAdapter Filter a filter request every time the text changes. Remember to remove the TextWatcher in OnDestroy()! Here is the final solution:

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);
}

这篇关于如何在 Android 上动态更新 ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆