2012-08-04 27 views
5

próbuję przełączyć Fragments pomocą ViewPager + FragmentPagerAdapter. obecnie używam najnowszego wsparcia Android Pack v4: podczas korzystania ViewPager # setCurrentItem()

„java.lang.IllegalStateException nie można zmienić znacznik fragmentu” błędu

Mam 5 kart w mojej aplikacji. Kiedy wybiorę czwartą kartę, aplikacja nagle wychodzi i mówi "nie można zmienić znacznika fragmentu ~~".

Nie próbowałem zastąpić fragmentu zawartego w pliku xml układu, więc nie mogłem znaleźć przyczyny.

Oto kod, gdzie występuje błąd nr:

@Override 
public void onTabSelected(ActionBar.Tab tab, 
     FragmentTransaction fragmentTransaction) { 
    // When the given tab is selected, switch to the corresponding page in 
    // the ViewPager. 
    mViewPager.setCurrentItem(tab.getPosition()); 
} 

Poniżej fragment FragmentPagerAdapter Używam

@Override 
    public Fragment getItem(int i) { 
     if (fragment_list.get(i) == null) { 
      fragment_list.add(i, getFragment(i)); 
     } 

     return fragment_list.get(i); 
    } 

    private Fragment getFragment(int index) { 
     switch (index) { 
     case TOP: 
      return UseCaseListWithOptionFragment.newInstance(
        URLHelper.USE_CASES_TOP_URL, R.array.comment); 
     case FEED: 
      int user_id = UserHelper.getCurrentUser(MainActivity.this).id; 
      return UseCaseListFragment.newInstance(
        URLHelper.getMyFeedsURL(user_id), true); 
     case RECENT: 
      return UseCaseListFragment.newInstance(
        URLHelper.USE_CASES_RECENT_URL, true); 
     case CATEOGORY: 
      return UseCaseGroupListFragment.newInstance(
        URLHelper.USE_CASE_GROUPS_URL, R.array.use_case); 
     case MY: 
      return UserProfileFragment.newInstance(UserHelper 
        .getCurrentUser(MainActivity.this)); 
     default: 
      throw new IllegalStateException("Tab index out of bound."); 
     } 
    } 

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

Poniżej znajduje się dziennik błędów spotykam:

08-04 17:51:55.983: E/AndroidRuntime(1112): FATAL EXCEPTION: main 
08-04 17:51:55.983: E/AndroidRuntime(1112): java.lang.IllegalStateException: Can't change tag of fragment UseCaseGroupListFragment{4055f558 id=0x7f050034 android:switcher:2131034164:3}: was android:switcher:2131034164:3 now android:switcher:2131034164:4 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:356) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:347) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:99) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:692) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.view.ViewPager.populate(ViewPager.java:875) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:469) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:441) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:422) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at org.everyuse.android.activity.MainActivity.onTabSelected(MainActivity.java:176) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at com.actionbarsherlock.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:526) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at com.actionbarsherlock.internal.app.ActionBarImpl$TabImpl.select(ActionBarImpl.java:907) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at com.actionbarsherlock.internal.widget.ScrollingTabContainerView$TabClickListener.onClick(ScrollingTabContainerView.java:503) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.view.View.performClick(View.java:2485) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.view.View$PerformClick.run(View.java:9080) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.os.Handler.handleCallback(Handler.java:587) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.os.Handler.dispatchMessage(Handler.java:92) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.os.Looper.loop(Looper.java:123) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at java.lang.reflect.Method.invokeNative(Native Method) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at java.lang.reflect.Method.invoke(Method.java:507) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
08-04 17:51:55.983: E/AndroidRuntime(1112):  at dalvik.system.NativeStart.main(Native Method) 

Z góry dziękuję ...

+0

czynić u mieć odpowiedź teraz? – singhsumit

+1

Twoja implementacja 'public Fragment getItem (int)' wydaje się trochę dziwna. Co by się stało, gdyby 'getItem (4)' został wywołany przed 'getItem (3)'? Wyobrażam sobie, że na liście pojawiłby się wyjątek IndexOutOfBoundsException. To się tutaj nie dzieje, ale możesz rozważyć nieco inne podejście i ostatecznie rozwiązać problem. – mkasberg

Odpowiedz

4

Doświadczyłem tego samego wyjątku, gdy niepoprawnie implementuję metodę getCount. Czy sprawdziłeś, czy zwracany jest prawidłowy rozmiar?

@Override 
public int getCount() { 
    return 5; 
} 
+0

Też miałem problemy z tym, co okazało się niedopasowanym 'publicznym int getCount()', jak zasugerował bogdan. – mkasberg

1

widzę, że to było podczas gdy zadał to pytanie, ale dla przyszłego użytkownika, który może sprostać ten problem także ...

miałem dokładnie ten sam błąd na niektórych urządzeniach, a ja nie mogłem znajdź jakikolwiek reasone, dopóki nie zobaczę komentarza @ mkasberg ... Jakimś sposobem metoda getItem może zostać wywołana nie w kolejności, może dlatego, że niektóre urządzenia przetwarzają szybciej lub nie wiem, ale użycie sparseArray zamiast arrayList rozwiązało mój problem. Dzięki!

I tu, jak można to zrobić:

public Fragment getItem(int i) { 
    if (sparseArray.get(i) == null) { 
     sparseArray.put(i, getFragment(i)); 
    } 

    return sparseArray.get(i); 
} 
Powiązane problemy