26

notifyDataSetChanged मैं ActionBar Android दस्तावेज़ here से लिया टैब के साथ ViewPager उदाहरण उपयोग कर रहा हूँ।IllegalStateException: आवेदन के PagerAdapter PagerAdapter # बुला बिना एडाप्टर के सामग्री बदल

दुर्भाग्य से, जैसे ही मैंने addTab विधि निम्न अपवादों के साथ अनुप्रयोग क्रैश फोन:

IllegalStateException: आवेदन के PagerAdapter PagerAdapter # notifyDataSetChanged बुला बिना एडाप्टर की सामग्री बदल गया है! उम्मीद एडाप्टर आइटम गिनती 0, पाया 1.

यह FragmentPagerAdapter कोड है:

public static class TabsAdapter extends FragmentPagerAdapter 
      implements ActionBar.TabListener, ViewPager.OnPageChangeListener { 
     private final Context mContext; 
     private final ActionBar mActionBar; 
     private final ViewPager mViewPager; 
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

     static final class TabInfo { 
      private final Class<?> clss; 
      private final Bundle args; 

      TabInfo(Class<?> _class, Bundle _args) { 
       clss = _class; 
       args = _args; 
      } 
     } 

     public TabsAdapter(Activity activity, ViewPager pager) { 
      super(activity.getFragmentManager()); 
      mContext = activity; 
      mActionBar = activity.getActionBar(); 
      mViewPager = pager; 
      mViewPager.setAdapter(this); 
      mViewPager.setOnPageChangeListener(this); 
     } 

     public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { 
      TabInfo info = new TabInfo(clss, args); 
      tab.setTag(info); 
      tab.setTabListener(this); 
      mTabs.add(info); 
      mActionBar.addTab(tab); 
      notifyDataSetChanged(); 
     } 

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

     @Override 
     public Fragment getItem(int position) { 
      TabInfo info = mTabs.get(position); 
      return Fragment.instantiate(mContext, info.clss.getName(), info.args); 
     } 

     @Override 
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     } 

     @Override 
     public void onPageSelected(int position) { 
      mActionBar.setSelectedNavigationItem(position); 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      Object tag = tab.getTag(); 
      for (int i=0; i<mTabs.size(); i++) { 
       if (mTabs.get(i) == tag) { 
        mViewPager.setCurrentItem(i); 
       } 
      } 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction ft) { 
     } 
    } 
} 

मैं अपने कोड के किसी अन्य भाग में मेरी अनुकूलक को संशोधित नहीं कर रहा हूँ और मैं addTab फोन कर रहा हूँ मुख्य धागे से विधि, addTab विधि notifyDataSetChanged पर कॉल के साथ समाप्त होती है। जैसा कि दस्तावेज करने की सिफारिश करता है:

पेजर एडाप्टर डेटा सेट परिवर्तनों का समर्थन करता है। डेटा सेट परिवर्तन मुख्य थ्रेड पर होना चाहिए और बेसएडाप्टर से व्युत्पन्न एडाप्टर व्यू एडाप्टर के समानडेटाडेटा() को सूचित करने के लिए कॉल के साथ समाप्त होना चाहिए।

उत्तर

18

मुझे अपने ViewPager काम करने में कठिन समय था। अंत में, ऐसा लगता है कि प्रलेखन में उदाहरण गलत है।

public void addTab(Tab tab, Class<?> clss, Bundle args) { 
     TabInfo info = new TabInfo(clss, args); 
     tab.setTag(info); 
     tab.setTabListener(this); 
     mTabs.add(info); 
     notifyDataSetChanged(); 
     mActionBar.addTab(tab); 
    } 

सूचना पिछले तीन आपरेशन के आदेश:

addTab विधि इस प्रकार होना चाहिए। मूल उदाहरण में, notifyDataSetChanged को mActionBar.addTab फ़ंक्शन के बाद बुलाया गया था।

दुर्भाग्य से, जैसे ही आप पर ActionBar पर कॉल करते हैं, तो आपके द्वारा जोड़े जाने वाला पहला टैब स्वचालित रूप से चुना जाता है। इस वजह से, onTabSelected ईवेंट निकाल दिया गया है और पृष्ठ को पुनर्प्राप्त करने का प्रयास करते समय, यह IllegalStateException को ट्राउज़ करता है क्योंकि यह अपेक्षित आइटम गणना और वास्तविक एक के बीच एक विसंगति को नोटिस करता है।

+0

मैं थोड़ी देर के लिए इस तलाश रहे हैं काम किया। क्या मैं अकेला हूं जो इसे अजीब लगता है कि त्रुटि पढ़ती है जैसे कि मैं अधिसूचना को कॉल नहीं कर रहा हूंडेटाट चेंज(), जब मुझे वास्तव में कार्रवाई करने की आवश्यकता होती है (मेरे मामले में setCurrentItem) सूचित करने के बादडेटाट चेंज()? – wizurd

8

मैं) notifyDataSetChanged (callinig द्वारा यह तय एक बार और सिर्फ getCount() की अगली कॉल करने से पहले:

private boolean doNotifyDataSetChangedOnce = false; 

@Override 
public int getCount() { 

    if (doNotifyDataSetChangedOnce) { 
    doNotifyDataSetChangedOnce = false; 
    notifyDataSetChanged(); 
    } 

    return actionBar.getTabCount(); 

} 

private void addTab(String text) { 

    doNotifyDataSetChangedOnce = true; 

    Tab tab = actionBar.newTab(); 
    tab.setText(text); 
    tab.setTabListener(this); 
    actionBar.addTab(tab); 

} 

private void removeTab(int position) { 

    doNotifyDataSetChangedOnce = true; 

    actionBar.removeTabAt(position); 

} 
+0

यहां अच्छी चीजें हैं ... धन्यवाद! – worked

0

मैं FragmentStatePager अनुकूलक में एक ही समस्या थी। onResume() में जब विज्ञापनदाता को फिर से शुरू करें और ViewPager, वही त्रुटि IllegalStateException दिखाई देगी। समाधान:

टैब addtab जोड़ते समय, सेट चयनित चयन पैरा को गलत पर सेट करके चयनित नहीं किया गया है।

actionBar.addTab(tab,false); 

मैं अपवाद है क्योंकि निम्न

viewPager.setCurrentItem(tab.getPosition()); 

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

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

:

3

मैं getCount() में टैब का हवाला आप की तरह इस त्रुटि हो रही थी संग्रह पॉप्युलेट/उत्परिवर्तित किया गया है।

0

मेरा मुद्दा बिल्कुल वही नहीं था, लेकिन समान संदर्भ था।

मेरे पास एक अलर्टडिअलॉग एक लेआउट में दिखाया गया है जिसमें ViewPager है और AppCompatActivity का उपयोग कर रहा है। स्क्रीन को घूर्णन करते समय मुझे IllegalStateException और क्रैश हो रहा था।

उत्तर @almisoft और @Zagorax के उत्तरों के लिए धन्यवाद, मैंने संवाद दिखाने से ठीक पहले notifyDataSetChanged(); पर कॉल करने का प्रयास किया, और समस्या दूर हो गई प्रतीत होती है।

1

इसे आजमाएं। मैं

protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      System.out.println("Asyncrona onPostExecute"); 
      /*::::::::::::::::::: Guardo los cambios ::::::::::::::*/ 
      //menuTabs = menuTabs2; 
      viewPager = (ViewPager) rootView.findViewById(R.id.viewPager_menu); 
      costumAdapter = new CostumAdapter2(getActivity().getSupportFragmentManager()); 
      costumAdapter.notifyDataSetChanged(); 

      viewPager.setAdapter(costumAdapter); 
      tabLayout = (TabLayout) rootView.findViewById(R.id.tablayout_menu); 
      tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
       @Override 
       public void onTabSelected(TabLayout.Tab tab) { 
        System.out.println(" La Seleccionado: " + tab.getText()+", POSICION: "+tab.getPosition()); 
        viewPager.setCurrentItem(tab.getPosition()); 
       } 

       @Override 
       public void onTabUnselected(TabLayout.Tab tab) { 
        viewPager.setCurrentItem(tab.getPosition()); 
       } 

       @Override 
       public void onTabReselected(TabLayout.Tab tab) { 
        viewPager.setCurrentItem(tab.getPosition()); 
       } 

      }); 
      viewPager.setAdapter(costumAdapter); 
      tabLayout.setupWithViewPager(viewPager); 
      loading.closeMessage(); 

     } 
0

एक पंक्ति जवाब सिर्फ viewpageadapter.notifyDataSetChanded जोड़ने()

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