Array Adapter的notifyDataSetChanged()方法不起作用

6

我在这个问题上浪费了太多时间,不得不再次询问。我完全不知道为什么会发生这种情况。

我有一个数组适配器(aAdapter)和一个数组列表(aList),我试图放置一个清除按钮来擦除数据库中的条目并清除列表。

我的问题是,在我的onclick方法中NotifyDataSetChanged()根本无法起作用:

public void clearDB(View view) {
    aList.clear();
    aAdapter.notifyDataSetChanged();
    HighScoresDB hsdb = new HighScoresDB(HighScoresActivity.this);
    hsdb.openDB();
    hsdb.clearDB();
    hsdb.closeDB();

}

但是从其他地方都可以正常运行。我甚至尝试把 clear 和 notifyDataSetChanged() 放到另一个方法中并进行调用,但是这种方法也不起作用,但是在 onCreate 中调用时确实有效...

有什么想法吗?

附注:数据库已被清除。


ن½ ه°‌试è؟‡ن½؟用notifyDataSetInvalidated()而ن¸چوک¯notifyDataSetChanged()هگ—ï¼ں - edthethird
如果你有一个数据库,我强烈推荐使用CursorAdapter。它是神奇的!你不需要做notifyDataSetChanaged(),它会自动知道你已经对数据库进行了更改,并自行更新所有内容。 - MinceMan
5个回答

12

首先,我认为 Android 适配器实现有很大的缺陷。对于执行任何定制操作,似乎存在使用方式模糊不清的情况,而官方文档并没有澄清其中任何一个。如果我错了,我将非常高兴。

在编辑视图中的数据时,我获得一致结果的方法如下:

  • 所有对正在呈现的底层数据结构的更改都应该在 AsyncTask 中完成,这是有意义的,因为您正在 UI 线程上更改东西,不想出现并发问题。

  • 对底层数据结构的操作应通过调用适配器方法来执行,因此,如果您有一个 ListAdapter,那么可以使用 list adapter 的 add, removeclear。这意味着适配器管理视图通知等。这通常会导致需要创建自定义适配器,因为可用方法有限(甚至在 7 版本之前的 sdk 中都没有 add all)。您还最终使适配器充当一个大的 fat controller,尽管我知道我们不应将 Android 视为 MVC 模式,但仍然感觉不对。

  • 我创建了一些应用程序,在这些应用程序中,我绕过适配器调用以操作底层数据结构,并且它可以正常运行,尽管结果可能是不可预测的,除非您严密管理视图的通知。现在我只是通过适配器进行调用。

因此,虽然我不能解释为什么在您的 onClick 方法中 notifiyDataSetChanged 无法正常工作,但我提供的有用信息可能有助于您使应用程序按预期工作。


感谢您提供的所有信息,我一定会实现您的一些想法。不幸的是,这是一项大学作业,而且我要明天去度假了,所以我想我现在会尝试blindstuffs的建议。然而,在我提交作业之后,我将把它发布到市场上,所以在那之前我会尝试您的一些想法。 :) - A_Porcupine
2
我同意,whatsthebeef!我不再使用特定的“文档功能”,因为我不能保证它们始终起作用(即使提供了文档)。事实上,我以前也遇到过porcupine的问题,所以我甚至不再使用notifydatachanged()。:( 我只是制作自己的事件处理程序。真的很难过。此评论仅与Android适配器有关,而不是整个SDK - Fuzzical Logic

9

虽然不太美观,但您可以重新初始化适配器而不是通知它,我发现有时这是唯一使其工作的方法。


1
这也是我能让它自己清理的唯一方法。 - Aharon Manne
我发现重新初始化适配器是唯一有效的解决方案!谢谢 - Sahil
是的,今天也发生在我身上了。我有三种基于其他活动结果的方法,其中一种通知适配器不会产生任何作用。 - Paweł Poręba

2

我处理类似问题的方法是像blindstuff所说的那样重新初始化适配器。

    public class Example extends Activity{
        CustomAdapter adapter;
        ArrayList<ArrayList<String>> info = new ArrayList<ArrayList<String>>();
        final ListView list = (ListView) findViewById(R.id.listView_custom);
        adapter = new CustomAdapter(this, diceInfo.get(id));
        list.setAdapter(adapter);

然后在onclick监听器中

add.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                info.get(id).add("1,0,0,true");
                adapter = new CustomAdapter(Example.this, info.get(id));
                list.setAdapter(adapter);
            }
        });

这个例子没有初始化所有内容,但已经能够达到目的。我只需要创建一个新的适配器并将其设置到我的列表视图中。效果不错。


0

我猜这个帖子已经不再活跃了,但是为了以后的参考:

根据developer.android.com

[onNotifyDataSetChanged()] 通知已连接的观察者底层数据已更改,任何反映数据集的视图都应该刷新自己。

不要让适配器告诉视图刷新自己,只需使用adapter.clear()和adapter.add()更新数据,然后通过调用listView.setAdapter(adapter)强制ListView更新即可。


0

还遇到了适配器在对话框中的奇怪行为。 一旦适配器被更新(或底层结构 - 两种方式),并且notifyDataSetChanged对话框消失,没有错误或其他LogCat或Eclipse调试的痕迹。 完全相同的代码,一旦适配器应用于正常活动(ListView),就可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接