2011-08-28 35 views
10

Trong Tổ ong, các API Loader được giới thiệu là cách thích hợp để cung cấp dữ liệu cho một ứng dụng bằng cách thực hiện việc nâng hạng nặng trên một sợi nền. Trong đơn đăng ký của tôi, tôi đang làm việc để thay thế tất cả các Cursor s của mình bằng Loader s trả về Cursor s. Kể từ khi Cursor.requery() bị khấu hao ngay bây giờ, bạn nên gọi restartLoader và cho phép công việc được thực hiện lại trên một sợi nền và sau đó changeCursor khi nó trả về trong onLoadFinished.Làm thế nào để duy trì vị trí ListView khi sử dụng API trình tải mới?

Tất cả điều này hoạt động tuyệt vời ngoại trừ ListView không duy trì vị trí cuộn khi tôi muốn requery dữ liệu, sử dụng Cursor.requery() được sử dụng để làm việc vì nó là cùng một bản sao con trỏ với dữ liệu cập nhật.

Làm cách nào để làm mới Trình tải của tôi mà không mất vị trí cuộn?

+0

Bạn có thể sử dụng 'getScrollX() 'và' getScrollY() 'để lưu nó trước khi bạn làm mới, và sau đó tự thiết lập lại nó. Tôi không chắc chắn nếu điều này sẽ dẫn đến hình ảnh nhấp nháy hoặc khó chịu khác. : - / –

Trả lời

6

Bản thân lớp Loader không biết khi nào tập dữ liệu thay đổi và hiện đang triển khai cụ thể cho CursorLoader. Bây giờ, bên trong ứng dụng của tôi, dữ liệu mà tôi cần làm là bên trong một cơ sở dữ liệu SQLite cục bộ (không có ContentProvider), vì vậy tôi phải sửa đổi CursorLoader để sử dụng cơ sở dữ liệu cục bộ của mình thay vì Dianne Hackborne được đề cập trên developer group.

Đáng tiếc là chỉ trả về một con trỏ từ loadInBackground không cho phép ContentObserver thông báo đúng Loader khi thay đổi dữ liệu, điều này là do AbstractCursor chỉ gọi notifyChanged() khi requery() được gọi là trên con trỏ.

Kể từ khi ContentObserver sẽ không bao giờ thông báo cho Loader rằng dữ liệu đã thay đổi, tôi đã tự động gọi số Loader.onContentChanged() khi cần. Tại thời điểm này, mọi thứ dường như đang hoạt động nhưng tôi sẽ cập nhật câu trả lời này nếu có bất kỳ vấn đề quan trọng nào xảy ra.

0

Bạn chỉ cần không tạo bộ điều hợp mới trong mỗi Tải bộ nạp; Ý tôi là ..

@Override 
    public void onLoadFinished(Loader<List<NotificationItem>> loader, List<NotificationItem> notifications) { 
     // We must do it in this way to not losing listview scroll position after a reload. 
     if(mAdapter==null) { 
      mAdapter = new HomeUserActivityListAdapter(getActivity(), notifications); 
      mListView.setAdapter(mAdapter); 

     }else{ 
      mAdapter.refill(notifications); 
     } 
    } 

Và trong bạn bị tiếp hợp tạo ra một phương pháp để mục nạp

public void refill(List<NotificationItem> notifications) { 
    mNotificationsList.clear(); 
    mNotificationsList.addAll(notifications); 
    notifyDataSetChanged(); 
} 

Và đó là tất cả, nó sẽ duy trì vị trí di chuyển của bạn chính xác :-)

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