FragmentPagerAdapter और FragmentStatePagerAdapter के बीच अंतर क्या है?


374

बीच क्या अंतर है FragmentPagerAdapterऔर FragmentStatePagerAdapter?

FragmentPagerAdapterGoogle के मार्गदर्शक के बारे में कहते हैं:

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

और के बारे में FragmentStatePagerAdapter:

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

इसलिए मेरे पास सिर्फ 3 टुकड़े हैं। लेकिन उनमें से सभी अलग-अलग मॉड्यूल हैं जिनमें बड़ी मात्रा में डेटा है।

Fragment1कुछ डेटा को संभालता है (जो उपयोगकर्ता दर्ज करते हैं) और इसे गतिविधि में गुजरता है Fragment2, जो कि बस एक सरल है ListFragmentFragment3एक भी है ListFragment

तो मेरे सवाल हैं : मुझे किस एडॉप्टर का उपयोग करना चाहिए? FragmentPagerAdapterया FragmentStatePagerAdapter?


2
मुझे लगता है कि केवल 3 फ्रैगमेंट होने से आप फ्रैगमेंटपेजर एडेप्टर का उपयोग कर सकते हैं। इन खंडों के लिए टैब शायद सभी एक साथ दिखाई देंगे।
इगोरगानापोलस्की

2
इस पोस्ट ने मेरे 5-6 घंटे बचाए क्योंकि मैं गलत प्रकार के एडेप्टर का उपयोग करता हूं
नैनटैप 16

1
इस सवाल का जवाब एक और सवाल stackoverflow.com/questions/9156406/…
Piyush Kukadiya

वहाँ है FragmentPagerAdapterऔर FragmentStatePagerAdapterलेकिन क्या है FragmentStateAdapter?
the_prole

जवाबों:


291

जैसे डॉक्स कहते हैं, उसके बारे में इस तरह से सोचें। यदि आप एक पुस्तक पाठक की तरह एक आवेदन करना चाहते थे, तो आप एक बार में सभी टुकड़ों को मेमोरी में लोड नहीं करना चाहेंगे। Fragmentsजैसा कि उपयोगकर्ता पढ़ता है आप उसे लोड और नष्ट करना चाहेंगे । इस मामले में आप का उपयोग करेंगे FragmentStatePagerAdapter। यदि आप केवल 3 "टैब" प्रदर्शित कर रहे हैं, जिसमें बहुत अधिक डेटा नहीं है (जैसे Bitmaps), तो FragmentPagerAdapterआप पर अच्छी तरह से बात हो सकती है। इसके अलावा, ध्यान रखें कि ViewPagerडिफ़ॉल्ट रूप से मेमोरी में 3 टुकड़े लोड होंगे। पहला जो Adapterआप उल्लेख करते हैं वह Viewपदानुक्रम को नष्ट कर सकता है और ज़रूरत पड़ने पर इसे फिर से लोड कर सकता है, दूसरा Adapterकेवल राज्य को बचाता है Fragmentऔर इसे पूरी तरह से नष्ट कर देता है, यदि उपयोगकर्ता फिर उस पृष्ठ पर वापस आता है, तो स्थिति पुनर्प्राप्त हो जाती है।


मेरे पास Fragment1 और ListView में कई बटन और TextView हैं जो Fragment2 और Fragment3 में गतिशील रूप से आइटम उत्पन्न करते हैं। क्या आपको लगता है कि FragmentStatePagerAdapter का उपयोग करना और गतिविधि में सभी डेटा संग्रहीत करना एक अच्छा विचार है, इसे बंडल के माध्यम से Fragments में पास करना है?
एलेक्समोमोटोव

2
@AlexMomotov फ्रैगमेंट के लेआउट में दृश्य FragmentStatePassAdapter की पसंद के साथ कुछ नहीं करना है। यहां सवाल यह है कि फ्रेग्मेंट की मात्रा किसके माध्यम से पाई जाएगी।
इगोरगानापोलस्की

1
इसलिए आधारभूत FragmentPagerAdapterइसका उपयोग करने के पक्ष में कुछ भी नहीं है।
टॉमाज़ मूलार्क

3
@ टॉमाज़ का लाभ FragmentPagerAdapterयह है कि टुकड़ों के बीच स्विच करना बहुत तेज़ हो सकता है, क्योंकि वास्तविक Fragmentवस्तुओं को हर बार पुनर्निर्माण करने की आवश्यकता नहीं होती है। दूसरी ओर, यह स्मृति में खंडित वस्तुओं को पकड़कर अधिक मेमोरी का उपयोग करके समाप्त होगा।
रिचर्ड ले मेसुरियर

मेरे पास 3 टैब / पृष्ठ हैं (जो प्रत्येक एक WebView दिखाते हैं), इसलिए FragmentPagerAdapter का उपयोग किया है । हालाँकि, जब मैं पहले पृष्ठ से उस पर स्वाइप करता हूँ, तब भी अंतिम पृष्ठ फिर से तैयार हो जाता है। इसे हल करने के लिए, मैंने उपयोग किया है viewPager.setOffscreenPageLimit(2)
प्रतिबंध-जियोइंजीनियरिंग

131
  • FragmentPagerAdapterमेमोरी में पूरे टुकड़े को स्टोर करता है, और बड़ी मात्रा में टुकड़ों का उपयोग करने पर मेमोरी ओवरहेड बढ़ा सकता है ViewPager

  • इसके सिबलिंग के विपरीत, FragmentStatePagerAdapterकेवल टुकड़ों के सहेजे गए इंस्टेंस को संग्रहीत करता है, और जब आप अपना ध्यान केंद्रित करते हैं तो सभी टुकड़ों को नष्ट कर देते हैं।

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

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

  • जब मैं कहता हूं कि पूरे टुकड़े को स्मृति में रखा जाता है तो इसका मतलब है, इसके उदाहरण नष्ट हो जाएंगे और एक स्मृति उपरि पैदा करेंगे। इसलिए इसे FragmentPagerAdapterतभी उपयोग करने की सलाह दी जाती है, जब टुकड़ों की संख्या कम हो ViewPager

  • यह बेहतर होगा यदि टुकड़े स्थिर हैं, क्योंकि उनके पास बड़ी मात्रा में ऑब्जेक्ट नहीं होंगे जिनके उदाहरण संग्रहीत किए जाएंगे।

अधिक विवरण के लिए,

FragmentStatePagerAdapter:

  • के साथ FragmentStatePagerAdapter, आपका अनावश्यक टुकड़ा नष्ट हो जाता है। लेन-देन आपकी गतिविधि से पूरी तरह से टुकड़े को हटाने के लिए प्रतिबद्ध है FragmentManager

  • राज्य FragmentStatePagerAdapterइस तथ्य से आता है कि यह नष्ट होने पर आपके टुकड़े को बचाएगा BundlesavedInstanceStateजब उपयोगकर्ता वापस नेविगेट करता है, तो टुकड़े के राज्य का उपयोग करके नए टुकड़े को बहाल किया जाएगा।

FragmentPagerAdapter:

  • तुलना करने FragmentPagerAdapterसे कुछ भी नहीं होता है। जब टुकड़े की जरूरत नहीं रह जाती है। FragmentPagerAdapterके detach(Fragment)बजाय लेन-देन पर कॉल करता है remove(Fragment)

  • यह खंड के दृश्य को नष्ट कर देता है, लेकिन टुकड़े के उदाहरण को जिंदा छोड़ देता है। इन FragmentManagerटुकड़ों में बनाए गए टुकड़े FragmentPagerAdapterकभी नष्ट नहीं होते हैं।


2
आपके पास 2 उत्तर क्यों हैं?
जेरेड बुरो

स्मृति में पूरे टुकड़े रखने का क्या लाभ है?
टॉमाज़ मूलार्क

4
@ टोमेक: यदि अगला टुकड़ा पहले से ही इंस्टेंटेटेड है (यानी FragmentPagerAdapter), तो जब आप इसे स्वाइप करेंगे तो रेंडर करने के लिए तैयार हो जाएगा, इसलिए स्वाइप एनिमेशन स्मूद होगा। FragmentStatePagerAdapter के साथ, अगले टुकड़ा उदाहरण तब तक मौजूद नहीं हो सकता जब तक आप इसे स्वाइप नहीं करते हैं, और यदि यह एक बड़ा टुकड़ा है जो बनाने के लिए महंगा है, तो आप एनीमेशन में एक हकलाना देख सकते हैं। यह प्रदर्शन बनाम मेमोरी खपत का सवाल है।
डालबर्गिया

1
@Jared बिल bcoz एक बस है AnswerText जो छोटे और स्थिर जवाब के लिए अच्छा है और अन्य है AnswerStateText जो बड़ा और गतिशील जवाब के लिए है
सरल बंदे

48

यहां प्रत्येक टुकड़े का एक लॉग जीवनचक्र है ViewPagerजिसमें 4 टुकड़े हैं औरoffscreenPageLimit = 1 (default value)

FragmentStatePagerAdapter

Fragment1 (लॉन्च गतिविधि) पर जाएं

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

Fragment2 पर जाएं

Fragment3: onCreateView
Fragment3: onStart

Fragment3 पर जाएं

Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach
Fragment4: onCreateView
Fragment4: onStart

Fragment4 पर जाएं

Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy

FragmentPagerAdapter

Fragment1 (लॉन्च गतिविधि) पर जाएं

Fragment1: onCreateView
Fragment1: onStart
Fragment2: onCreateView
Fragment2: onStart

Fragment2 पर जाएं

Fragment3: onCreateView
Fragment3: onStart

Fragment3 पर जाएं

Fragment1: onStop
Fragment1: onDestroyView
Fragment4: onCreateView
Fragment4: onStart

Fragment4 पर जाएं

Fragment2: onStop
Fragment2: onDestroyView

निष्कर्ष : FragmentStatePagerAdapterकॉल onDestroyजब टुकड़ा दूर है offscreenPageLimit, जबकि FragmentPagerAdapterनहीं।

नोट : मुझे लगता है कि हमें बहुत सारे पेज के FragmentStatePagerAdapterलिए उपयोग करना चाहिए ViewPagerक्योंकि यह प्रदर्शन के लिए अच्छा होगा।

उदाहरण के offscreenPageLimit:

अगर हम Fragment3 पर जाते हैं, तो यह Fragment1 (या Fragment5 अगर होगा) को रोक देगाoffscreenPageLimit = 1 । यदि हम सेट offscreenPageLimit > 1करते हैं तो यह नष्ट नहीं होगा
यदि इस उदाहरण में, हम सेट करते हैं offscreenPageLimit=4, तो उपयोग करने के बीच कोई भिन्न नहीं है FragmentStatePagerAdapterया FragmentPagerAdapterक्योंकि Fragment कभी कॉल नहीं करता है onDestroyViewऔर onDestroyजब हम टैब बदलते हैं

यहाँ Github डेमो


निष्कर्ष का इतना बढ़िया तरीका!
राहुल रस्तोगी

अच्छी व्याख्या
सिंघल

1
अच्छी व्याख्या। आपने कहा कि बहुत सारे पृष्ठ होने पर FragmentStatePagerAdapter का उपयोग करना प्रदर्शन के लिए अच्छा है। क्या आपका मतलब है कि यह मेमोरी सेविंग के लिए अच्छा है? लक्ष्य के रूप में मैं समझता हूं कि यह संभव कई फ्रैगमेंट उदाहरणों के मामले में स्मृति को संरक्षित करना है - इसलिए प्रदर्शन का निहितार्थ लाभ है; स्पष्ट लक्ष्य स्मृति को संरक्षित करना है
हाटज़िल

38

प्रलेखन में या इस पृष्ठ पर दिए गए उत्तरों में स्पष्ट रूप से कुछ नहीं कहा गया है (भले ही @ नारुतो द्वारा निहित है), यह है कि FragmentPagerAdapterयदि फ्रेग्मेंट में डेटा में परिवर्तन होता है, तो यह फ्रैगमेंट को अपडेट नहीं करेगा क्योंकि यह फ्रैगमेंट को मेमोरी में रखता है।

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

यहां मेरा पूरा कहना यह है कि फ्रेगमेंट की संख्या और वे समान हैं या नहीं, इस पर विचार करने के लिए हमेशा महत्वपूर्ण पहलू नहीं होता है। आपके टुकड़े गतिशील हैं या नहीं यह भी महत्वपूर्ण है।


तो कहो कि मेरे पास 2 टुकड़े हैं, 1 पुनरावर्तन ए में टुकड़े ए, जब मैं एक आइटम पर क्लिक करता हूं तो यह टुकड़ा बी की सामग्री को बदलता है, कहते हैं कि मैं aromB.setText ("blablabla") करता हूं। मुझे राज्य के पेजरन का उपयोग करना चाहिए?
सीएसएस

निश्चित नहीं लेकिन मैं हां कहूंगा। बस दोनों का प्रयास करें, अपने कोड को एक से दूसरे में बदलने के लिए वास्तव में आसान और त्वरित है।
JDenais

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

14

FragmentPagerAdapterपिछले डेटा को एडॉप्टर से प्राप्त किया FragmentStatePagerAdapterजाता है, जबकि इसे निष्पादित किए जाने वाले एडॉप्टर से हर बार नया मूल्य लेता है।


4

FragmentStatePagerAdapter = बड़ी संख्या में टुकड़े को ViewPager में समायोजित करने के लिए। चूंकि यह एडॉप्टर उपयोगकर्ता को दिखाई नहीं देता है और इसे केवल उपयोग के लिए रखा जाता है। इस तरह कम मात्रा में मेमोरी का उपयोग किया जाता है और गतिशील टुकड़ों के मामले में बेहतर प्रदर्शन दिया जाता है।


1

FragmentPagerAdapter : उपयोगकर्ता के विज़िट के प्रत्येक पृष्ठ का टुकड़ा स्मृति में संग्रहीत किया जाएगा, हालांकि दृश्य नष्ट हो जाएगा। इसलिए जब पृष्ठ फिर से दिखाई देता है, तो दृश्य फिर से बनाया जाएगा लेकिन टुकड़े का उदाहरण फिर से नहीं बनाया जाएगा। इसके परिणामस्वरूप महत्वपूर्ण मात्रा में मेमोरी का उपयोग किया जा सकता है। FragmentPagerAdapter का उपयोग तब किया जाना चाहिए जब हमें मेमोरी में पूरे टुकड़े को स्टोर करने की आवश्यकता होती है। FragmentPagerAdapter हटाने (Fragment) के बजाय लेनदेन पर detach (Fragment) कहता है।

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

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