【问题标题】:notifyDataSetChanged examplenotifyDataSetChanged 示例
【发布时间】:2011-04-09 19:39:25
【问题描述】:

我正在尝试在我的Android Application 中使用notifyDataSetChanged() 方法作为ArrayAdapter,但它对我不起作用。

我发现as answer herenotifyDataSetChanged() 应该在主线程中运行,但没有示例。

任何人都可以发送一个示例或至少一个链接吗?!

【问题讨论】:

标签: android android-arrayadapter notifydatasetchanged


【解决方案1】:

对于ArrayAdapternotifyDataSetChanged 仅在您在适配器上使用add()insert()remove()clear() 时有效。

ArrayAdapter 被构造时,它包含对传入的List 的引用。如果你要传入一个作为Activity 成员的List,并稍后更改该Activity 成员, ArrayAdapter 仍然持有对原始 List 的引用。 Adapter 不知道你更改了 Activity 中的List

您的选择是:

  1. 使用ArrayAdapter的函数修改底层List(add()insert()remove()clear()等)
  2. 使用新的List 数据重新创建ArrayAdapter。 (使用大量资源和垃圾收集。)
  3. 创建您自己的派生自 BaseAdapterListAdapter 的类,允许更改底层 List 数据结构。
  4. 每次更新列表时使用notifyDataSetChanged()。要在 UI 线程上调用它,请使用 ActivityrunOnUiThread()。 然后,notifyDataSetChanged() 将起作用。

【讨论】:

  • 在为您的数据分配“新”对象时也要小心。改用 clear(),重新填充/更改数据,然后调用 notifyDataSetChanged()
  • 但是如果我们以这种方式调用notifyDataSetChanged() 会怎样:((BaseAdapter) arrayAdapter).notifyDataSetChanged();
  • 我使用 BaseExpandableListAdapter,它没有 add() 或 remove() 函数,因此我将 Map 存储为成员变量。我更新 Map 并调用 notifyDatasetChanged() 但没有任何反应。当我使用选项#4 时,它起作用了。为什么???
  • 我尝试创建自己的 BaseAdapter 以将排序方法添加到列表中,但由于某种原因它不起作用。并不是说我的应用程序很慢,即使我使用排序的数组列表重新创建整个适配器,但它仍然让我感到厌烦。它究竟是如何产生大量垃圾的呢?我假设实际的昂贵数据数组作为引用保存在调用适配器的活动中,这意味着只会收集适配器。
  • 请记住,当调用notifyDataSetChanged() 时,将检查声明为in the adapter 的数组。所以你应该在适配器中创建一个public 方法,比如updateArrayList,它会修改声明的数组。请记住使用ArrayList 方法如add()insert()remove()clear() 来更新项目。另外,请记住更新 RecyclerView 适配器中getItemCount() 中使用的数组大小。该参数用于确定RecyclerView的行号。
【解决方案2】:

您可以使用runOnUiThread() 方法,如下所示。如果您没有使用ListActivity,只需修改代码以获取对您的ArrayAdapter 的引用。

final ArrayAdapter adapter = ((ArrayAdapter)getListAdapter());
runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

【讨论】:

【解决方案3】:

我最近写过关于这个主题的文章,虽然这篇文章很旧,但我认为这对想知道如何以正确的方式逐步实现BaseAdapter.notifyDataSetChanged()的人有所帮助。

请关注How to correctly implement BaseAdapter.notifyDataSetChanged() in Androidthe newer blog BaseAdapter.notifyDataSetChanged()

【讨论】:

  • 您好,我尝试了第一个链接示例,但不是mItem.add(),而是我只编辑了一个元素,这意味着mItem.get(position).setImage(encodedImage) 可能就是它给出错误NullPointer exeption 的原因。notifyDataSetChange 也可以工作只是编辑它,bcz 用于上面提到的 Array 适配器它仅适用于 add()、clear()、remove() 等
  • notifyDataSetChanged 将用于编辑或修改数据集,您的空指针是因为其他原因,请查看日志。
【解决方案4】:

我遇到了同样的问题,我不想连续用新实例替换整个 ArrayAdapter。因此,我让 AdapterHelper 在其他地方完成繁重的工作。

将此添加到您通常(尝试)调用通知的地方

new AdapterHelper().update((ArrayAdapter)adapter, new ArrayList<Object>(yourArrayList));
adapter.notifyDataSetChanged();

AdapterHelper 类

public class AdapterHelper {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void update(ArrayAdapter arrayAdapter, ArrayList<Object> listOfObject){
        arrayAdapter.clear();
        for (Object object : listOfObject){
            arrayAdapter.add(object);
        }
    }
}

【讨论】:

  • 我的代码中有几个其他的 ArrayAdapter,它们可以正常工作。今晚,我决定将 SimpleCursorAdapter 变成 ArrayAdapter,但它不会工作。在挣扎了几个小时并试图找到它不起作用的原因之后,我找到了您的 AdapterHelper 类,现在它可以工作了!谢谢!
  • 这可以在函数中轻松完成...为什么要为它实例化一个新类?
  • 在 Java 中,函数被称为方法。您会提出什么建议,也许将这种高度可重用的方法与 Array Adapter 放在同一个类中?还是包含列表视图的片段/活动?所以是的,它在一个可以重用的类中。如果你想让它保持静态,请继续。
  • 好主意。另一种方法是扩展 ArrayAdapter,命名为 ArrayAdapterCompat 并覆盖 addAll(..) 方法,因为这个方法仅在 API 11 之后可用。在那里,检查 API 级别并使用 super.addAll(..) 表示 API > 11 和 super.add (..) 结合像你这样的迭代:if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.HONEYCOMB) { super.addAll(items); } else { for (Object o : collection) { super.add(o); } }。现在只需从您的新适配器类扩展。
  • 完美!非常感谢@Kevin - 这正是我所需要的!
【解决方案5】:

我知道这是一个较晚的响应,但我遇到了类似的问题,我设法通过在正确的位置使用 notifyDataSetChanged() 来解决它。

所以我的情况如下。

我必须使用从完全不同的活动返回的内容更新操作栏选项卡(片段)中的列表视图。然而,最初,列表视图不会反映任何更改。但是,当我单击另一个选项卡然后返回到所需的选项卡时,列表视图将使用来自其他活动的正确内容进行更新。所以为了解决这个问题,我在必须返回数据的活动代码中使用了操作栏适配器的notifyDataSetChanged()

这是我在活动中使用的代码 sn-p。

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) 
    {
        case R.id.action_new_forward:

            FragmentTab2.mListAdapter.notifyDataSetChanged();//this updates the adapter in my action bar tab
            Intent ina = new Intent(getApplicationContext(), MainActivity.class);
            ina.putExtra("stra", values1);
            startActivity(ina);// This is the code to start the parent activity of my action bar tab(fragment).
    }
}

此活动将向FragmentTab2 返回一些数据,并直接更新我在FragmentTab2 中的列表视图。

希望有人觉得这很有用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多