2013-06-03 4 views
6

मुझे यह कहकर शुरू करना है कि यह सूची दृश्यों को स्क्रॉल करने के बारे में कोई प्रश्न नहीं है। मैं नहीं जानना चाहता हूं कि कोई उपयोगकर्ता किसी सूची के नीचे स्क्रॉल करता है, तो कृपया मुझे उस प्रश्न के उत्तर न दें, या इसे डुप्लिकेट के रूप में चिह्नित करें।अधिक डेटा पुनर्प्राप्त करने के लिए एंड्रॉइड AsyncTaskLoader को बताएं

मैं एक ऐसी कक्षा का उपयोग कर रहा हूं जो एक वेब सेवा से डेटा के साथ ListView को पॉप्युलेट करने के लिए AsyncTaskLoader को विस्तारित करता है।

प्रारंभ में, मैं 50 आइटम लोड करता हूं और सबकुछ बढ़िया काम कर रहा है। मुझे यह जानने की जरूरत है कि लोडर को अगले 50 आइटमों को बढ़ाने के लिए कैसे बताना है। मैं समझता हूं कि ListView कोड में ऐसा करने के लिए, लेकिन मैं लोडर को बताने का सबसे अच्छा तरीका नहीं समझ सकता कि मैं इसे रीसेट किए बिना और फिर से लोड किए बिना अधिक डेटा लोड करना चाहता हूं।

फिर से, स्पष्ट करने के लिए, जिस मुद्दे को मैं हल करने की कोशिश कर रहा हूं वह सिर्फ लोडर को सूचित कर रहा है कि अधिक डेटा लोड होने की आवश्यकता है। यह पहले से ही जानता है कि loadInBackground() को दूसरी बार कॉल करने पर अधिक डेटा कैसे लोड किया जाए, और ListView पहले से ही जानता है कि लोडर को कब/कब सूचित किया जाए, प्रश्न केवल है

प्रासंगिक कोड में से कुछ:

@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

@ जॉर्जस्टॉकर कृपया इस प्रश्न को पढ़ें। आप देखेंगे कि यह आपके द्वारा सूचीबद्ध प्रश्न का डुप्लिकेट नहीं है। – drewhannay

+0

एक ही क्वेरी स्ट्रिंग के लिए अधिक डेटा लोड करने की आवश्यकता है? वैसे भी मैं 'लोडर' को छोड़ दूंगा और अतिरिक्त डेटा लोड करने के लिए 'AsyncTask' या सामान्य थ्रेड का उपयोग करूंगा। – Luksprog

+1

लेकिन एक लोडर नहीं है जो सूची दृश्य को वापस करने के लिए डेटा प्रदान करने के लिए अनुशंसित तरीका है? एक AsyncTask कॉन्फ़िगरेशन परिवर्तनों को संभाल नहीं करता है, और लोडर करते हैं। – drewhannay

उत्तर

3

मैं एक तरीका है कि काम करता है पता लगा। मेरी SearchAdapter#getView() विधि में, मैं निम्नलिखित कोड है:

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

मैं अभी भी अगर यह "सबसे अच्छा अभ्यास" यह ऐसा करने का तरीका है जानना चाहते हैं, लेकिन यह अभी के लिए मेरी समस्या का समाधान करने लगता है।

+0

आप अपने एडाप्टर से LoaderManager() कैसे प्राप्त करते हैं? – raybaybay

+0

मेरा एडाप्टर मेरे टुकड़े के अंदर एक आंतरिक वर्ग है – drewhannay

+0

सर्वोत्तम समाधान सबसे सरल हैं – Bwire

0

आपके परिदृश्य में मैं आपको ForceLoadContentObserver का उपयोग करने की सलाह दूंगा जिसे आप सामग्री आरसोलवर के लिए यूआरआई से जोड़ सकते हैं। इस तरह:

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

    ... 
} 

तो आप अपने परिवर्तन हर जगह उपयोग करके हमें सूचित कर सकते हैं:

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

यहां तक ​​कि जब गतिविधि लोडर पकड़े पृष्ठभूमि में deliverResult करना संभव नहीं है या। और आपको लोडर्स के उदाहरण प्राप्त करने की आवश्यकता नहीं है।

सभी अधिसूचना ऑब्जेक्ट के उरी के आसपास है। उरी एंड्रॉइड में डेटा का एक शक्तिशाली प्रतिनिधित्व है।

लेकिन मुझे भी मेरा भ्रम है। इस परिदृश्य में, आपके दृष्टिकोण और मेरे दृष्टिकोण दोनों मानते हैं एक सामग्री परिवर्तन का मतलब है अधिक डेटा लोड करना। लेकिन अगर आपको सभी डेटा पुनः लोड करने की आवश्यकता है तो क्या होगा? आप किस तरह की अधिसूचना का उपयोग करेंगे?

संबंधित मुद्दे