notifyDataSetChanged示例


166

我正在尝试在自己Android ApplicationnotifyDataSetChanged()方法中使用,ArrayAdapter但对我来说不起作用。

我在这里找到答案notifyDataSetChanged()应该在主线程中运行,但是没有示例。

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



您可以在github上查看此博客和此示例,以及这些内容
Cabezas

Answers:


328

对于ArrayAdapternotifyDataSetChanged只有当你使用的作品add()insert()remove(),和clear()在适配器。

当一个ArrayAdapter构造,它保存了参考List中传递。如果你是在一个传递List,这是一个活动中的一员,并更改活动成员后,ArrayAdapter仍持原来的一个参考List。适配器不知道您List在“活动” 中进行了更改。

您的选择是:

  1. 使用的功能ArrayAdapter修改底层列表(add()insert()remove()clear(),等等)
  2. ArrayAdapter用新List数据重新创建。(使用大量资源和垃圾回收。)
  3. 创建自己的类衍生BaseAdapterListAdapter允许潜在的改变List数据结构。
  4. notifyDataSetChanged()每次更新列表时使用。要调用它的UI线程,使用runOnUiThread()Activity。然后,notifyDataSetChanged()将工作。

13
还要为数据分配“新”对象也要小心。使用clear()代替,重新填充/更改数据,然后调用notifyDataSetChanged()
moonlightcheese

但是,如果我们所说的notifyDataSetChanged()以这种方式:((BaseAdapter) arrayAdapter).notifyDataSetChanged();
teoREtik 2012年

2
我使用BaseExpandableListAdapter,它没有add()或remove()函数,因此我将Map存储为成员变量。我更新Map并调用notifyDatasetChanged(),但没有任何反应。当我使用选择#4时,它可以工作。为什么???
emeraldhieu 2012年

我将ArrayAdapter用于自定义GridView,我通过调用adapter.add(dataReceived)从URL获取图像时添加图像。这可以很好地添加数据,但是为什么会刷新和显示顶部。我要显示项目,因为它们将添加而不刷新列表。(要做的是使用notifyDatasetChanged()使用android的GridView。)如何使它在此customGridView(StaggeredGridView)中工作。
MobileEvangelist

1
我尝试创建自己的BaseAdapter来向列表添加排序方法,但是由于某种原因,它根本无法正常工作。即使我使用排序后的arraylist重新创建了整个适配器,也并不是我的应用程序运行缓慢,但这仍然让我感到烦恼。究竟会产生多少垃圾呢?我假设在调用适配器的活动中保留了昂贵数据的实际数组作为参考,这意味着仅收集适配器。
2014年

34

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

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

1
我试图在onCreate方法中将您的代码片段添加到我的代码中(您可以在这里stackoverflow.com/questions/3667442/how-to-refresh-adapter上找到它),但是我仍然没有任何成功:(也许添加它的位置不对
Tima 2010年

1
您的问题只是问您如何调用该方法并使其在主UI线程中运行。这回答了这个问题。在您的特殊情况下(stackoverflow.com/questions/3670500/…),您应该考虑AsyncTask及其onPostExecute()方法。
Brian

12

我最近写了关于这个主题的文章,尽管这篇文章过时了,但我认为这对希望了解如何BaseAdapter.notifyDataSetChanged()逐步正确地实施的人会有所帮助。

请遵循如何在Android较新的博客BaseAdapter.notifyDataSetChanged()中正确实现BaseAdapter.notifyDataSetChanged()的方法


嗨,我尝试了第一个链接示例,但是代替了mItem.add(),我只是编辑了一个元素,这mItem.get(position).setImage(encodedImage)可能就是为什么这给了NullPointer exeption错误。所以notifyDataSetChange只是在编辑它,在上面提到的Array适配器的bcz是这样工作的仅用于add(),clear(),remove()等
Shreekant N

notifyDataSetChanged将用于编辑或修改数据集,您的空指针是由于其他原因,请检查日志。
Arif Nadeem

7

我遇到了同样的问题,我不希望用新实例连续替换整个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);
        }
    }
}

我的代码中还有其他几个ArrayAdapters,它们工作正常。今晚,我决定将SimpleCursorAdapter变成ArrayAdapter,它将无法正常工作。经过几个小时的苦苦挣扎,并试图找到它不起作用的原因之后,我找到了您的AdapterHelper类,并且现在可以工作了!谢谢!
自豪geekdad

1
这可以在一个函数中轻松完成...为什么要为此实例一个新类?
techiServices 2012年

2
在Java中,函数称为方法。您会提出什么建议,在与Array Adapter相同的类中使用这种高度可重用的方法?还是包含列表视图的片段/活动?是的,它在可以重用的类中。如果您要使其完全静态,请继续。
凯文·帕克

1
好主意。另一种方法是扩展名为ArrayAdapterCompat的ArrayAdapter并重写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); } }。现在,从新的适配器类扩展。
Konsumierer 2012年

完善!非常感谢@Kevin-这正是我所需要的!
基比

3

我知道这是一个较晚的答复,但我遇到了类似的问题,因此设法notifyDataSetChanged()在正确的地方使用来解决此问题。

所以我的情况如下。

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

这是我在活动中使用的代码片段。

@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并将直接更新中的listview FragmentTab2

希望有人觉得这有用!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.