如何在Android上动态更新ListView

Ham*_*amy 159 android listview filter android-widget

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

我正在寻找这样的东西:

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------
Run Code Online (Sandbox Code Playgroud)

Ham*_*amy 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>
Run Code Online (Sandbox Code Playgroud)

这将使一切正常,在ListView上方有一个很好的EditText.接下来,像平常一样创建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());
    }
Run Code Online (Sandbox Code Playgroud)

现在运行应用程序应该显示您的上一个ListView,上面有一个很好的框.为了使该框执行某些操作,我们需要从中获取输入,并使该输入过滤列表.虽然很多人都尝试手动执行此操作,但大多数 ListView Adapter类都附带了一个Filter可用于自动执行过滤的对象.我们只需将输入管道输入EditTextFilter.事实证明这很容易.要运行快速测试,请将此行添加到您的onCreate()通话中

adapter.getFilter().filter(s);
Run Code Online (Sandbox Code Playgroud)

请注意,您需要将您保存ListAdapter到变量才能使其正常工作 - 我已将我ArrayAdapter<String>之前保存到名为'adapter'的变量中.

下一步是从中获取输入EditText.这实际上需要一些思考.你可以添加OnKeyListener()到您的EditText.但是,此侦听器仅接收一些关键事件.例如,如果用户输入"wyw",预测文本可能会推荐"眼睛".在用户选择"wyw"或"eye"之前,您OnKeyListener将不会收到关键事件.有些人可能更喜欢这种解决方案,但我发现它令人沮丧.我想要每个关键事件,所以我可以选择过滤或不过滤.解决方案是TextWatcher.只需创建并添加TextWatcherEditText,并通过ListAdapter Filter每一次的过滤器请求文本更改.记得删除TextWatcherin 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);
}
Run Code Online (Sandbox Code Playgroud)

  • Viktor - 如果你感兴趣的单词用空格分隔,那么它会自动完成.否则,不是真的.可能最简单的方法是通过扩展它来继承Adapter,并覆盖getFilter方法以返回您定义的Filter对象.请参阅http://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/ArrayAdapter.java#L449以了解默认ArrayFilter的工作原理 - 复制95%的此代码和改变第479和486行 (12认同)
  • 是否有任何直接的方式来过滤"包含"中的ListView而不是像这个解决方案那样的"开头"时尚? (7认同)
  • 这真的有必要吗?>记得在OnDestroy()中删除TextWatcher (4认同)
  • 哈米,优秀的写作!我有一个问题:我已经实现了这个,在我输入的每个字母之后,ListView消失了几秒钟然后又回来了,过滤了.你有没有经历过这个?我的直觉是因为我在列表中有600多个项目,具有非平凡的toString()函数. (2认同)
  • 在较小屏幕上的横向模式下,EditText +键盘占据整个屏幕,并且ListView不可见!有解决方案吗 (2认同)

j7n*_*n7k 10

运行程序将导致力关闭.

我划过界限:

机器人:ID = "@ + building_list/search_box"

机器人:ID = "@ + ID/search_box"

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