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

        在应用里用到了 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 进行设置的,下面我们看看源码:

	@Override
	public 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):

	@Override
	public 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);




你可能感兴趣的:(Android开发)