2013-08-15 5 views
27

मुझे "newInstance" -Pterntern (Best practice for instantiating a new Android Fragment) के बारे में पता है। लेकिन मैं एक टुकड़े के इन तर्कों को कैसे अपडेट करूं उदाहरण के लिए यदि कोई अन्य खंड डेटा बदलता है?एक टुकड़े के तर्कों को अद्यतन करने के लिए सबसे अच्छा अभ्यास?

मुझे फ्रैगमेंट/गतिविधि के बीच कॉलबैक-विधियों के बारे में पता है, लेकिन ये कॉलबैक तर्क अपडेट नहीं करेंगे ?!

उदाहरण के लिए: खंड के निर्माण पर मैं बंडल के साथ एक यूआरआई पास करता हूं। फिर दूसरा खंड इस यूआरआई को पहले खंड पर परिवर्तन उरी (उरी यूरी) विधि कॉलबैक के माध्यम से बदलता है। यदि तब खंड को फिर से बनाया जाता है (उदाहरण के लिए स्क्रीन रोटेशन के कारण) यह बाद में अपडेट की गई यूरी के बजाए तर्कों के बंडल से पहले यूआरआई का उपयोग करेगा, सही?

इसे हल करने का सबसे अच्छा अभ्यास क्या है? क्या मुझे इसे सहेजे गए इन्स्टेंसस्टेट में मैन्युअल रूप से संग्रहीत करना है और उपयोग पर यह तय करना है कि इंस्टेंसस्टेट या तर्क-बंडल का उपयोग करना है या नहीं?

मैं अपने टुकड़े के तर्कों से निपटने में एक मानक तरीका के लिए देख रहा हूँ, इसलिए मुझे लगता है मैं इस तरह के एक दृष्टिकोण के साथ जा रहा हूँ (छद्म कोड):

private Uri arg1; 

public static Fragment newInstance(Uri arg1) { 
    create bundle 
    create fragment instance 
    set bundle to fragment 
    return fragment 
} 

private void onCreate(Bundle savedInstance) { 
    if(savedInstance != null) { 
    arg1 = savedInstance.uri 
    } 
} 

private Uri getUri() { 
    if(arg1 == null) { 
    arg1 = getArguments.uri 
    } 
    if(arg1 == null) { 
    arg1 = defaultValue 
    } 
} 

तो मैं एक बस एकीकृत है मेरे तर्क तक पहुंचने का तरीका। और अगर मुझे उस तर्क की आवश्यकता होती है, तो मुझे और परेशानी का उपयोग करने की ज़रूरत नहीं है।

आप इसके बारे में क्या सोचते हैं?

+0

हां। कितना कोड बात कर रहे हैं? एक oveeriden विधि-'onSaveInstanceState'- 1 अतिरिक्त लाइन के साथ और 'ऑनक्रेट' में एक if-else कथन? – gunar

+0

असफल डिज़ाइन दोष दोष अन्य टुकड़ों पर निर्भर नहीं होना चाहिए – danny117

+0

उस खंड के सार्वजनिक तरीके में तर्कों को 'पुनः लिखना' के बारे में क्या? –

उत्तर

16

आप सेट के बाद तर्क बदल नहीं सकते हैं और FragmentActivity में जोड़ा गया है, मैंने आपके द्वारा परिभाषित समान दृष्टिकोण का उपयोग किया था। मैंने पहले Bundle को onCreate() पर पारित किया है, यदि यह शून्य नहीं है तो मैं इसका उपयोग करता हूं लेकिन अगर यह शून्य है तो मैं तर्क का उपयोग करता हूं। और मैं onSaveInstanceState() में नवीनतम डेटा जो भी बचाता हूं उसे बचाता हूं। अधिक जानकारी के लिए: Is it possible to pass arguments to a fragment after it's been added to an activity?

+1

मैं ओपी के लिए उचित क्रेडिट देने के उत्तर के रूप में इसे सेट करने की अत्यधिक अनुशंसा करता हूं। –

4

आप फ्रैगमेंट के onSaveInstanceState कॉलबैक में गतिविधियों के लिए वैसे ही राज्य को सहेजते हैं। यदि आपने पिछले onCreate() के बाद से यूआरआई को अपडेट किया है, तो आप Bundle में अद्यतन यूआरआई स्टोर करेंगे, और इसे onCreate() में वापस प्राप्त करेंगे। राज्य को सहेजना ठीक है, जिसे इसके लिए डिज़ाइन किया गया है, और यूआरआई को बदलकर, आपने जो कुछ किया है वह राज्य बदल गया है।

0

आप अपने टुकड़ों का उपयोग करने के तरीके के आधार पर यह निर्धारित कर सकते हैं कि रणनीति कितनी प्रभावी होगी।

उदाहरण के लिए, यदि आपके पास सामान्य टैब/पेज पेजर पैटर्न में कई टुकड़े हैं और उन्हें FragmentStatePagerAdapter के साथ प्रबंधित कर रहे हैं तो आपके गतिविधि या अन्य टुकड़ों के लिए एक खंड उदाहरण का संदर्भ देने का अवसर हो सकता है जो अब शून्य के कारण मौजूद नहीं है सूचक अपवाद।

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

इरादों के बारे में सुंदर बात यह है कि उन्हें विशिष्ट समय पर काम करने के लिए ट्यून किया जा सकता है और बंडलों और पार्सल-सक्षम वस्तुओं सहित डेटा एक्स्ट्रा की एक विस्तृत श्रृंखला को स्वीकार किया जा सकता है।

1

Best practice for updating arguments of a fragment: क्यों हम तर्क जोड़ने के लिए NewInstance() विधि & कारण है कि यह टुकड़ा के लिए सर्वोत्तम प्रथाओं है द्वारा की आवश्यकता है?

टुकड़ा किसी गतिविधि के मॉड्यूलर सेक्शन के रूप में सोचा जा सकता है। इसका मतलब है कि जब हम एक टुकड़ा बनाते हैं तो हमें इसे मॉड्यूलर & स्वतंत्र बनाने की आवश्यकता होती है।

आप एक टुकड़ा जो operate.We करने के लिए एक तर्क यह भी

MyFragmentClass mFrag = new MyFragmentClass(); 
Bundle bundle = new Bundle(); 
bundle.putString("key", value); 
mFrag.setArguments(bundle); 

लिख सकते हैं यह भी ठीक & काम करता है आप तर्क onCreate विधि प्राप्त कर सकते हैं की जरूरत की जरूरत है मान लीजिए। यहां अंतर है कि आप तर्क के बिना खंड का एक उदाहरण भी बना सकते हैं और इसे खंड प्रबंधक में जोड़ सकते हैं लेकिन आपके टुकड़े को संचालित करने के लिए तर्क की आवश्यकता है। सृजन के दौरान तर्क जोड़ने के लिए newInstance विधि खंड बलों डेवलपर में विधि जोड़ना। यही कारण है कि यह सर्वोत्तम प्रथाओं कहा जाता है।

आपकी समस्या में आप setRetainInstance(boolean retain) का उपयोग कर सकते हैं जो गतिविधि को नष्ट होने पर आपके टुकड़े को नष्ट नहीं करने के लिए रोकते हैं।

4

मैं सिर्फ बंडल में मान बदलने उदाहरण: नया तर्क के साथ

synchronized (fragment.getArguments()) { 
     fragment.getArguments().putInt(KEY, new Value); 
    } 

और अद्यतन सामग्री

+3

सिंक्रनाइज़ क्यों? –

+0

हां सिंक्रनाइज़ क्यों किया जाता है? –

0

यदि आपके एक टुकड़ा पुन: उपयोग करना चाहते हैं लेकिन तर्क अद्यतन करने की जरूरत है, तो आप उपयोग करने की आवश्यकता fragment.getArguments()। PutAll (बंडल);

private static void setInspireByDoArguments(DoOptionsFragment fragment, long doId) { 
    Bundle bundle = new Bundle(); 
    bundle.putLong(Constants.EXTRA_DO_ID, doId); 
    bundle.putInt(Constants.EXTRA_DO_OPTIONS_DIALOG_MODE, MODE_GET_INSPIRE_BY_DO); 
    if (fragment.getArguments() != null) { 
     fragment.getArguments().putAll(bundle); 
    } else 
     fragment.setArguments(bundle); 
} 

//This is how I managed to Check if the fragment exist and update the arguments. 

public static void showDoInspireDialog(FragmentManager fragmentManager, long doId, DoOptionsFragment.DoOptionCallBack callBack) { 
    DoOptionsFragment doOptionsFragment = (DoOptionsFragment) fragmentManager.findFragmentByTag("do_options_fragment"); 
    if (doOptionsFragment == null) { 
     doOptionsFragment = DoOptionsFragment.getInspiredByDoInstance(doId, callBack); 
     fragmentManager.beginTransaction() 
       .add(doOptionsFragment, "do_options_fragment") 
       .commit(); 
    } else { 
     doOptionsFragment.setCallBack(callBack); 
     setInspireByDoArguments(doOptionsFragment, doId); 
     doOptionsFragment.showInspireByDoDialog(doId); 
    } 
} 

    public static DoOptionsFragment getInspiredByDoInstance(long doId, DoOptionsFragment.DoOptionCallBack callBack) { 
    DoOptionsFragment doOptionsFragment = new DoOptionsFragment(); 
    setInspireByDoArguments(doOptionsFragment, doId); 
    doOptionsFragment.setCallBack(callBack); 
    return doOptionsFragment; 
} 
+0

'fragment.setArguments (बंडल) 'यदि आप गतिविधि में मौजूदा खंड में वापस स्विच करते हैं तो' java.lang.IleglegalStateException' 'उत्पन्न कर सकते हैं – StAlex

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