java.lang.IllegalStateException: Can't change tag of fragment xxxFragment

来源:互联网 发布:北外网络教育 编辑:程序博客网 时间:2024/05/29 18:43

        在应用里用到了 ViewPager 和 FragmentPagerAdapter  实现多页滑动,每一页都是一个Fragment。

        当需要对某个Fragment进行操作时,就要获取到这个Fragment(Fragment之间通信有几种方式,在这直说Tag),但是并没有去设置Tag。当我们通过getFragmentManager().beginTransaction().add(xxxFragment, "tag")方式去添加的时候会出现异常:

 java.lang.IllegalStateException: Can't change tag of fragment OrderJXZFragment{412af788 #4 OrderJXZFragment}: was OrderJXZFragment now android:switcher:2131231294:1

该非法异常是说我们不能去修改Fragment的Tag,因为已经设置了。那我们什么时候设置过呢,当然是通过FragmentPagerAdapter 进行设置的,下面我们看看源码:

@Overridepublic Object instantiateItem(ViewGroup container, int position) {if (mCurTransaction == null) {mCurTransaction = mFragmentManager.beginTransaction();}final long itemId = getItemId(position);// Do we already have this fragment?String name = makeFragmentName(container.getId(), itemId);Fragment fragment = mFragmentManager.findFragmentByTag(name);if (fragment != null) {if (DEBUG)Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);mCurTransaction.attach(fragment);} else {fragment = getItem(position);if (DEBUG)Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);mCurTransaction.add(container.getId(), fragment,makeFragmentName(container.getId(), itemId));}if (fragment != mCurrentPrimaryItem) {fragment.setMenuVisibility(false);fragment.setUserVisibleHint(false);}return fragment;}
看一下5-9行,最关键在第8行 makeFragmentName(container.getId(), itemId) 方法,第一个参数为viewpager的id,第二个参数为fragment在viewpager中的id,通过第5行可知是通过getItemId(position)来获取的。 那么接下来我们看看makeFragmentName(container.getId(), itemId)方法的实现:

private static String makeFragmentName(int viewId, long id) {return "android:switcher:" + viewId + ":" + id;}
很简单就是返回一个固定字符串加viewId的值和id的值。

        下面就是获取Tag的方法:

         重写MyFragmentPagerAdapter的instantiateItem方法(最好的方式,Fragment在viewpager中初始化时都已经获取到了Tag,不影响其他地方根据tag获取Fragment):

@Overridepublic Object instantiateItem(ViewGroup container, int position) {// TODO Auto-generated method stub//return super.instantiateItem(container, position);Fragment fragment = (Fragment) super.instantiateItem(container, position);if(fragment instanceof xxxFragment){mTags = fragment.getTag();Log.e("MyFragmentPagerAdapter instantiateItem", mTags);}                return fragment;}
从打印的信息就可以看到Tag的格式,通过该Tag就可以在其他地方来获取要操作的Fragment进行操作。

打印信息:

11-10 14:26:24.269: E/MyFragmentPagerAdapter instantiateItem(26912): android:switcher:2131231294:1
通过Tag获取Fragment:

          FragmentManager fm = getFragmentManager();          xxxFragment of = (xxxFragment ) fm.findFragmentByTag(mTags);




0 0