दूसरी बार देखे जाने के बाद FragmentPagerAdapter का उपयोग करके ViewPager में टुकड़ा


98

मेरे पास नीचे के साथ टैब के साथ एक खंड इंटरफ़ेस है जो मुख्य दृश्य में अलग-अलग टुकड़े खोलते हैं।

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

व्यूपेजर आइटम दिखाने के लिए एक FragmentPagerAdapter का उपयोग करता है।

समस्या तब आती है जब उपयोगकर्ता सूची में किसी आइटम का चयन करता है, उसे देखता है, फिर सूची पर वापस जाने के लिए टैब बार पर बटन दबाता है, फिर किसी अन्य आइटम का चयन करता है। दूसरी बार जब कोई आइटम चुना जाता है, तो दृश्यदर्शी के बजाय एक रिक्त स्क्रीन दिखाई देती है। ऐसा होने पर मुझे मेरे LogCat में कोई त्रुटि नहीं मिलती है।

दृश्यदर्शी केवल पहली बार क्यों दिखाई दे रहा है?

FragmentPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {
    Cursor mCursor;

    public ViewPagerAdapter(FragmentManager fm, Cursor c) {
        super(fm);
        mCursor = c;
    }

    public void changeCursor(Cursor c) {
        mCursor = c;
        this.notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (mCursor == null) return 0;
        else return mCursor.getCount();
    }

    @Override
    public Fragment getItem(int position) {
        mCursor.moveToPosition(position);
        return TeamCardFragment.newInstance(mCursor, position);
    }
}

PagerFragment:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Bundle bundle = getArguments();
    mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);

    View mView = inflater.inflate(R.layout.team_card_master, container, false);
    mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);

    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();

    return mView;
}

private class setAdapterTask extends AsyncTask<Void, Void, Void> {
    protected Void doInBackground(Void... params) {
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mViewPager.setAdapter(mAdapter);
        mViewPager.setCurrentItem(mCursorPosition);
    }
}

जवाबों:


221

मेरी भी यही समस्या थी। "दूसरी बार" पर मेरे प्रदर्शन मुद्दे android.support.v4.app.FragmentPagerAdapterको android.support.v4.app.FragmentStatePagerAdapterहल करने के लिए मेरे पेज एडेप्टर के मूल वर्ग को बदलना ViewPager!


2
मजाक नहीं? मेरे पास अब यह कोड नहीं है अन्यथा मैं इसका परीक्षण करूंगा। शायद यह जवाब किसी और की मदद करेगा।
howettl

10
क्या आदमी है! मैं इस समाधान के लिए दिनों की तलाश में था! एक टन आदमी का धन्यवाद, एक आकर्षण की तरह काम करता है। लेकिन मुझमें डेवलपर पूछ रहा है कि परिवर्तन क्या प्रभाव डालता है? मेरा मतलब है कि StatePagerAdapter में यह पहले और क्यों काम नहीं करता था
आनंद साईनाथ

1
इसके अलावा आपको @Override public int getItemPosition (ऑब्जेक्ट ऑब्जेक्ट) {रिटर्न POSITION_NONE की आवश्यकता है; }
हेलिन वांग

1
मेरे लिए भी काम किया। यहाँ एक लिंक है। यह खंडित स्थिति को बचाने के लिए लगता है, जिससे सभी अंतर होता है। डेवलपर
.android.com

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

87

मैं बदल कर भी इस का समाधान करने में कामयाब getFragmentManager()साथ getChildFragmentManager()माता पिता टुकड़ा में। यह पैरेंट फ़्रेग्मेंट android.support.v4.app.FragmentPagerAdapter को अस्थिर करने (स्लाइड करने योग्य) अंशों को बनाने के लिए प्रेरित कर रहा था, जिसके लिए कंस्ट्रक्टर में एक टुकड़ा प्रबंधक की आवश्यकता होती है। इस कंस्ट्रक्टर के लिए मैंने रिटर्न वैल्यू पास कीgetChildFragmentManager()

Hackbod की लिंक कुंजी थी ( https://developer.android.com/about/versions/android-4.2.html#NestedFragments ), जो इस पोस्ट में फ़्रैगमेंट्स के भीतर अंश में पाई गई थी

एक टुकड़ा घोंसला करने के लिए, बस getChildFragmentManager()उस टुकड़े पर कॉल करें जिसमें आप एक टुकड़ा जोड़ना चाहते हैं। यह एक FragmentManager देता है जिसका उपयोग आप उस तरह से कर सकते हैं जैसा कि आप सामान्य रूप से शीर्ष-स्तरीय गतिविधि से कर सकते हैं।


Thankyou ... मैं एक समान मुद्दा था, जो एक onresume () के बाद स्लाइडिंग टैब व्यू को फिर से इंस्टेंट करने की कोशिश कर रहा था, जिसमें एक फ़्रेग्मेंप्रैज़ेड एडाप्टर शामिल था ... मैं जिस ट्यूटोरियल का उपयोग करता था वह 2016 से था और इसे प्राप्त करने के लिए मुझे इसे टुकड़े टुकड़े करने के लिए इसे बदलने की आवश्यकता थी। काम। काश मैं जानता था।
Nerdy Bunz

इस उत्तर ने मेरा बहुत समय बचाया। क्योंकि केवल FragmentStatePagerAdapterdonot का उपयोग करके यहां पूछे गए प्रश्न को हल न करें। साथ FragmentStatePagerAdapterमें माता-पिता के टुकड़े YourAdapter adapter = new YourAdapter (getChildFragmentManager()); को भी जोड़ना होगा
MMK

17

मेरे लिए मुझे अपने व्यूअर पर यह कॉल करना पड़ा:

myViewPager.setSaveFromParentEnabled(false);

मेरे पास ऐसा मुद्दा था जहां दृश्य-चित्र ताज़ा नहीं था और मैंने देखा कि एक खाली सफेद स्क्रीन थी जहाँ टुकड़े होने चाहिए। मैं getChildFragmentManager में गुजर रहा था लेकिन इससे कोई फायदा नहीं हुआ।


1
दुनिया में यह काम क्यों किया? इससे मेरा मुद्दा ठीक हो गया लेकिन मुझे कोई सुराग नहीं मिला।
क्लेहरेंडीन

मैंने इसे अब अपने कोड से हटा दिया है। टुकड़ा प्रबंधक इस मुद्दे को पैदा कर रहा था। Getchildfragmentmanager और getfragmentmanager के बीच टॉगल करने की कोशिश करें
j2emanue

मैंने पहले ही कोशिश कर ली है। मैंने उन सभी व्यूवर्स के साथ टैब को नेस्ट किया है, जिन्होंने स्वाइपिंग को अक्षम कर दिया है। मुझे पता है कि यह खराब डिजाइन है लेकिन इसके ग्राहक मेरी इच्छा नहीं रखते। शीर्ष स्तर के टैब्बर के लिए चाइल्डफ्रैगमेंट मैनजर का उपयोग करके इम। निचले स्तर के टैब्बर / व्यूपेजर के लिए टॉगल करना समस्या को ठीक करने में नहीं लगता है। मुझे लगता है कि मैं अभी तक काम कर रहा हूँ क्योंकि मैं सेटसेवफ्रॉमपेंटेंट (झूठा) के साथ रहूँगा।
क्लेहरेंडीन

क्या आप नवीनतम समर्थन पुस्तकालय का उपयोग कर रहे हैं
j2emanue

2
मैं पिछले 2 दिनों से उसी मुद्दे का सामना कर रहा था .. आपके समाधान ने मेरे लिए काम किया। धन्यवाद !
बृजएक्सकोन

11

मेरे विशेष मामले में, जहाँ मैं एक AppBarLayout और ViewPager के साथ एक CoordinatorLayout का उपयोग कर रहा था, मेरे लिए इसे हल करना क्या मेरे AppBarlayout xml गुणों से android: fitSystemWindows = "true" को हटा रहा था ।

मुझसे मत पूछो क्यों। मुझे पता है कि यह थोड़ा हास्यास्पद लगता है और जैसे कि इसका कोई सहसंबंध नहीं होना चाहिए, लेकिन यह एक ही लाइन थी केवल एक चीज जो परेशानी पैदा कर रही थी क्योंकि मैं अपने एडेप्टर में getChildFragmentManager () का उपयोग कर रहा था। मैंने इसे खोजने के लिए पूरे दिन अपना कोड डिबगिंग में बिताया, इसलिए मुझे उम्मीद है कि यह किसी और को कुछ समय बचाता है।


3
ओह यार ... मैं इस मुद्दे के साथ लगभग आत्मसमर्पण करने वाला था। आपने मेरा विदाई का दिन बना दिया! Geez Google, WTF AppBarLayout के साथ गलत है? मैंने लगभग सौ पृष्ठों को देखा है और बिना किसी समस्या के इस समस्या को हल करने की कोशिश में एक घंटे का समय बिताया है। मैं वास्तव में आभारी हूं कि मैं आपकी टिप्पणी के साथ समस्या को हल करने में कामयाब रहा। आपका बहुत बहुत धन्यवाद! पुनश्च: मैं इतना हताश था कि मैंने AOSP में एक मुद्दा भी बनाया: code.google.com/p/android/issues/… XD
गुइल्म रोका

संकेत के लिए धन्यवाद। कम से कम इसने मसले को सुलझाने में हमारी मदद की है। अब हम इसे पूर्ण स्क्रीन बनाने के लिए विकल्प तलाशने की कोशिश कर रहे हैं
परेश मेयानी

आप एक जीवन रक्षक है! मैं पूरी तरह से क्लूलेस था कि मैं इस मुद्दे पर क्यों चल रहा था और अभी भी क्लूलेस क्यों काम कर रहा था!
नंदू

10

मेरे पास एक ही मुद्दा था जिसके लिए मैंने एडॉप्टर FragmentPagerAdapterको FragmentStatePagerAdapterऔर getFragmentManager()पेरेंट के टुकड़े में बदल दियाgetChildFragmentManager()

इसके पीछे का कारण FragmentStatePagerAdapterबड़ी संख्या में पृष्ठों को संग्रहीत करने में सहायक होता है और प्रत्येक पृष्ठ से जुड़ी मेमोरी कम होती है क्योंकि यह केवल खंड की बची हुई स्थिति को बनाए रखता है जबकि पृष्ठ दिखाई नहीं देता है। टुकड़ों के बीच स्विच करते समय यह ओवरहेड को कम करता है।


4

पैरेंट व्यूगरsetOffscreenPageLimit (int limit) पर डालने की कोशिश करें

mViewPager.setOffscreenPageLimit(totalPages-1);

इसने मेरे लिए आकर्षण की तरह काम किया।

मेरे मामले में मैं टुकड़ा अंदर था TabLayoutसाथViewPager.

और ViewPagerउस टुकड़े के अंदर एक और । पहली बार सभी ठीक काम कर रहे हैं, लेकिन जब मैं टैब बदलता हूं और वापस लौटता हूं, तो मेरा कुछ टुकड़ा खाली हो गया।


1
अच्छा उत्तर। यह मेरी मदद की है।
थिरुमलवलवन


1

हमने इसे पेजर आइटमों को पुन: लागू करने के बजाय टुकड़ों के बजाय मानक विचारों के अनुसार और एडेप्टर को बदलकर प्राप्त किया।


आप isViewFromObject (दृश्य देखें, ऑब्जेक्ट ऑब्जेक्ट) फ़ंक्शन को हटाने की कोशिश कर सकते हैं
मीना सामी

वहाँ एक बेहतर तरीका होना चाहिए ....: / हालांकि जितना अधिक मैं एंड्रॉइड में खुदाई करता हूं उतना कम परिपक्व मुझे एहसास होता है कि यह है।
स्टैकऑवरफ्लो

1
नेस्टेड टुकड़े का समर्थन नहीं किया जाता है , इसलिए मानक दृश्य के साथ फिर से लागू करना बेहतर तरीका है।
सिलफे

मैं इसी तरह के मुद्दे से जूझ रहा हूं। मैंने FragmentAdapter के बजाय PagerAdapter का उपयोग करने की कोशिश की फिर भी मैं उसी मुद्दे का सामना करता हूं। कृपया मेरी मदद करें !
गौरव अरोड़ा

यदि आप नेस्टेड अंशों का उपयोग करना चाहते हैं, तो आप इस उत्तर में दिए गए एडाप्टर का उपयोग कर सकते हैं: stackoverflow.com/questions/7700226/…
Slickelito

1

मैं एक ही स्क्रीन के साथ Xamarin Android पर एक ही समस्या हो रही थी दूसरी बार के आसपास .. मेरे लिए यह तय कर दिया।

viewPager.SaveFromParentEnabled = false;

0

आप उन मामलों के लिए भी एडेप्टर को इनिशियलाइज़ कर सकते हैं जब आप इस त्रुटि का अनुभव करते हैं जब आपका ऐप कम से कम हो जाता है और बाद में कॉल किया जाता है।

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Bundle bundle = getArguments();
    mCursorPosition = bundle.getInt(TeamCardCommon.BUNDLE_KEY_CURSOR_POSITION);
    View mView = inflater.inflate(R.layout.team_card_master, container, false);
    mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);
    initViewPagerAdapter();
    return mView;
}
private void initViewPagerAdapter(){
    mAdapter = new ViewPagerAdapter(getFragmentManager(), cursor);
    new setAdapterTask().execute();
}

@Override
public void onResume(){
    super.onResume();
    initViewPagerAdapter();
}

0

मेरे पास एक ही बात थी, दूसरी बार मैं पेजर एडेप्टर को कॉल करता हूं, चाइल्ड व्यू एक NullPointerException को वापस करता है। और FragmentStatePagerAdapter में एडेप्टर को बदलने से मेरी समस्या भी हल हो जाती है।


0

के बजाय उपयोग FragmentPagerAdapterमें बदलेंFragmentStatePagerAdaptergetChildFragmentManager()getFragmentManager()

getChildFragmentManager()- क्योंकि प्रलेखन के अनुसार, यह इस Fragment के अंदर Fragments रखने और प्रबंधित करने के लिए एक निजी FragmentManager लौटाएगा। इस बीच getFragmentManager()इस गतिविधि से जुड़े अंशों के साथ बातचीत करने के लिए फ्रैगमेंट मैनजर लौटाएगा


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