16

मेरी गतिविधि TabLayout + ViewPager का उपयोग करती है।IllegalStateException: खंड का टैग नहीं बदला जा सकता था एंड्रॉइड: स्विचर अब एंड्रॉइड: स्विचर

3 स्थैतिक टैब + गतिविधि 3 बनाई जाती है जब गतिविधि बनाई जाती है। उसके बाद, मेरा ऐप कुछ दूरस्थ वस्तुओं को प्राप्त करता है और उन दूरस्थ वस्तुओं को प्राप्त करने के लिए अतिरिक्त टैब + टुकड़े प्रस्तुत करता है। हर समय, 3 प्रारंभिक टैब + टुकड़े पहले गतिशील टैब + टुकड़े के बाद होते हैं।

क्रैशलिटिक्स के माध्यम से दुर्घटना की सूचना दी गई है, मैं इसे दोहराने में सक्षम नहीं हूं।

मेरे अभ्यास कोड:;:

public class MyTabsAdapter extends FragmentPagerAdapter { 

    private List<FragmentWithTitle> mTabs = new ArrayList<>(); 

    public MyTabsAdapter(FragmentManager fm, List<FragmentWithTitle> sdsTabs) { 
     super(fm); 
     this.mTabs = sdsTabs; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return mTabs.get(position).getFragment(); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     return mTabs.get(position).getTitle(); 
    } 

    @Override 
    public int getCount() { 
     return this.mTabs.size(); 
    } 

    public int getItemPosition(Object object) { 
     return POSITION_NONE; 
    } 

    /** 
    * Prevent java.lang.IllegalStateException Fragment no longer exists for key android:target_state: index 5 
    * 
    * @return 
    */ 
    @Override 
    public Parcelable saveState() { 
     return null; 
    } 

    public ArrayList<String> getTitles() { 
     ArrayList<String> titles = new ArrayList<>(); 
     for (int i = 0; i < mTabs.size(); i++) { 
      titles.add((String) mTabs.get(i).getTitle()); 
     } 
     return titles; 
    } 

    public void addTab(FragmentWithTitle fragmentWithTitle) { 
     mTabs.add(fragmentWithTitle); 
    } 
} 

पूर्ण स्टैकट्रेस: ​​

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     boolean isAppRestarting = PrefUtils.getBoolean("app_restarting", false); 
     if (isAppRestarting) { 
      super.onCreate(null); 
      this.savedInstanceState = null; 
     } else { 
      super.onCreate(savedInstanceState); 
      this.savedInstanceState = savedInstanceState; 
     } 

     initSlidingTabs(); 

     fetchSomeData(); // callback onDataFetched() 
    } 

private void initSlidingTabs() { 
     List<FragmentWithTitle> sdsTabs = new ArrayList<>(); 
     if (savedInstanceState == null) { 
      sdsTabs.add(new FragmentWithTitle(ShopFrag.newInstance(), "ShopFrag")); 
      sdsTabs.add(new FragmentWithTitle(FragB.newInstance(), "FragB")); 
      sdsTabs.add(new FragmentWithTitle(FragC.newInstance(), "FragC")); 
     } else { 
      Logger.i("There is saved instance state"); 
      ArrayList<String> titles = savedInstanceState.getStringArrayList(TAB_TITLES); 
      if (titles != null) { 
       for (int i = 0; i < titles.size(); i++) { 
        if (getFragment(i) != null) { 
         sdsTabs.add(new FragmentWithTitle(getFragment(i), titles.get(i))); 
        } 
       } 
      } 
     } 

     mTabsAdapter = new MyTabsAdapter(getSupportFragmentManager(), sdsTabs); 

     // Assigning ViewPager View and setting the mTabsAdapter 
     mViewPager = (ViewPager) findViewById(R.id.layoutViewPagerSlidingTabs); 
     mViewPager.setAdapter(mTabsAdapter); 
     mViewPager.setOffscreenPageLimit(2); 

     mSlidingTabs = (CustomTextTabLayout) findViewById(R.id.tabs); 
     mSlidingTabs.setupWithViewPager(mViewPager); 
} 

@Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     if (mTabsAdapter != null) { 
      outState.putStringArrayList(TAB_TITLES, mTabsAdapter.getTitles()); 
     } 
    } 

    private Fragment getFragment(int position) { 
     Logger.d("getFragment " + position); 
     return savedInstanceState == null ? mTabsAdapter.getItem(position) : getSupportFragmentManager() 
       .findFragmentByTag(getFragmentTag(position)); 
    } 

    private String getFragmentTag(int position) { 
     return "android:switcher:" + R.id.layoutViewPagerSlidingTabs + ":" + position; 
    } 

/** 
Callback of fetchData() in onCreate() 
*/ 
private void onDataFetched(List<ProductCategory> cats) { 
     if (savedInstanceState == null) { 
      if (cats != null) { 
       for (ProductCategory cat : cats) { 
        mTabsAdapter.addTab(new FragmentWithTitle(CategoryFrag.newInstance(cat.getSlugUrl()), cat 
          .getLabel())); 
       } 
      } 
     } else { 
      Logger.d("There is saved instance state"); 
      ArrayList<String> titles = savedInstanceState.getStringArrayList(TAB_TITLES); 
      if (titles != null) { 
       for (int i = 0; i < titles.size(); i++) { 
        mTabsAdapter.addTab(new FragmentWithTitle(getFragment(i), titles.get(i))); 
       } 
      } 
     } 

     mTabsAdapter.notifyDataSetChanged(); 
    } 

MyTabsAdapter (नकल की और इंटरनेट से चिपकाया saveState() विधि समझ में नहीं आता है, बाकी कुछ खास नहीं लगता है)

Fatal Exception: java.lang.IllegalStateException: Can't change tag of fragment ShopFrag{4dbb6e90 #0 id=0x7f1200dd android:switcher:2131886301:0}: was android:switcher:2131886301:0 now android:switcher:2131886301:9 
     at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:444) 
     at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:426) 
     at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:103) 
     at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1038) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1252) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1120) 
     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1646) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 
     at android.view.View.measure(View.java:17396) 
     at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1081) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
     at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:695) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:588) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2505) 
     at android.view.View.measure(View.java:17396) 
     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2175) 
     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1316) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1513) 
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1200) 
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6401) 
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803) 
     at android.view.Choreographer.doCallbacks(Choreographer.java:603) 
     at android.view.Choreographer.doFrame(Choreographer.java:573) 
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789) 
     at android.os.Handler.handleCallback(Handler.java:733) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:157) 
     at android.app.ActivityThread.main(ActivityThread.java:5335) 
     at java.lang.reflect.Method.invokeNative(Method.java) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081) 
     at dalvik.system.NativeStart.main(NativeStart.java) 

FragmentWithTitle:

public class FragmentWithTitle { 
    public FragmentWithTitle(Fragment mFragment, CharSequence mTitle) { 
     this.fragment = mFragment; 
     this.title = mTitle; 
    } 

    public Fragment getFragment() { 
     return fragment; 
    } 

    public void setFragment(Fragment fragment) { 
     this.fragment = fragment; 
    } 

    public CharSequence getTitle() { 
     return title; 
    } 

    public void setTitle(CharSequence title) { 
     this.title = title; 
    } 

    private Fragment fragment; 
    private CharSequence title; 
} 
+2

की तरह एक बहुत ध्वनि: [टुकड़ा त्रुटि के टैग नहीं बदला जा सकता है - एक PagerAdapter उपयोग करने के लिए कोशिश कर रहा है स्विचिंग के लिए] (http://stackoverflow.com/questions/24355838/cant-change-tag-of-fragment-error-trying-to-use-a-pageradapter-for-switching)। – Tigger

+0

मुझे पता है, इसे पढ़ें लेकिन मैं उत्तर से कुछ भी लागू नहीं कर सकता @ टिगर – ericn

+0

कृपया अपनी कक्षा 'फ्रैगमेंट विथटिटल' –

उत्तर

12

FragmentPagerAdapter पहले से ही आपके लिए Fragments कैश करता है। प्रत्येक खंड को एक टैग असाइन किया जाता है, और फिर FragmentPagerAdapterfindFragmentByTag पर कॉल करने का प्रयास करता है। यह केवल getItem() पर कॉल करता है यदि findFragmentByTag का परिणाम null है।

आपको शायद यह त्रुटि मिल रही है क्योंकि आप सूची में एक ही खंड उदाहरण जोड़ रहे हैं। आपको प्रत्येक पृष्ठ के लिए नया उदाहरण बनाना चाहिए।

उदाहरण प्रपत्र दस्तावेज़:

//... 
     public static class MyAdapter extends FragmentPagerAdapter { 
      public MyAdapter(FragmentManager fm) { 
       super(fm); 
      } 

      @Override 
      public int getCount() { 
       return NUM_ITEMS; 
      } 

      @Override 
      public Fragment getItem(int position) { 
       return ArrayListFragment.newInstance(position); 
      } 
     } 
    //.. 

देखें: FragmentPagerAdapter

मुख्य धागा: Retrieve a Fragment from a ViewPager

+0

धन्यवाद @Charu ක, स्मृति प्रबंधन के मामले में कोई कमी है? – ericn

+1

@eric का मतलब है कि आप नए उदाहरण को वापस कर सकते हैं, मुझे लगता है कि नहीं, इसे केवल कॉल कहा जाता है फ्रैगमेंटबिटैग शून्य है http://stackoverflow.com/questions/19339500/when-is-fragmentpageradapters-getitem-called http://stackoverflow.com/questions/12581896/fragmentpageradapter-GetItem-है-नहीं बुलाया –

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