2012-01-10 67 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(適配器)來更新一次。

相關問題