ViewPager中adapter基本使用总结

21 篇文章 2 订阅

ViewPager的基本使用

ViewPager和TabLayout的使用:

https://developer.android.com/guide/navigation/navigation-swipe-view

  • PagerAdapter

    主要用于加载页面是view时

    可实现针对View的广告栏滑动效果

    • instantiateItem(ViewGroup, int)

      创建并添加子控件,实例化控件

    • destroyItem(ViewGroup, int, Object)

      判断滑动的控件是否超出了缓存范围,如果超出则销毁,移除不需要的子view控件

    • getCount()

      获取viewpager要显示控件的数量

    • isViewFromObject(View, Object)

      判断两个对象是否相等,是否需要重新生成子view

    • getPageTitle(int position)

      设置标签页的标题

    • saveState();
      finishUpdate();
      getPageTitle();
      getPageWidth();
      registerDataSetObserver();
      unregisterDataSetObserver();
      startUpdate();
      restoreState();
      

    FragmentPagerAdapter与FragmentStatePagerAdapter的区别

  • 共同点

    两者都主要用于加载页面是fragment时

    都是抽象类,并且都继承于PagerAdapter

    使用时都要实现getItem()与getCount()两个抽象方法

  • 区别

    • FragmentPagerAdapter

      FragmentPagerAdapter会将每一个生成的Fragment保存在内存中,所以只适用于页面较少的情况。如果页面比较多,会导致占用较大内存,影响用户体验。

          @Override
          public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
              Fragment fragment = (Fragment) object;
              if (mCurTransaction == null) {
                  mCurTransaction = mFragmentManager.beginTransaction();
              }
              mCurTransaction.detach(fragment);
              if (fragment == mCurrentPrimaryItem) {
                  mCurrentPrimaryItem = null;
              }
          }
      

      destroyItem()中调用了detach方法,将Fragment从Activity中分离,会销毁其View,但不会销毁Fragment的实例,因此fragment还在FragmentManager的管理中,fragment所占用的资源部不会被释放。

    • FragmentStatePagerAdapter

      只保留当前页面,当页面离开视线后,就会将fragment消除,释放资源,在需要fragment需要显示的时候,生成新的页面,好处是不会占用大量内存

      //源码中有两个重要的变量
      ArrayList<Fragment.SavedState> mSavedState;		//缓存fragment的状态
      ArrayList<Fragment> mFragments;					//缓存fragment
      

      如果页面不显示了,则在destroyItem()方法中将fragment从mFragments中移除,并且保存fragment的状态在mSaveState中

      显示的会放入mFragments中保存

          @Override
          public void destroyItem(ViewGroup container, int position, Object object) {
              Fragment fragment = (Fragment) object;
      
              if (mCurTransaction == null) {
                  mCurTransaction = mFragmentManager.beginTransaction();
              }
              if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object
                      + " v=" + ((Fragment)object).getView());
              while (mSavedState.size() <= position) {
                  mSavedState.add(null);
              }
              mSavedState.set(position, fragment.isAdded()
                      ? mFragmentManager.saveFragmentInstanceState(fragment) : null);
              mFragments.set(position, null);
      
              mCurTransaction.remove(fragment);
          }
      
  • 总结

    FragmentPagerAdapter

    适用于较少的页面,占用内存

    FragmentStatePagerAdapter

    适用于不确定数量,较多数量的页面时使用,大量页面时不会占用大量内存

    这里需要注意一个问题,在 Fragment 没有被添加到 FragmentManager 之前,我们可以通过 Fragment.setArguments() 来设置参数,并在 Fragment 中,使用 getArguments() 来取得参数。这是常用的参数传递方式。但是这种方式对于我们说的情况不适用。因为这种数据传递方式只可能用一次,在 Fragment 被添加到 FragmentManager 后,一旦被使用,我们再次调用 setArguments() 将会导致 java.lang.IllegalStateException: Fragment already active 异常。因此,我们这里的参数传递方式选择是,在继承的 Fragment 子类中,新增几个 setter,然后通过这些 setter 将数据传递过去。反向也是类似。这些 setter 中要注意不要操作那些 View,这些 View 只有在 onCreateView() 事件后才可以操作。

     @Override
     public Fragment getItem(int position) {
         MyFragment f = new MyFragment();
         return f;
     }
      
     @Override
     public Object instantiateItem(ViewGroup container, int position) {
         MyFragment f = (MyFragment) super.instantiateItem(container, position);
         String title = mList.get(position);
         f.setTitle(title);
         return f;
     }
      
     @Override
     public int getItemPosition(Object object) {
         return PagerAdapter.POSITION_NONE;
     }
    
  • 参考

    https://blog.csdn.net/JSON_ZJS/article/details/78894404

    https://blog.csdn.net/Jack_King007/article/details/41413405?utm_source=itdadao&utm_medium=referral

    viewpager使用其他的相关参考

    https://www.jianshu.com/p/f70073f7e837

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值