2012-01-10 94 views
6

我一直在浪费太多的时间在这个,所以不得不再次问。我不知道为什么这会发生。数组适配器notifyDataSetChanged()将不起作用

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

我的问题是NotifyDataSetChanged()从我的点击数的方法在这里里面只是不会工作:

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

} 

它从其他地方,虽然工作。我甚至试图把清除和notifyDataSetChanged()在另一种方法,并调用它,但也不起作用,但是,当我从onCreate调用它时,工作。

任何想法?

p.s.数据库正在清除。

+0

你试过'notifyDataSetInvalidated()'而不是'notifyDataSetChanged()'吗? – edthethird 2012-06-08 02:16:23

+0

如果你有一个数据库,我强烈建议使用CursorAdapter。这是神奇的!你不必做notifyDataSetChanaged()它只会知道你已经对数据库进行了改变并且自己进行了全部更新。 – MinceMan 2013-09-06 23:02:12

回答

12

首先,我发现Android适配器的实现非常有缺陷。当谈到执行任何定制的事情时,似乎有关于如何使用它的含糊不清的说明,官方文档没有澄清其中的任何内容。我很乐意被证明是错误的。

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

  • 被提出应在AsyncTask这是有道理的,你是改变事物做的所有改变底层数据结构在UI线程上,不想有并发问题。对底层数据结构

  • 的操作应该通过调用适配器方法,所以如果你有一个ListAdapter,那么你使用addremove和列表适配器clear进行。这意味着适配器管理视图通知等。这通常会导致必须创建自定义适配器,因为可用的方法有限(甚至没有在7之前的sdk版本中添加所有)。您最终还是会以您的适配器作为大fat controller,尽管我知道我们不应该将android视为MVC模式,但它仍然看起来错了。

  • 我已经创建了一些应用程序,我绕过适配器调用来操作底层数据结构,并且它的全部结果都无法预测,除非您将通知严格管理到视图。现在我只需通过适配器调用。

所以,虽然我不能够解释,为什么在notifiyDataSetChanged不会在你的onClick方法具体工作。我希望能够提供有用的信息,这可能有助于您的应用按预期工作。

+0

感谢所有的信息,我一定会实现你的一些想法。不幸的是,这是一个单一的任务,因为我明天要去度假,所以我没时间了,所以我想我现在会尝试盲目的建议。 但是,我将这件作品发布到市场上之后,我会在此之前尝试一些您的想法。 :) – 2012-01-10 18:26:46

+2

我同意,whatsthebeef!我甚至不再使用特定的“记录功能”,因为我无法保证它们始终工作(即使提供了文档)。实际上,我之前遇到过豪猪的问题,我甚至不再使用notifydatachanged()。 :(我只是做自己的事件处理程序,真的很伤心,**这个评论特别涉及Android适配器,而不是整个SDK ** – 2012-01-10 21:22:59

9

虽然不太好,但您可以重新初始化适配器而不是通知它,我曾经看到有时它是使其工作的唯一方法。

+0

我会试试这个,谢谢。 :) – 2012-01-10 18:27:38

+1

这也是我可以让它自行清洁的唯一方法。 – 2014-10-23 13:25:41

+0

我发现重新初始化适配器是唯一可行的解​​决方案!谢谢 – Sahil 2015-12-05 14:45:24

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

在对话框中使用时,也会遇到Adapter的奇怪行为。 一旦适配器更新(或底层结构 - 两种方式)和notifiyDataSetChanged对话框消失没有错误或LogCat中的其他跟踪或调试的Eclipse。 完全相同的代码,一旦适配器应用于正常活动(ListView)就行得通。

0

我想这线程处于非活动状态了,但以供将来参考:

根据developer.android.com

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

而不是由适配器告诉视图更新自身,只是用adapter.clear()和adapter.add()更新数据,然后强制ListView控件调用listView.setAdapter(适配器)来更新一次。

相关问题