11

मेरे पास एक ऐसी गतिविधि है जो लोडर कॉलबैक का उपयोग कर सर्वर से डेटा सूची लोड करती है। मैं एक टुकड़ा जो फैलीऑनलोड से खंड को प्रतिबद्ध करें गतिविधि के भीतर परिभाषित

SherlockListFragment 

मैं

Fragment newFragment = CategoryFragment.newInstance(mStackLevel,categoryList); 
FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
ft.add(R.id.simple_fragment, newFragment).commit(); 
onLoadFinished में

का उपयोग कर टुकड़ा प्रतिबद्ध करने के लिए करने की कोशिश की में डेटा की सूची के लिए है और यह एक IllegalStateException कह

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished 

मेरे पास है देता है एक्शनबार शेरलॉक में उदाहरण का उल्लेख किया गया है, लेकिन उन उदाहरणों में टुकड़े के भीतर लोडर हैं, न कि गतिविधि।

क्या कोई मुझे इस के साथ मदद कर सकता है कि मैं लोडर को टुकड़े से बुलाए बिना इसे ठीक कर सकता हूं!

+0

के संभावित डुप्लिकेट [एंड्रॉयड - FragmentActivity + लोडर का उपयोग कर अद्यतन करने के लिए FragmentStatePagerAdapter समस्याओं] (http://stackoverflow.com/questions/7746140/android-problems-using-fragmentactivity-loader- टू-अपडेट-फ्रैगमेंटस्टेटपेगेरा) – rds

उत्तर

14

अटलास्ट, मुझे इस समस्या का समाधान मिला है। एक खाली संदेश सेट करने वाला एक हैंडल बनाएं और उस हैंडलर को लोड करेंफिनिश() पर कॉल करें। कोड इसी के समान है।

@Override 
public void onLoadFinished(Loader<List<Station>> arg0, List<Station> arg1) { 
    // do other actions 
    handler.sendEmptyMessage(2); 
} 

हैंडलर में,

private Handler handler = new Handler() { // handler for commiting fragment after data is loaded 
    @Override 
    public void handleMessage(Message msg) { 
     if(msg.what == 2) { 
      Log.d(TAG, "onload finished : handler called. setting the fragment."); 
      // commit the fragment 
     } 
    } 
}; 

टुकड़े की संख्या की आवश्यकता पर निर्भर करते हैं।

This method can be mainly used in case of stackFragments, where all fragments have different related functions. 
+1

हम्म मैं इसके खिलाफ सलाह दूंगा। यदि आपको वास्तव में टुकड़ों को ढेर करने की आवश्यकता है, तो आप केवल प्रतिबद्धता कॉलिंगस्टॉस लॉस() को कॉल कर सकते हैं। यह हैंडलर और IllegalArgumentException से बच जाएगा क्योंकि आप मंच को बता रहे होंगे .. "ठीक है, मुझे जोखिमों से अवगत है .. वैसे भी करें"। देखें [लिंक] (https://developer.android.com/reference/android/support/v4/app/FragmentTransaction.html#commitAllowingStateLoss()) – kwazi

+0

धन्यवाद kwazi, मैंने उस विधि को आजमाया था। आपकी सहायता के लिए धन्यवाद. यह एक अच्छी सलाह थी। चीयर्स :) – DroidBee

+4

बस एक नोट: कॉलिंग commit AllowStateLoss DialogFragment.show() को कॉल करते समय एक विकल्प नहीं है। मुझे उस विशेष प्रकार के टुकड़े लेनदेन के लिए एक हैंडलर का उपयोग करना पड़ा। – javahead76

8

विधि onLoadFinished() पर Android डॉक्स के अनुसार:

ध्यान दें कि सामान्य रूप से एक आवेदन के बाद से यह बाद एक गतिविधि के राज्य सहेजा जाता है हो सकता है, टुकड़ा लेनदेन प्रतिबद्ध करने के लिए है, जबकि इस कॉल में अनुमति नहीं है। इस पर और चर्चा के लिए FragmentManager.openTransaction() देखें।

https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html#onLoadFinished(android.content.Loader, D)

(नोट: कॉपी/पेस्ट कि अपने ब्राउज़र में लिंक ... StackOverflow यह अच्छी तरह से निपटने नहीं है ..)

तो आप बस उस में एक टुकड़ा लोड कभी नहीं करना चाहिए राज्य। यदि आप वास्तव में लोडर को फ्रैगमेंट में नहीं रखना चाहते हैं, तो आपको गतिविधि की अपनी ऑनक्रेट() विधि में खंड को प्रारंभ करने की आवश्यकता है, और फिर जब ऑनलोड लोड होता है, तो बस अपने टुकड़े पर एक विधि कॉल करें।

कुछ किसी न किसी छद्म कोड इस प्रकार है:

public class DummyFragment { 

    public void setData(Object someObject) { 
      //do stuff 
    } 

public class DummyActivity extends LoaderCallbacks<Object> { 

    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      Fragment newFragment = DummyFragment.newInstance(); 
      FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
      ft.add(R.id.simple_fragment, newFragment).commit(); 

      getSupportLoaderManager.initLoader(0, null, this) 
    } 

    // put your other LoaderCallbacks here... onCreateLoader() and onLoaderReset() 

    public void onLoadFinished(Loader<Object> loader, Object result) { 
      Fragment f = getSupportLoaderManager.findFragmentById(R.id.simple_fragment); 
      f.setData(result); 
    } 

जाहिर है, आप सही वस्तु .. और सही लोडर का उपयोग करना चाहते हैं, और शायद अपने टुकड़ा अद्यतन करने के लिए एक उपयोगी setData() विधि को परिभाषित । लेकिन उम्मीद है कि यह आपको सही दिशा में इंगित करेगा।

+0

आपके उत्तर के लिए धन्यवाद! :) शायद मैं अपने प्रश्न के बारे में स्पष्ट नहीं था। मेरे पास पहले से ही मेरा होमफ्रैगमेंट केंद्रित है, बस कुछ डेटा लोड करने पर, अगले खंड की ढेर को लागू करना चाहता था। मुझे इसे लागू करने के लिए एक विधि मिली। मैं इसे एक उत्तर के रूप में पोस्ट करूंगा। आपके समर्थन और उत्तर के लिए +1। मैंने वास्तव में f.setData (परिणाम) का उपयोग करने के बारे में सोचा नहीं था जिसे मैं अन्य टुकड़ों के भीतर एक ही गतिविधि में इस्तेमाल कर सकता था। :) – DroidBee

+0

आह, मुझे पता नहीं था। किसी भी बेहतर समाधान के संबंध में आपके उत्तर पर मेरी टिप्पणी देखें। commitAllowingStateLoss() जाने का रास्ता होगा ... – kwazi

0

रूप @kwazi जवाब इस onLoadFinished() से FragmentTransition.commit() कॉल करने के लिए एक खराब उपयोगकर्ता अनुभव है। मुझे प्रोग्रेसडिअलॉग का उपयोग करके इस घटना का समाधान मिला है।

पहले getLoaderManager().restartLoader() से पहले onLoadFinished(). इसके अलावा मुझे क्या progressDialog.show() देखने के लिए ProgressDialog.setOnDismissListener(new listener) बनाया। और अंत में progressDialog.dismiss()onLoadFinished() में रखें। इस तरह के दृष्टिकोण मुख्य यूआई थ्रेड और लोडर के थ्रेड को बाध्य नहीं करते हैं।

public class FrPersonsListAnswer extends Fragment 
 
\t \t \t \t \t \t implements 
 
\t \t \t \t \t \t LoaderCallbacks<Cursor>{ 
 
private ProgressDialog progressDialog; 
 
           \t @Override 
 
\t public View onCreateView(LayoutInflater inflater, 
 
\t \t \t ViewGroup container, Bundle savedInstanceState) { 
 
\t \t View view = inflater.inflate(R.layout.fragment_persons_list, container, false); 
 
\t \t 
 
\t \t //prepare progress Dialog 
 
\t \t progressDialog = new ProgressDialog(curActivity); 
 
\t \t progressDialog.setMessage("Wait..."); 
 
\t \t progressDialog.setIndeterminate(true); 
 
\t \t progressDialog.setOnDismissListener(new OnDismissListener() { 
 
\t \t \t 
 
\t \t \t @Override 
 
\t \t \t public void onDismiss(DialogInterface dialog) { 
 
\t \t \t \t //make FragmentTransaction.commit() here; 
 
\t \t \t \t 
 
\t \t \t \t //but it's recommended to pass control to your Activity 
 
\t \t \t \t //via an Interface and manage fragments there. 
 
\t \t \t } 
 
\t \t }); 
 
\t \t 
 
\t \t lv = (ListView) view.findViewById(R.id.lv_out1); 
 
\t \t lv.setOnItemClickListener(new OnItemClickListener() { 
 

 
\t \t \t @Override 
 
\t \t \t public void onItemClick(AdapterView<?> parent, final View view, 
 
\t \t \t \t \t final int position, long id) { 
 
\t \t \t \t 
 
\t \t \t \t //START PROGRESS DIALOG HERE 
 
\t \t \t \t progressDialog.show(); 
 
\t \t \t \t 
 
\t \t \t \t Cursor c = (Cursor) parent.getAdapter().getItem(position); 
 

 
\t \t \t \t // create Loader 
 
\t \t \t \t getLoaderManager().restartLoader(1, \t null, curFragment); 
 
\t \t \t } 
 
\t \t }); 
 

 
\t \t return view; 
 
\t } 
 
    
 
\t @Override 
 
\t public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
 
\t \t switch (loader.getId()) { 
 
\t \t case 1: 
 
\t \t \t //dismiss dialog and call progressDialog.onDismiss() listener 
 
\t \t \t progressDialog.dismiss(); 
 
\t \t \t break; 
 

 
\t \t default: 
 
\t \t \t break; 
 
\t \t } 
 
\t }

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