Fragment(三)ViewPager中使用Fragment

Fragment(三)ViewPager中使用Fragment

博客对应的Demo地址:GitHubGitee

通过这篇博客,我们能知道以下问题:

  • Fragment 加载到 ViewPage上的过程和用户可见性判断
  • Fragment 加载到 ViewPage2上的过程和用户可见性判断

ViewPager 中使用 Fragment

1. Fragment 怎样加载到 ViewPage

使用 ViewPager需要一个 PagerAdapter,我们如果使用 Fragment 填充 ViewPager 的话,需要使用的是 FragmentPagerAdapter 或者 FragmentStatePagerAdapter ,当然这两个 Adapter 都是继承至 PagerAdapter 的,这两个 Adapter 有什么差别,在后面我们会说到。

对于 PagerAdapter 我们主要看三个方法 instantiateItem()destroyItem()setPrimaryItem()

  • instantiateItem():创建 ViewPager 页面时调用
  • destroyItem():移除 ViewPager 页面时调用
  • setPrimaryItem()ViewPager 页面改变显示位置时调用(比如调用 adapter.setCurrentItem() 方法时)

当然还有两个方法 startUpdate()finishUpdate(),分别表示将要开始改变位置和位置改变完成时调用,代码比较简单,直接看一下。就不多说了【FragmentPagerAdapterFragmentStatePagerAdapter 中都一样】

@Override
public void startUpdate(@NonNull ViewGroup container) {
    if (container.getId() == View.NO_ID) {
        throw new IllegalStateException("ViewPager with adapter " + this
                + " requires a view id");
    }
}

@Override
public void finishUpdate(@NonNull ViewGroup container) {
	if (mCurTransaction != null) {
	    if (!mExecutingFinishUpdate) {
	        try {
	            mExecutingFinishUpdate = true;
	            mCurTransaction.commitNowAllowingStateLoss();
	        } finally {
	            mExecutingFinishUpdate = false;
	        }
	    }
	    mCurTransaction = null;
	}
}
ViewPager 改变位置时的方法调用顺序

当改变 ViewPager 的位置时,方法的调用顺序为: startUpdate() -> instantiateItem()【ViewPager 中的 addNewItem() 方法内部调用】 -> destroyItem() -> setPrimaryItem() -> finishUpdate()

注意:因为 ViewPager 的缓存和预加载机制,instantiateItem()destroyItem()方法会调用多次,并且顺序并非一个调用多次之后另一个在调用多次,而是交叉的调用。

instantiateItem() 方法解析

Fragment 加载到 ViewPage 上,主要在 instantiateItem() 方法中:

  • FragmentPagerAdapter

      // FragmentPagerAdapter 类
      public Object instantiateItem(@NonNull ViewGroup container, int position) {
          if (mCurTransaction == null) {
              mCurTransaction = mFragmentManager.beginTransaction();
          }
    
          final long itemId = getItemId(position);
    
          String name = makeFragmentName(container.getId(), itemId);
      	// 当前需要显示的Fragment,是否已经存在
          Fragment fragment = mFragmentManager.findFragmentByTag(name);
          if (fragment != null) {
      		// 存在,调用 attach() 方法
              mCurTransaction.attach(fragment);
          } else {
      		// 不存在,调用 add() 方法
              fragment = getItem(position);
              mCurTransaction.add(container.getId(), fragment,
                      makeFragmentName(container.getId(), itemId));
          }
    
          return fragment;
      }
    

    先通过 FragmentManager 判断将要显示的 Fragment 是否已经在容器中存在,如果存在调用 FragmentTransaction#attach() 方法,否则通过 getItem(position) 方法获取将要显示的 Fragment,然后调用 FragmentTransaction#add() 方法将 Fragment 添加到容器中。<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值