使用 ViewPager#setCurrentItem() 时出现“java.lang.IllegalStateException: Can't change tag of fragment”错误
Posted
技术标签:
【中文标题】使用 ViewPager#setCurrentItem() 时出现“java.lang.IllegalStateException: Can\'t change tag of fragment”错误【英文标题】:"java.lang.IllegalStateException: Can't change tag of fragment" error when using ViewPager#setCurrentItem()使用 ViewPager#setCurrentItem() 时出现“java.lang.IllegalStateException: Can't change tag of fragment”错误 【发布时间】:2012-08-02 09:27:36 【问题描述】:我正在尝试使用ViewPager + FragmentPagerAdapter.
切换片段
我目前正在使用最新的 android 支持包 v4
我的应用中有 5 个标签。当我选择第 4 个选项卡时,应用程序突然退出并显示“无法更改片段的标签 ~~”。
我没有尝试替换布局xml文件中包含的Fragment,所以我无法找出原因。
出现错误的代码如下:
@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());
下面是我正在使用的 FragmentPagerAdapter 的片段
@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;
以下是我遇到的错误日志:
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 UseCaseGroupListFragment4055f558 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)
提前谢谢...
【问题讨论】:
你现在有答案了吗? 您对public Fragment getItem(int)
的实现似乎有点奇怪。如果在getItem(3)
之前调用getItem(4)
会发生什么?我想你会在列表中得到一个 IndexOutOfBoundsException 。此处不会发生这种情况,但您可能会考虑采用稍微不同的方法并最终解决问题。
【参考方案1】:
我在错误地实现 getCount 方法时遇到了同样的异常。你检查过是否返回了正确的尺寸吗?
@Override
public int getCount()
return 5;
【讨论】:
我也遇到了这个问题,正如 bogdan 建议的那样,结果证明public int getCount()
不匹配。【参考方案2】:
我看到你问这个问题已经有一段时间了,但对于未来可能面临这个问题的用户来说......
我在某些设备上遇到了完全相同的错误,直到我看到 @mkasberg 的评论之前我找不到任何理由... 不知何故 getItem 方法可能被不按顺序调用,可能是因为某些设备处理速度更快或者我没有不知道,但是使用 sparseArray 而不是 arrayList 解决了我的问题。 谢谢!
这里是你如何做到的:
public Fragment getItem(int i)
if (sparseArray.get(i) == null)
sparseArray.put(i, getFragment(i));
return sparseArray.get(i);
【讨论】:
以上是关于使用 ViewPager#setCurrentItem() 时出现“java.lang.IllegalStateException: Can't change tag of fragment”错误的主要内容,如果未能解决你的问题,请参考以下文章
Android ------ ViewPager1和ViewPager2的使用
Android ------ ViewPager1和ViewPager2的使用
Android ------ ViewPager1和ViewPager2的使用
如何在viewPager的视图顶部使用nestedScrollView中的viewpager