2012-03-06 85 views
5

我一直在爲此奮鬥一段時間。在我的項目中有幾個活動包括一個ListView和一個擴展BaseAdapter的自定義適配器。他們還實現了一些通常會告訴它數據已經改變的接口。但是,當我從我的類中實現的偵聽器/接口方法調用notifyDataSetChanged()時,ListView不會更新,並且不會調用任何適配器方法(getCount(),getView())。我知道這與notifyDataSetChanged()被調用的事實有關,我的意思是哪個線程,但我不太瞭解它,並找不到這種行爲的直接解釋。從偵聽器回調方法調用Android的BaseAdapter notifyDataSetChanged()

作爲這個問題的解決方法,我使用了一個Handler,它週期性地調用一個方法,並且在那個方法中,我看看布爾值'needsToBeUpdated'的值是否爲真,然後我調用notifyDataSetChanged()方法。不過,這很醜陋,我相信需要有一種方法可以異步執行。

任何幫助,將不勝感激。

public class FriendsActivity extends Activity implements FriendsListener { 
private ListView mListView; 
private ArrayList<Friends> mFriendsList; 
private FriendsAdapter mFriendsAdapter; 
private boolean mNeedsToBeUpdated; 
private Handler mListUpdateHandler; 
private Runnable mListUpdateTask; 

onCreate() { 
    initViews(); 
    mFriendsAdapter = new FriendsAdapter(mFriendsList); 
    mListView.setAdapter(mFriendsAdapter); 
    SomeStaticClass.addFriendListener(this) 

    mNeedsToBeUpdated = false; 

    mListUpdateHandler = new Handler(); 
    mListUpdateHandler.removeCallbacks(mListUpdateTask); 
    mListUpdateHandler.postDelayed(mListUpdateTask, 10000); 

} 

onListenerMethod() { 
    updateFriendsList(); 
    mFriendsAdapter.updateDataSource(mFriendsList); 
    mFriendsAdapter.notifyDataSetChanged(); // THIS DOESN'T UPDATE THE VIEWS 
    mNeedsToBeUpdated = true; 
} 

protected void onResume() { 
    mListUpdateTask = new Runnable() { 
     public void run() { 
      if (mNeedsToBeUpdated) { 
       updateFriendsList(); 
       mFriendsAdapter.updateDataSource(mFriendsList); 
       mFriendsAdapter.notifyDataSetChanged(); // THIS UPDATES THE VIEWS 
       mListsRequireUpdating = false; 
      } 
      mListUpdateHandler.postDelayed(mListUpdateTask, 10000); 
     } 
    }; 
    mListUpdateHandler = new Handler(); 
    mListUpdateHandler.removeCallbacks(mListUpdateTask); 
    mListUpdateHandler.post(mListUpdateTask); 
    super.onResume(); 
} 

編輯:什麼我談論的

僞代碼。當然,我花了幾乎沒有時間去尋找答案,一旦我張貼了這個在這裏...

我恨做到這一點,但我多放些精力來尋找一個答案,我想我發現它得益於此:http://developer.android.com/resources/articles/painless-threading.html - 這:http://developer.android.com/reference/android/os/Handler.html

的解決方案是痛苦的簡單。除了主/ UI線程之外,不可能在任何其他線程中更改UI。這就是爲什麼在回調方法中不起作用的原因。然而,在用戶界面線程中創建一個處理程序(例如在onCreate()方法中)將其連接到UI線程,稍後可用於將事件發佈到該線程。

mListUpdateHandler = new Handler(); 

然後,在完成UI調整的情況下,需要實現Runnable接口的內部類。

class UpdateListRunnable implements Runnable { 
     @Override 
     public void run() { 
      Log.i(LOGTAG, "UpdateListRunnable"); 
      FriendsActivity.this.updateLists();    
     } 
    } 

最後,在回調方法中,我們通過處理程序後與出UpdateListRunnable類的事件,主線程:到了upadteLists()方法是在UI線程中運行

@Override 
    public void entriesUpdated(Collection<String> entries) { 
     Log.i(LOGTAG, "entriesUpdated"); 
     for (String entry : entries) { 
      Log.i(LOGTAG, "entry: " + entry); 
     } 
     mListUpdateHandler.post(new UpdateListRunnable()); 
    } 

謝謝一切都像魅力一樣。

回答

相關問題