2013-06-03 40 views
6

Hãy để tôi bắt đầu bằng cách nói đây không phải là câu hỏi về việc cuộn ListView. Tôi không muốn biết cách người dùng cuộn xuống cuối danh sách, vì vậy, vui lòng không trả lời cho câu hỏi đó hoặc đánh dấu câu trả lời này là trùng lặp.Yêu cầu Android AsyncTaskLoader truy xuất thêm dữ liệu

Tôi đang sử dụng một lớp mở rộng AsyncTaskLoader để điền một ListView với dữ liệu từ một dịch vụ web.

Ban đầu, tôi tải 50 mục và mọi thứ đang hoạt động tuyệt vời. Tôi cần phải biết làm thế nào để nói cho các Loader để tải 50 mục tiếp theo tăng dần. Tôi hiểu WHERE để làm điều này trong mã ListView, nhưng Tôi không thể tìm ra cách tốt nhất để nói cho Trình tải mà tôi muốn tải thêm dữ liệu mà không cần đặt lại và tải lại mọi thứ.

Một lần nữa, để làm rõ, vấn đề tôi đang cố gắng giải quyết ở đây chỉ là thông báo cho bộ nạp rằng cần phải tải thêm dữ liệu. Nó đã biết cách tải thêm dữ liệu khi loadInBackground() được gọi là lần thứ hai và ListView đã biết vị trí/khi nào cần thông báo cho Trình tải, câu hỏi chỉ là cách.

Một số mã có liên quan:

@Override 
public void onActivityCreated(Bundle savedInstanceState) 
{ 
    super.onActivityCreated(savedInstanceState); 

    m_adapter = new SearchAdapter(getActivity()); 
    setListAdapter(m_adapter); 

    // if the loader doesn't already exist, one will be created 
    // otherwise the existing loader is reused so we don't have 
    // to worry about orientation and other configuration changes 
    getLoaderManager().initLoader(SEARCH_LOADER_ID, null, this); 
} 

@Override 
public Loader<List<Result>> onCreateLoader(int id, Bundle args) 
{ 
    String query = args != null ? args.getString(QUERY_KEY) : ""; 
    return new SearchLoader(getActivity(), query); 
} 

private class SearchAdapter extends ArrayAdapter<Result> 
{ 
    // ... 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 

     // ... 

     if (position == getCount() - 2) 
      // TODO: Need to notify Loader here 

     // ... 
    } 
} 

private static class SearchLoader extends OurAsyncTaskLoader<List<Result>> 
{ 
    public SearchLoader(Context context, String query) 
    { 
     super(context); 

     m_query = query; 
     m_data = Lists.newArrayList(); 
     m_loadedAllResults = false; 
    } 

    @Override 
    public List<Result> loadInBackground() 
    { 
     if (m_loadedAllResults) 
      return m_data; 

     // the Loader implementation does a == check rather than a .equals() check 
     // on the data, so we need this to be a new List so that it will know we have 
     // new data 
     m_data = Lists.newArrayList(m_data); 

     MyWebService service = new MyWebService(); 
     List<Result> results = service.getResults(m_query, m_data.size(), COUNT); 
     service.close(); 

     if (results == null) 
      return null; 

     if (results.size() < COUNT) 
      m_loadedAllResults = true; 

     for (Result result : results) 
      m_data.add(result) 

     return m_data; 
    } 

    private static final int COUNT = 50; 

    private final String m_query; 

    private boolean m_loadedAllResults; 
    private List<Result> m_data; 
} 
+0

@GeorgeStocker Vui lòng đọc câu hỏi này. Bạn sẽ thấy rằng nó KHÔNG phải là một bản sao của câu hỏi mà bạn đã liệt kê. – drewhannay

+0

Cần thêm dữ liệu cho cùng một chuỗi truy vấn? Dù sao tôi sẽ thả 'Loader' và sử dụng một' AsyncTask' hoặc một luồng bình thường để tải dữ liệu bổ sung. – Luksprog

+1

Nhưng không phải là một Trình tải theo cách được khuyến nghị để cung cấp dữ liệu để quay trở lại một ListView? AsyncTask không xử lý các thay đổi cấu hình và Trình tải làm. – drewhannay

Trả lời

3

tôi đã tìm ra một cách mà làm việc. Trong phương pháp SearchAdapter#getView() tôi, tôi có đoạn mã sau:

private class SearchAdapter extends ArrayAdapter<Result> 
{ 
    // ... 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 

     // ... 

     if (position == getCount() - 2) 
      getLoaderManager().getLoader(SEARCH_LOADER_ID).onContentChanged(); 
     // ... 
    } 
} 

tôi vẫn muốn biết nếu điều này là "thực hành tốt nhất" cách làm việc đó, nhưng có vẻ như để giải quyết vấn đề của tôi bây giờ.

+0

cách bạn getLoaderManager() từ Bộ điều hợp của bạn? – raybaybay

+0

Bộ điều hợp của tôi là một lớp bên trong bên trong Mảnh vỡ của tôi – drewhannay

+0

Các giải pháp tốt nhất là đơn giản nhất – Bwire

0

Trong trường hợp của bạn, tôi sẽ khuyên bạn nên sử dụng ForceLoadContentObserver mà bạn có thể liên kết với một URI với ContentResolver. Như thế này:

class SearchLoader .... 
    ForceLoadContentObserver contentObserver = new ForceLoadContentObserver(); 
    .... 

    @Override 
    public void onStartLoading() { 
     if (cacheResult == null || takeContentChanged()) { // This will see if there's a change notification to observer and take it. 
      onForceLoad(); 
     } else { 
      deliverResult(cacheResult); 
     } 
    } 

    @Override 
    public Result loadInBackground() { 
     Result result = loadResult(); 
     // notification uri built upon Result.BASE_URI so it receives all notifications to BASE_URI. 
     getContext().getContentResolver().registerContentObserver(result.getNotificationUri(), true, contentObserver); 
    } 

    @Override 
    public void onReset() { 
     // ... Do your clean stuff... 
     getContext().getContentResolver().unregisterContentObserver(contentObserver); 
    } 

    ... 
} 

Vì vậy, bạn có thể thông báo thay đổi của bạn ở khắp mọi nơi bằng cách sử dụng:

context.getContentResolver().notifyChanged(Result.BASE_URI, null); 

Ngay cả khi hoạt động giữ loader là ở chế độ nền hoặc không thể deliverResult. Và bạn không cần phải có được trường hợp của trình tải.

Tất cả thông báo là xung quanh Uri của đối tượng. Uri là một đại diện mạnh mẽ của dữ liệu trong Android.

Nhưng tôi cũng có sự nhầm lẫn của mình. Trong trường hợp này, cả phương pháp tiếp cận của bạn và phương pháp tiếp cận của tôi giả định thay đổi nội dung có nghĩa là tải thêm dữ liệu. Nhưng nếu bạn cần tải lại tất cả dữ liệu thì sao? Bạn sẽ sử dụng loại thông báo nào?

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