एक नया एंड्रॉइड फ्रैगमेंट इंस्टेंट करने के लिए सबसे अच्छा अभ्यास


706

मैंने एक अनुप्रयोग में एक नए फ़्रैगमेंट को तुरंत करने के लिए दो सामान्य प्रथाओं को देखा है:

Fragment newFragment = new MyFragment();

तथा

Fragment newFragment = MyFragment.newInstance();

दूसरा विकल्प एक स्थैतिक विधि का उपयोग करता है newInstance()और आम तौर पर निम्नलिखित विधि होती है।

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}

सबसे पहले, मैंने सोचा था कि मुख्य लाभ यह था कि मैं नई सामग्री () पद्धति को अधिभार देने के लिए लचीलापन दे सकता हूं जब एक फ्रैगमेंट के नए उदाहरण बनाते हैं - लेकिन मैं यह भी फ्रैगमेंट के लिए एक अतिभारित निर्माणकर्ता बना सकता हूं।

क्या मैं कुछ भुल गया?

एक पर दूसरे के दृष्टिकोण के क्या लाभ हैं? या यह सिर्फ अच्छा अभ्यास है?


जब पैरामीटर होते हैं, तो कोई विकल्प नहीं होता है, और यहां बड़े पैमाने पर इसका जवाब दिया जाता है। फिर भी, यह सवाल टुकड़े टुकड़े के बिना तर्क के निर्माण के लिए बना हुआ है।
आरडीएस

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

जवाबों:


1138

यदि एंड्रॉइड बाद में आपके फ्रैगमेंट को फिर से बनाने का फैसला करता है, तो यह आपके टुकड़े के नो-तर्क निर्माता को कॉल करने वाला है। इसलिए निर्माणकर्ता को ओवरलोड करना कोई समाधान नहीं है।

इसके साथ ही कहा जा रहा है, आपके फ्रैगमेंट में सामान को पास करने का तरीका ताकि एंड्रॉइड द्वारा एक फ्रैगमेंट को दोबारा बनाए जाने के बाद वे उपलब्ध हों, setArgumentsविधि के लिए एक बंडल पास करना है ।

इसलिए, उदाहरण के लिए, यदि हम उस टुकड़े का पूर्णांक पास करना चाहते हैं, जिसका उपयोग हम कुछ इस तरह करेंगे:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

और बाद में Fragment में onCreate()आप उपयोग करके उस पूर्णांक तक पहुँच सकते हैं:

getArguments().getInt("someInt", 0);

यह बंडल तब भी उपलब्ध होगा जब फ्रेगमेंट किसी तरह से एंड्रॉइड द्वारा फिर से बनाया गया हो।

यह भी नोट करें: setArgumentsगतिविधि में संलग्न होने से पहले केवल कॉल किया जा सकता है।

यह दृष्टिकोण Android डेवलपर संदर्भ में भी प्रलेखित है: https://developer.android.com/reference/android/app/Frag@gmail


7
@Vlasto दुर्भाग्य से स्थिर तरीकों को ओवरराइड नहीं किया जा सकता है।
AJD

8
@ मुझे लगता है कि मुझे यहां कुछ याद आ रहा है, क्या आप किसी भी तरह से यहां एक कंस्ट्रक्टर का उपयोग नहीं कर सकते हैं, एक जो बंडल बनाता है और सेटआर्ग्यूमेंट्स () अभी भी कॉल करता है क्योंकि यह केवल आपके कोड द्वारा कॉल किया जाएगा (और नहीं जब एंड्रॉइड आपके द्वारा फिर से बनाता है टुकड़ा)?
माइक ट्यूनीक्लिफ

9
@mgibson यदि आप चाहते हैं कि डेटा तब उपलब्ध हो, जब टुकड़ा बाद में फिर से बनाया जाए, तो आपको एक बंडल का उपयोग करना चाहिए
यिदल

114
टुकड़ों के लिए नो-लॉजिक कंस्ट्रक्टर बनाने के लिए FORCED होना संभावित रूप से सभी प्रोग्रामिंग में कहीं भी सबसे बड़ा गोच है। यह वस्तु निर्माण और आरंभीकरण में एक पूर्ण प्रतिमान परिवर्तन के लिए बाध्य करता है। यदि आप Android पर नए हैं और इस थ्रेड पर ठोकर खाई है, तो कृपया उत्तर को बार-बार पढ़ें।
remrabelle

9
मैं उस दावे के साथ बहस करूंगा। पहला, टाइप-सेफ़िटी एक भाषा की चिंता है, न कि एक फ्रेमवर्क की चिंता। दूसरे, IMO, फ्रेमवर्क "आपके एपीआई को कभी नहीं करना चाहिए" के क्षेत्र में कदम रख रहा है। यदि मैं कांग्रेस के पुस्तकालय को अपने खंडहर निर्माणकर्ता में पारित करना चाहता हूं, तो मुझे अनुमति दी जानी चाहिए। "नो-आर्ग्स" कंस्ट्रक्टर कॉन्ट्रैक्ट मूल रूप से टुकड़ों में निर्भरता इंजेक्शन के उपयोग को मारता है - प्रमुख व्यंग।
रमीराबेल

95

newInstance()मेरे द्वारा देखे जाने का उपयोग करने में एकमात्र लाभ निम्नलिखित हैं:

  1. आपके पास एक एकल स्थान होगा जहां टुकड़े द्वारा उपयोग किए जाने वाले सभी तर्क को बंडल किया जा सकता है और आपको किसी टुकड़े को तुरंत हटाने के लिए नीचे दिए गए कोड को लिखने की ज़रूरत नहीं है।

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    args.putString("someString", someString);
    // Put any other arguments
    myFragment.setArguments(args);
  2. अन्य वर्गों को यह बताने का एक अच्छा तरीका है कि यह उम्मीद करता है कि यह विश्वासपूर्वक काम करने की उम्मीद करता है (हालांकि आपको ऐसे मामलों को संभालने में सक्षम होना चाहिए यदि कोई तर्क खंड में नहीं हैं)।

तो, मेरा लेना यह है कि newInstance()किसी अंश का त्वरित करने के लिए स्थैतिक का उपयोग करना एक अच्छा अभ्यास है।


4
१) यह तर्क को किसी रचनाकार में डालने से अलग कैसे है? दोनों एकल स्थान हैं जहाँ आप इस तर्क को शामिल करते हैं। 2) एक स्थिर कारखाने पर पैरामीटर किसी निर्माणकर्ता के मापदंडों से अलग कैसे होते हैं? दोनों बताते हैं कि क्या तर्क दिए जाने की उम्मीद है। मेरा कहना है कि यह एक अलग प्रतिमान है, यकीन है, लेकिन कंस्ट्रक्टरों के उपयोग से इस पर कोई स्पष्ट लाभ नहीं है।
आरजे कटहबर्टसन

2
आप फ़्रेग्मेंटेशन के लिए कस्टम कंस्ट्रक्टर का उपयोग नहीं कर सकते। फ्रेमवर्क, टुकड़ों को बहाल करने के लिए नो लॉजिक कंस्ट्रक्टर का उपयोग करता है।
500865

5
हां, मैं वहां आपसे सहमत हूं। मैं कह रहा हूं कि वैचारिक रूप से ओवरलोडेड कंस्ट्रक्टरों का उपयोग करने के बजाय स्थिर कारखाना पैटर्न का उपयोग करने में कोई लाभ नहीं है, और इसके विपरीत। आपके दोनों बिंदु दोनों पैटर्न में मान्य हैं; एक के ऊपर एक प्रयोग करने का कोई लाभ नहीं है। एंड्रॉइड आपको स्थिर कारखाने पैटर्न का उपयोग करने के लिए मजबूर करता है - लेकिन एक या दूसरे का उपयोग करने का कोई लाभ नहीं है।
आरजे कुथबर्टन

pastebin.com/EYJzES0j
RJ Cuthbertson

@RJCuthbertson एक संभावित लाभ स्थैतिक कारखाने विधि के वर्ग के उप-वर्ग बनाने और वापस करने की क्षमता होगा यानी स्थिति के लिए एक उपयुक्त उपवर्ग वापस करने के लिए।
अर्जेंट

62

एक और तरीका भी है:

Fragment.instantiate(context, MyFragment.class.getName(), myBundle)

अगर मैं गलत नहीं हूँ, यह केवल तभी संभव है जब आप Android समर्थन लाइब्रेरी का उपयोग करें।
तिमो

2
यह समर्थन पुस्तकालय के साथ करने की कोशिश की, लेकिन onCreateView (मेरे टुकड़े में), बंडल पारित कर दिया गया अशक्त था, इसलिए मैं setArguments / getArguments विकल्प के साथ चला गया और इसने (इसे पढ़ने वाले किसी के लिए) काम किया।
Jrop

1
दिलचस्प है, मैंने यह दृष्टिकोण पहले नहीं देखा है। क्या किसी फ्रैग्मेंट को इंस्टेंट करने के अन्य तरीकों पर इसका कोई लाभ है?
इगोरगानापोलस्की

23
से डेवलपर दस्तावेज़ ,instantiate() Creates a new instance of a Fragment with the given class name. This is the same as calling its empty constructor.
ब्रायन बोमन

2
हालांकि उन्होंने खाली कंस्ट्रक्टर को बुलाए जाने का उल्लेख किया। "args.setClassLoader (f.getClass () getClassLoader ()।);" को बंडल दलीलों के लिए नीचे कहा जाता है
Gökhan Barış Aker

49

जबकि @yydl एक सम्मोहक कारण देता है कि newInstanceविधि बेहतर क्यों है:

यदि एंड्रॉइड बाद में आपके फ्रैगमेंट को फिर से बनाने का फैसला करता है, तो यह आपके टुकड़े के नो-तर्क निर्माता को कॉल करने वाला है। इसलिए निर्माणकर्ता को ओवरलोड करना कोई समाधान नहीं है।

एक निर्माता का उपयोग करना अभी भी काफी संभव है । यह क्यों है, यह देखने के लिए, पहले हमें यह देखने की आवश्यकता है कि एंड्रॉइड द्वारा उपरोक्त वर्कअराउंड का उपयोग क्यों किया जाता है।

एक टुकड़े का उपयोग करने से पहले, एक उदाहरण की आवश्यकता है। Android कॉल YourFragment()( कोई तर्क निर्माता नहीं) खंड का एक उदाहरण का निर्माण करने के लिए। यहां आपके द्वारा लिखे गए किसी भी अतिभारित निर्माता को अनदेखा किया जाएगा, क्योंकि एंड्रॉइड यह नहीं जान सकता है कि किसका उपयोग करना है।

एक गतिविधि के जीवनकाल में, टुकड़ा ऊपर के रूप में बनाया जाता है और कई बार एंड्रॉइड द्वारा नष्ट कर दिया जाता है। इसका अर्थ है कि यदि आप डेटा को खंड ऑब्जेक्ट में डालते हैं, तो यह टुकड़ा नष्ट हो जाने पर खो जाएगा।

वर्कअराउंड करने के लिए, एंड्रॉइड पूछता है कि आप Bundle(कॉलिंग setArguments()) का उपयोग करके डेटा स्टोर करते हैं , जिसे तब से एक्सेस किया जा सकता है YourFragment। तर्क bundleएस एंड्रॉइड द्वारा संरक्षित हैं, और इसलिए लगातार बने रहने की गारंटी है ।

इस बंडल को सेट करने का एक newInstanceतरीका स्थिर विधि का उपयोग करना है :

public static YourFragment newInstance (int data) {
    YourFragment yf = new YourFragment()
    /* See this code gets executed immediately on your object construction */
    Bundle args = new Bundle();
    args.putInt("data", data);
    yf.setArguments(args);
    return yf;
}

हालांकि, एक निर्माता:

public YourFragment(int data) {
    Bundle args = new Bundle();
    args.putInt("data", data);
    setArguments(args);
}

newInstanceविधि के रूप में बिल्कुल वैसा ही कर सकते हैं ।

स्वाभाविक रूप से, यह विफल हो जाएगा, और एक कारण है कि एंड्रॉइड आपको newInstanceविधि का उपयोग करना चाहता है :

public YourFragment(int data) {
    this.data = data; // Don't do this
}

आगे की व्याख्या के रूप में, यहाँ Android के Fragment Class है:

/**
 * Supply the construction arguments for this fragment.  This can only
 * be called before the fragment has been attached to its activity; that
 * is, you should call it immediately after constructing the fragment.  The
 * arguments supplied here will be retained across fragment destroy and
 * creation.
 */
public void setArguments(Bundle args) {
    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

ध्यान दें कि एंड्रॉइड पूछता है कि तर्क केवल निर्माण पर सेट किए गए हैं, और गारंटी देता है कि इन्हें बनाए रखा जाएगा।

संपादित करें : जैसा कि @JHH द्वारा टिप्पणियों में बताया गया है, यदि आप एक कस्टम कंस्ट्रक्टर प्रदान कर रहे हैं जिसमें कुछ तर्कों की आवश्यकता होती है, तो जावा आपके टुकड़े को बिना किसी आर्ग डिफॉल्ट कंस्ट्रक्टर के साथ प्रदान नहीं करेगा । तो इसके लिए आपको एक arg कंस्ट्रक्टर को परिभाषित करने की आवश्यकता होगी , जो कोड है जिसे आप newInstanceफ़ैक्टरी विधि से बचा सकते हैं ।

संपादित करें : Android अब टुकड़ों के लिए एक अतिभारित निर्माता का उपयोग करने की अनुमति नहीं देता है। आपको newInstanceविधि का उपयोग करना चाहिए ।


Android का उपयोग कब उचित होगा: configChanges = "अभिविन्यास | कीबोर्डहाइंड | स्क्रीनसेज़"?
ल्यूक एलीसन

1
एंड्रॉइड स्टूडियो अब टुकड़ों में सभी गैर-डिफ़ॉल्ट बिल्डरों के लिए एक त्रुटि फेंकता है, इसलिए यह अब काम नहीं करता है।
शेहरार

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

3
वैसे इसका एक सूक्ष्म कारण है। आप तर्कों के साथ अपना स्वयं का निर्माता बनाने के लिए स्वतंत्र हैं, लेकिन फिर भी एक नो-आर्ग कंस्ट्रक्टर होने की आवश्यकता है । चूंकि कक्षाओं में हमेशा एक निहित नहीं-आर्ग कंस्ट्रक्टर होता है जब तक कि साथ एक कंस्ट्रक्टर को स्पष्ट रूप से परिभाषित नहीं किया जाता है , इसका मतलब है कि आपको अपने अर्ग-कंस्ट्रक्टर और नो-आर्ग कंस्ट्रक्टर दोनों को स्पष्ट रूप से परिभाषित करना होगा , या सिस्टम किसी को भी आमंत्रित करने में सक्षम नहीं होगा। नो-आर्ग कंस्ट्रक्टर। मेरा मानना ​​है कि इसीलिए यह सिफारिश एक स्थिर कारखाना विधि का उपयोग करने के लिए है - यह केवल एक गैर-अर्ग निर्माणकर्ता को परिभाषित करने के लिए भूलने के जोखिम को कम करता है।
जेएचएच

@ जेएचएच जो संकलन के समय में ही विफल हो जाएगा, इसलिए जोखिम का बड़ा हिस्सा नहीं। हालांकि, यहां मुद्दा यह है कि कंस्ट्रक्टर ओवरलोडिंग, एक प्रमुख प्रोग्रामिंग प्रतिमान, एंड्रॉइड द्वारा अस्वीकार किया जा रहा है।
Ps95

20

मैं यह कहते हुए यदी के उत्तर से असहमत हूं:

यदि एंड्रॉइड बाद में आपके फ्रैगमेंट को फिर से बनाने का फैसला करता है, तो यह आपके टुकड़े के नो-तर्क निर्माता को कॉल करने वाला है। इसलिए निर्माणकर्ता को ओवरलोड करना कोई समाधान नहीं है।

मुझे लगता है कि यह एक समाधान और एक अच्छा है, यह वास्तव में जावा कोर भाषा द्वारा विकसित किया गया है यही कारण है।

यह सच है कि एंड्रॉइड सिस्टम आपके को नष्ट और फिर से बना सकता है Fragment। तो आप यह कर सकते हैं:

public MyFragment() {
//  An empty constructor for Android System to use, otherwise exception may occur.
}

public MyFragment(int someInt) {
    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    setArguments(args);
}

यह आपको बाद वाले someIntसे खींचने की अनुमति देगा getArguments(), भले ही Fragmentसिस्टम द्वारा फिर से बनाया गया हो। यह staticकंस्ट्रक्टर की तुलना में अधिक सुरुचिपूर्ण समाधान है ।

मेरी राय में staticकंस्ट्रक्टर बेकार हैं और उनका उपयोग नहीं किया जाना चाहिए। साथ ही वे आपको सीमित कर देंगे यदि भविष्य में आप इसका विस्तार करना चाहते Fragmentहैं और निर्माणकर्ता को अधिक कार्यक्षमता जोड़ सकते हैं। staticकंस्ट्रक्टर के साथ आप ऐसा नहीं कर सकते।

अपडेट करें:

एंड्रॉइड ने निरीक्षण में कहा कि सभी गैर-डिफ़ॉल्ट निर्माणकर्ताओं को एक त्रुटि के साथ चिह्नित करें।
मैं ऊपर बताए गए कारणों से इसे निष्क्रिय करने की सलाह देता हूं।


4
एक स्थिर विधि होने का एक और लाभ, जिसका मैंने ऊपर उल्लेख नहीं किया है, वह यह है कि आप अकस्मात इसके गुणों को सेट नहीं कर सकते हैं।
yydl

4
इसके अतिरिक्त, "इस टुकड़े का विस्तार करें" के बारे में आपकी बात के संबंध में, यह विधि वास्तव में वास्तव में खराब होगी यदि आप कभी भी कक्षा का विस्तार करते हैं। सुपर कॉल करने से सेरग्यूमेंट्स () कॉल का कारण केवल बच्चे या माता-पिता दोनों के लिए प्रभावी होगा, लेकिन दोनों नहीं!
yydl

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

9
यह सच है, लेकिन लोगों ने Google द्वारा सुझाए गए पैटर्न का उपयोग करने के लिए प्रोत्साहित करने का एक और कारण है। बेशक, हम सभी सहमत हैं कि आपका समाधान 100% तकनीकी रूप से संभव है। बहुत कुछ उसी तरह से बहुत सारी चीजें करने के कई तरीके हैं। हालांकि, यह सवाल है कि क्या यह सबसे अच्छा है। और मुझे दृढ़ता से लगता है कि निर्माणकर्ता का उपयोग इस कार्य की वास्तविक प्रकृति का प्रतिनिधित्व नहीं करता है।
1

3
मैं @yydl से सहमत हूं कि स्थिर निर्माण बेहतर है। एक अन्य लाभ भविष्य की नई निर्भरता का निर्भरता इंजेक्शन है - इसके लिए निर्माता बीमार है और संभवतः अधिक कोड परिवर्तन (या अधिक निर्माणकर्ता जोड़े जाने का कारण) होगा।
बून

19

कुछ कोटलिन कोड:

companion object {
    fun newInstance(first: String, second: String) : SampleFragment {
        return SampleFragment().apply {
            arguments = Bundle().apply {
                putString("firstString", first)
                putString("secondString", second)
            }
        }
    }
}

और आप इसके साथ तर्क प्राप्त कर सकते हैं:

val first: String by lazy { arguments?.getString("firstString") ?: "default"}
val second: String by lazy { arguments?.getString("secondString") ?: "default"}

3

एंड्रॉइड में तर्कों के साथ अंशों को इंस्टाल करने का सबसे अच्छा अभ्यास आपके टुकड़े में स्थिर कारखाना विधि है।

public static MyFragment newInstance(String name, int age) {
    Bundle bundle = new Bundle();
    bundle.putString("name", name);
    bundle.putInt("age", age);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(bundle);

    return fragment;
}

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

आप यहां तर्कों के साथ अंशों को त्वरित करने के लिए सर्वोत्तम अभ्यास के बारे में अधिक जानकारी पा सकते हैं ।


2

चूंकि सर्वोत्तम अभ्यास के बारे में प्रश्न हैं, इसलिए मैं कुछ REST वेब सेवाओं के साथ काम करते समय टुकड़े पैदा करने के लिए हाइब्रिड दृष्टिकोण का उपयोग करने के लिए बहुत अच्छा विचार करूंगा।

हम उपयोगकर्ता के टुकड़े प्रदर्शित करने के मामले में, कुछ उपयोगकर्ता मॉडल के लिए, जटिल वस्तुओं को पारित नहीं कर सकते

लेकिन हम क्या कर सकते हैं, onCreateउस उपयोगकर्ता में जांच करना है ! = अशक्त और यदि नहीं - तो उसे डेटा परत से लाएं, अन्यथा - मौजूदा का उपयोग करें।

इस तरह से हम दोनों को उपयोगकर्ता द्वारा पुनः प्राप्त करने की क्षमता हासिल करते हैं, एंड्रॉइड द्वारा टुकड़ा मनोरंजन के मामले में और उपयोगकर्ता कार्यों के लिए तड़क-भड़क के साथ-साथ वस्तु को पकड़कर या केवल आईडी बनाने की क्षमता

कुछ इस तरह से:

public class UserFragment extends Fragment {
    public final static String USER_ID="user_id";
    private User user;
    private long userId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userId = getArguments().getLong(USER_ID);
        if(user==null){
            //
            // Recreating here user from user id(i.e requesting from your data model,
            // which could be services, direct request to rest, or data layer sitting
            // on application model
            //
             user = bringUser();
        }
    }

    public static UserFragment newInstance(User user, long user_id){
        UserFragment userFragment = new UserFragment();
        Bundle args = new Bundle();
        args.putLong(USER_ID,user_id);
        if(user!=null){
            userFragment.user=user;
        }
        userFragment.setArguments(args);
        return userFragment;

    }

    public static UserFragment newInstance(long user_id){
        return newInstance(null,user_id);
    }

    public static UserFragment newInstance(User user){
        return newInstance(user,user.id);
    }
}

3
आपने कहा: "हम जटिल वस्तुओं को पारित नहीं कर सकते, उदाहरण के लिए कुछ उपयोगकर्ता मॉडल," - यह सच नहीं है, हम कर सकते हैं। इस तरह: User user = /*...*/ उपयोगकर्ता को बंडल में रखें: Bundle bundle = new Bundle(); bundle.putParcelable("some_user", user); और तर्क से उपयोगकर्ता को प्राप्त करें: User user = getArguments().getParcelable("some_user"); ऑब्जेक्ट को पार्सलेबल इंटरफ़ेस लागू करना चाहिए। लिंक
एडम वर्हेगी

3
ठीक है, हाँ, लेकिन जब कक्षा जटिल होती है और इसमें अन्य वस्तुओं के लिए रेफ़र होता है ... मैं व्यक्तिगत रूप से इसे सरल रखना पसंद करता हूं, या तो मेरे पास कोई वस्तु है, या मुझे नहीं चाहिए और फिर इसे प्राप्त करने की आवश्यकता है
तिगरा

1

इस कोड का उपयोग करें 100% अपनी समस्या को ठीक करें

FirstFragment में यह कोड दर्ज करें

public static yourNameParentFragment newInstance() {

    Bundle args = new Bundle();
    args.putBoolean("yourKey",yourValue);
    YourFragment fragment = new YourFragment();
    fragment.setArguments(args);
    return fragment;
}

यह नमूना बुलियन डेटा भेजता है

और SecendFragment में

yourNameParentFragment name =yourNameParentFragment.newInstance();
   Bundle bundle;
   bundle=sellDiamondFragments2.getArguments();
  boolean a= bundle.getBoolean("yourKey");

पहले टुकड़े में मूल्य स्थिर होना चाहिए

खुश कोड


0

टुकड़े को हटाने के लिए सबसे अच्छा तरीका है डिफ़ॉल्ट Fragment.instantiate विधि का उपयोग करें या फ़्रेग्मेंट को तुरंत करने के लिए फ़ैक्टरी विधि
बनाएँ: हमेशा फ़्रेग्मेंट मेमोरी में एक खाली कंस्ट्रक्टर बनाएँ, जबकि फ़्रेग्मेंटेशन मेमोरी को रन-टाइम अपवाद फेंक देंगे।


0

मैं हाल ही में यहाँ हूँ। लेकिन मुझे पता है कि आपको थोड़ी मदद मिल सकती है।

यदि आप जावा का उपयोग कर रहे हैं, तो बदलने के लिए बहुत कुछ नहीं है। लेकिन कोटलिन डेवलपर्स के लिए, यहां कुछ स्निपेट निम्नलिखित हैं, जो मुझे लगता है कि आप को चलाने के लिए एक तहखाने बना सकते हैं:

  • जनक टुकड़ा:
inline fun <reified T : SampleFragment> newInstance(text: String): T {
    return T::class.java.newInstance().apply {
        arguments = Bundle().also { it.putString("key_text_arg", text) }
    }
}
  • सामान्य कॉल
val f: SampleFragment = SampleFragment.newInstance("ABC")
// or val f = SampleFragment.newInstance<SampleFragment>("ABC")
  • आप बच्चे के टुकड़े वर्ग में माता-पिता के इनिट ऑपरेशन को बढ़ा सकते हैं:
fun newInstance(): ChildSampleFragment {
    val child = UserProfileFragment.newInstance<ChildSampleFragment>("XYZ")
    // Do anything with the current initialized args bundle here
    // with child.arguments = ....
    return child
}

खुश कोडिंग।


-2

setArguments()व्यर्थ का। यह केवल एक गड़बड़ लाता है।

public class MyFragment extends Fragment {

    public String mTitle;
    public String mInitialTitle;

    public static MyFragment newInstance(String param1) {
        MyFragment f = new MyFragment();
        f.mInitialTitle = param1;
        f.mTitle = param1;
        return f;
    }

    @Override
    public void onSaveInstanceState(Bundle state) {
        state.putString("mInitialTitle", mInitialTitle);
        state.putString("mTitle", mTitle);
        super.onSaveInstanceState(state);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        if (state != null) {
            mInitialTitle = state.getString("mInitialTitle");
            mTitle = state.getString("mTitle");
        } 
        ...
    }
}

सिवाय आपको सिर्फ एक और विधि को ओवरराइड करने और एक ऐसा क्षेत्र बनाने के लिए मजबूर किया गया है जिसे onViewCreatedदायरे से अलग किया जा सकता था । यह सुविधा है मुझे लगता है, एक ही काम करने के कई तरीके। यह उपयोगकर्ता द्वारा किए गए अपडेट की जांच करने का एक आसान तरीका है (इसके बंडल getArgumentsऔर बंडल से तुलना करें onSaveInstanceState)
ओवरक्लोवर

@Asagen, मुझे प्रारंभिक और उपयोगकर्ता मूल्यों की तुलना के बारे में आपकी टिप्पणी पसंद है। मैंने कोड को संपादित किया और विचार किया कि यह अभी भी एक समान और स्पष्ट विटआउट getArgumentsसामान है। onViewCreatedस्कोप के बारे में ... हम वहां राज्य बंडल को पुनर्स्थापित कर सकते हैं। लेकिन मैं सिर्फ onCreateViewप्रकाश और तेज बनाना पसंद करता हूं और सभी भारी आरंभीकरण अंदर करता हूं onActivityCreatedक्योंकि Fragment.getActivity()कभी-कभी वापस लौटना पसंद करता है nullऔर onAttach()एपीआई 23 के नए संस्करण में बदलाव के कारण ।
वादिम स्टार

तुम सब यहाँ किया था कदम set और get Argumentsमें saveInstanceState। आप अनिवार्य रूप से वही काम कर रहे हैं जो "हुड के नीचे" किया गया है
OneCricketeer

1
@ क्रिकेट_007, या इसके ठीक विपरीतsaveInstanceState"हुड के नीचे" का उपयोग करना है। और उपयोग की Argumentsकार्यक्षमता का दोहराव है जो आपको दोहरी जांच करता है: पहले Argumentsमूल्य और फिर saveInstanceStateमूल्य। क्योंकि आपको saveInstanceStateकिसी भी तरह से उपयोग करना है। किस बारे में Arguments... वे आवश्यक नहीं हैं।
स्टार

तर्क टुकड़े के लिए इरादे एक्स्ट्रा के बराबर हैं । वे बेकार नहीं हैं, उनमें प्रारंभिक पैरामीटर हैं जो वर्तमान स्थिति से अलग है।
ब्लेडचोडर

-12

मेरा मानना ​​है कि मेरे पास इसके लिए एक बहुत ही अच्छा समाधान है।

public class MyFragment extends Fragment{

   private String mTitle;
   private List<MyObject> mObjects;

   public static MyFragment newInstance(String title, List<MyObject> objects)
   MyFragment myFrag = new MyFragment();
   myFrag.mTitle = title;
   myFrag.mObjects = objects;
   return myFrag;
   }

12
यदि MyFragment को फिर से बनाया जाए (उपयोगकर्ता होम स्क्रीन पर जाता है और बाद में वह ऐप खोलता है जो MyFragment पर छूट जाता है) mObjects को हटा दिया जाएगा। आप MyFragment को तर्क के रूप में बंडल भेजकर mObjects को बनाए रख सकते हैं।
ynnadkrap

1
इसके अलावा, गैर-स्थैतिक सदस्य चर तक स्थिर विधि कैसे पहुंचती है?
OrhanC1

2
@ynnadkrap आप सही हैं, एक बंडल का उपयोग करके यहां जाने का रास्ता है।
स्टीफन बोगार्ड

2
@ OrhanC1 इस उदाहरण कोड के अनुसार, स्थैतिक विधि सदस्य चरों तक नहीं पहुँच पा रही है। MyFragment का उदाहरण इसके सदस्यों तक पहुंच रहा है। यहां कोई त्रुटि नहीं है। हालाँकि, मैं किसी को भी इस उत्तर की अनुशंसा नहीं करता हूं क्योंकि जब एंड्रॉइड ओएस द्वारा कुछ स्थान को खोलने के लिए मेमोरी से आपके टुकड़े को हटा दिया जाता है, तो गतिविधि को पुनरारंभ करने के बाद और इस टुकड़े को चींटी चर को असाइन किए बिना डिफ़ॉल्ट खाली निर्माणकर्ता के साथ बनाया जाएगा।
गुनान

@ गुंजन तुम सही हो! यह। भ्रम के लिए क्षमा करें :)
OrhanC1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.