notifyDataSetChanged 示例

Posted

技术标签:

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

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

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

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

【问题讨论】:

***.com/questions/14503006/… 你可以检查这个blog和这个example in github和this as well 【参考方案1】:

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

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

您的选择是:

    使用ArrayAdapter的函数修改底层List(add()insert()remove()clear()等) 使用新的List 数据重新创建ArrayAdapter。 (使用大量资源和垃圾收集。) 创建您自己的派生自 BaseAdapterListAdapter 的类,允许更改底层 List 数据结构。 每次更新列表时使用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();
    
);

【讨论】:

我试图在 onCreate-method 的代码中添加你的代码片段(你可以在这里找到它***.com/questions/3667442/how-to-refresh-adapter),但我仍然没有任何成功:( 可能是错的添加它的地方?! 您的问题只是询问如何调用该方法并让它在主 UI 线程中运行。这回答了这个问题。在您的特定情况下 (***.com/questions/3670500/…) AsyncTask 及其 onPostExecute() 方法似乎是您应该考虑的。【参考方案3】:

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

请关注How to correctly implement BaseAdapter.notifyDataSetChanged() in Android或the 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 中的列表视图。

希望有人觉得这很有用!

【讨论】:

以上是关于notifyDataSetChanged 示例的主要内容,如果未能解决你的问题,请参考以下文章

ArrayAdapter.NotifyDataSetChanged() 不工作?

[完成]notifyDataSetChanged() 不会自动更新 ListActivity

notifyDataSetChanged() 上的 WinDeath

安卓:notifyDataSetChanged();不工作

在 customAdapter.notifyDataSetChanged 之后 ListView 不更新

Android notifyDataSetChanged