fragment的getChildFragmentManager与getFragmentManager方法

前提:这次项目中采用了在fragment中添加了一个viewpager的形式,viewpager中切换的是fragment。


BUG:退出了那个包含viewpager的fragment并重新进入,切换viewpager时,不调用fragmentpageradapter适配器的getItem()方法,在显示上,出现viewpager的显示数量增多、显示数据不正确(这个情况只在初始化fragment时,需要传递参数的情况)的情况。


调试:fragmentpageradapter的instantiateItem(ViewGroup container, int position)方法,在调用的时候做了优化处理:


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;
}


以上代码中,会先判断是否已经加载过这个fragment,如果加载过,就只进行attach操作,不会进行实例化,这样可以节约资源。在上面的前提下,debug到这时第二次进入到fragment后,切换内部的fragment时,在此处mFragmentManager.findFragmentByTag(name);方法返回值都不为空,所以导致了上面提到的BUG。


解决:在实例化FragmentPagerAdapter类时,需要传递两个参数,将第一个参数设置为getChildFragmentManager()而非getFragmentManager()即可解决问题。


fragment源码中有getFragmentManager()的说明:

/**
     * Return the FragmentManager for interacting with fragments associated
     * with this fragment's activity.  Note that this will be non-null slightly
     * before {@link #getActivity()}, during the time from when the fragment is
     * placed in a {@link FragmentTransaction} until it is committed and
     * attached to its activity.
     *
     * <p>If this Fragment is a child of another Fragment, the FragmentManager
     * returned here will be the parent's {@link #getChildFragmentManager()}.
     */
    final public FragmentManager getFragmentManager() {
        return mFragmentManager;
    }

可以理解为:

getFragmentManager()是所在fragment 父容器的碎片管理,
getChildFragmentManager()是在fragment  里面子容器的碎片管理。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值