如何在 Android 上动态更新 ListView

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

我在找这样的东西:

-------------------------
| Text View             |
-------------------------
| List item             |
| List item             |
| List item             |
| List item             |
|                       |
|                       |
|                       |
|                       |
-------------------------
91566 次浏览

首先,您需要创建一个同时具有 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对象,可用于自动执行过滤。我们只需要管道输入从 EditTextFilter。事实证明这很简单。若要运行快速测试,请将此行添加到 onCreate()调用中

adapter.getFilter().filter(s);

请注意,您将需要保存您的 ListAdapter到一个变量,使这个工作-我已经保存我的 ArrayAdapter<String>从早期到一个名为’适配器’的变量。

下一步是从 EditText获取输入。这确实需要一点思考。你可以在你的 EditText中加入一个 OnKeyListener()。但是,这个侦听器只接收 OnKeyListener()1。例如,如果用户输入“ wyw”,联想文本可能会推荐“ eye”。除非用户选择“ wyw”或“ eye”,否则 OnKeyListener将不会接收到密钥事件。有些人可能更喜欢这个解决方案,但我发现它令人沮丧。我想要每个关键事件,所以我可以选择过滤或不过滤。解决方案是 TextWatcher。只需创建一个 TextWatcher并将其添加到 EditText,并在每次文本更改时向 ListAdapterFilter传递一个过滤器请求。记住去掉 OnKeyListener()0中的 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);
}

运行程序会导致一股力量关闭。

我换了句台词:

Android: id = “@+ building _ list/search _ box”

Android: id = “@+ id/search _ box”

这是问题所在吗? “@+ building _ list”是什么意思?

我在过滤方面有问题, 结果已经过滤,但 没有修复

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

在筛选时,筛选器和 listAdapter 连接到主列表。

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

在我的例子中,这保证了列表会立即更新,甚至在删除搜索关键字时,列表在每种情况下都会成功恢复:)

不管怎样,谢谢你的解决方案。