2012-03-06 31 views
5

Tôi đã đấu tranh với điều này một thời gian rồi. Trong dự án của tôi có một số hoạt động bao gồm một ListView và một bộ điều hợp mở rộng adapter tùy chỉnh. Họ cũng thực hiện một số giao diện thường thông báo rằng dữ liệu đã được thay đổi.Gọi BaseAdapter của Android thông báoDataSetChanged() từ phương thức gọi lại của người nghe

Tuy nhiên, khi tôi gọi notifyDataSetChanged() từ phương thức lắng nghe/giao diện được triển khai trong lớp, ListView không được cập nhật và không có phương thức bộ điều hợp nào được gọi (getCount(), getView()).

Tôi biết điều này có liên quan đến thực tế khi mà notificationDataSetChanged() được gọi, nghĩa là chuỗi nào, nhưng tôi không hiểu rõ và không thể tìm thấy giải thích đơn giản về hành vi này.

Như một giải pháp cho vấn đề này, tôi sử dụng Trình xử lý gọi phương thức theo định kỳ và trong phương pháp đó, tôi xem giá trị boolean 'needsToBeUpdated' có đúng không và sau đó tôi gọi phương thức notifyDataSetChanged(). Điều này là xấu xí, mặc dù, và tôi chắc chắn có cần phải là một cách để làm điều đó một cách không đồng bộ.

Mọi trợ giúp sẽ được đánh giá cao.

Pseudo-code về những gì tôi đang nói về:

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(); 
} 

EDIT: Tất nhiên nó đã cho tôi hầu như không có thời gian để tìm câu trả lời khi tôi đăng này đây ...

Tôi ghét để làm điều đó nhưng tôi nỗ lực hơn nữa để tìm kiếm câu trả lời và tôi nghĩ rằng tôi đã tìm thấy câu trả lời này: http://developer.android.com/resources/articles/painless-threading.html - và điều này: http://developer.android.com/reference/android/os/Handler.html

Giải pháp này rất đơn giản. Không thể thay đổi giao diện người dùng trong bất kỳ chuỗi nào khác nhưng chủ đề chính/giao diện người dùng. Đó là lý do tại sao thực hiện nó trong các phương thức gọi lại không hoạt động. Tuy nhiên, việc tạo Trình xử lý trong Chủ đề giao diện người dùng (ví dụ: trong phương thức onCreate()) kết nối nó với Giao diện người dùng và sau này có thể được sử dụng để đăng sự kiện lên chuỗi này.

mListUpdateHandler = new Handler(); 

Sau đó, một lớp bên trong việc thực hiện các giao diện Runnable là cần thiết nơi tinh chỉnh giao diện người dùng được thực hiện.

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

Cuối cùng, trong phương thức callback chúng tôi đăng các sự kiện với lớp UpdateListRunnable ra các chủ đề chính thông qua các Handler:

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

Nhờ đó các upadteLists() phương pháp được chạy trong thread UI và mọi thứ hoạt động như một sự quyến rũ.

Trả lời

0

Tôi đã gặp sự cố tương tự với đơn đăng ký của mình. Giải pháp đầu tiên là sử dụng Trình xử lý. Thanh lịch hơn là sử dụng Bộ tải - kiểm tra http://developer.android.com/guide/components/loaders.html! Gói tương thích cho các phiên bản Android cũ hơn cung cấp cho Android 1.6+

Các vấn đề liên quan