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】:对于ArrayAdapter
,notifyDataSetChanged
仅在您在适配器上使用add()
、insert()
、remove()
和clear()
时有效。
当ArrayAdapter
被构造时,它包含对传入的List
的引用。如果你要传入一个作为Activity 成员的List
,并稍后更改该Activity 成员, ArrayAdapter
仍然持有对原始 List
的引用。 Adapter 不知道你更改了 Activity 中的List
。
您的选择是:
-
使用
ArrayAdapter
的函数修改底层List(add()
、insert()
、remove()
、clear()
等)
使用新的List
数据重新创建ArrayAdapter
。 (使用大量资源和垃圾收集。)
创建您自己的派生自 BaseAdapter
和 ListAdapter
的类,允许更改底层 List
数据结构。
每次更新列表时使用notifyDataSetChanged()
。要在 UI 线程上调用它,请使用 Activity
的 runOnUiThread()
。
然后,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 >= 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