Android ViewPager用法

本文详细介绍了Android中ViewPager的使用,包括PagerAdapter的适配器模式,如何处理Fragment,以及如何实现页面切换的监听和动画。重点讲解了FragmentPagerAdapter和FragmentStatePagerAdapter的区别,以及如何根据业务需求选择合适的适配器。此外,还探讨了设置页面间距和添加转场动画的方法,提供了多种动画效果的实现示例。
摘要由CSDN通过智能技术生成

1.适配器PagerAdapter

ViewPager使用适配器类将数据和view的处理分离,ViewPager的适配器叫PagerAdapter,这是一个抽象类,不能实例化,所以它有两个子类:FragmentPagerAdapter 和 FragmentStatePagerAdapter,这两个都是处理页面为Fragment的情况。而PagerAdapter则是处理通用View的适配器,但是使用它的时候一定要自定义一个类继承这个基类。

private class Adapter extends PagerAdapter {

    public Object instantiateItem(ViewGroup container, int position) {

        //container其实就是ViewPager

        View itemView = LayoutInflater.from( context).inflate(R.layout.item_pager, null);

        container.addView(itemView);

        return itemView;

    }

    @Override

    public void destroyItem(ViewGroup container, int position, Object object) {

        // object为instantiateItem返回的object对象

        container.removeView((View) object);

    } 

    @Override

    public int getCount() { 

        return 10; //获取viewpager页数

    }

    @Override

    public boolean isViewFromObject(View view, Object o) {

      //判断view和o是否存在对应关系,内部是通过view找到对应的object的关联关系(instantiateItem中返回的object)。如果在instantiateItem方法中返回的是view,那这里就返回view == o

        return view == o;

    }

}

PageAdapter主要有以下几个方法:

①Object instantiateItem(ViewGroup container, int position)

这个方法在ViewPager需要加载某个页面时调用,container就是ViewPager自己,position是页面索引;

这个方法需要实现的是添加一个view到container中,然后返回一个跟这个view能够关联起来的对象,这个对象可以是view自身,也可以是其他对象(比如FragmentPagerAdapter返回的就是一个Fragment),关键是在isViewFromObject能够将view和这个object关联起来。

②void destroyItem(ViewGroup container, int position, Object object)

当ViewPager需要销毁一个页面时调用,在这个方法里需要将position对应的view从container中移除。

这个方法有三个参数,container就是ViewPager自己,position是页面索引,第三个参数object就是instantiateItem方法返回的对象。

在这个方法里需要通过object找到对应的View,然后将其移除掉,如果instantiateItem方法返回的就是View,就直接将object强转成View移除即可:container.removeView((View) object);如果不是,一般会自己创建一个List缓存view列表,然后根据position从List中找到对应的view移除(如果不移除,会产生内存泄漏)。FragmentPagerAdapter的实现是:mCurTransaction.detach((Fragment)object),其实也就是将fragemnt的view从container中移除

③isViewFromObject(View view, Object object)

这个方法用来说明instantiateItem方法中向container中添加的view和方法返回的对象两者之间一对一的关系。因为在ViewPager内部有个方法叫infoForChild,这个方法是通过view去找到对应页面信息缓存类ItemInfo(内部调用了isViewFromObject),如果找不到,ViewPager会认为不是Adapter提供的View,所以这个View不会显示出来。所以说,isViewFromObject方法是让view和object(内部为ItemInfo)一一对应起来。

④int getItemPosition(Object object)

该方法是判断当前object对应的View是否需要更新,在调用notifyDataSetChanged时会间接触发该方法。如果返回POSITION_UNCHANGED,表示该页面不需要更新;如果返回POSITION_NONE则表示该页面无效了,需要销毁并触发destroyItem方法(并且有可能调用instantiateItem重新初始化这个页面)。

从这几个方法就可以看出ViewPager的工作流程:在注册Adapter和draw绘制等时机,会调用 getCount()确定需要显示的子View的数量,然后在真正addView()加载子View的时候会调用instantiateItem()获取具体要显示的View,然后在装载显示的时候又会调用isViewFromObject()方法再次确认类型正确,然后在ViewPager不需要某个View的时候,会调用destroyItem()方法请求销毁。

 

2.FragmentPagerAdapter

子View是Fragment的情景比较常见,而Fragment的管理是个麻烦事,意味着Adapter中更多的代码量,针对这种情况,谷歌推荐开发者直接继承PagerAdapter的两个直接子类FragmentPagerAdapter和FragmentStatePagerAdapter,这样就不用关注Fragment的管理,只需要提供两个方法就行了。

FragmentPagerAdapter是一个不管理Fragment状态的适配器。这就意味着,许多碎片的Fragment会占用大量的内存(在少数情况下Fragment还是有可能会丢失的),如果在Fragment页面较少,或者每个Fragment页面中持有的数据较少的情况下,可以选择使用较为简单的适配器,不用关注并管理 Fragment 的状态,加快业务开发。

另一种情况是当大量碎片的Fragment占用的内存是不能被容忍,这时FragmentStatePagerAdapter就派上用场了,这个适配器保存并绑定了状态,在状态为销毁的状态下,可以去重新获取。但是频繁创建又会导致切换页面的性能消耗。所以在选择适配器的时候,要根据具体的业务逻辑进行判断,选择合适的适配器。

这两个子类的区别主要是Fragment内存管理状态的不同。为了验证,在Fragment的生命周期中添加Log。

采用了FragmentPagerAdapter 的Log记录:

//滑到第一页

MessageFragment: ---onAttach----

MessageFragment: ---onCreate----

FriendFragment: ---onAttach----

FriendFragment: ---onCreate----

MessageFragment: ---onCreateView---

FriendFragment: ---onCreateView---

//滑到第二页

CircleFragment: ---onAttach----

CircleFragment: ---onCreate----

CircleFragment: ---onCreateView---

//滑到第三页

AccountFragment: ---onAttach----

AccountFragment: ---onCreate----

MessageFragment: ----onDestroyView---

AccountFragment: ---onCreateView---

//滑到第四页

FriendFragment: ----onDestroyView---

 

采用了FragmentStatePagerAdapter的Log记录:

//滑到第一页

MessageFragment: ---onAttach----

MessageFragment: ---onCreate----

FriendFragment: ---onAttach----

FriendFragment: ---onCreate----

MessageFragment: ---onCreateView---

FriendFragment: ---onCreateView---

//滑到第二页

CircleFragment: ---onAttach----

CircleFragment: ---onCreate----

CircleFragment: ---onCreateView---

//滑到第三页

AccountFragment: ---onAttach----

AccountFragment: ---onCreate----

MessageFragment: ----onDestroyView---

MessageFragment: ----onDestroy--- (不同的地方)

MessageFragment: ----ondetach--- (不同的地方)

AccountFragment: ---onCreateView---

//滑到第四页

FriendFragment: ----onDestroyView---

FriendFragment: ----ondestroy--- (不同的地方)

FriendFragment: ----ondetach--- (不同的地方)

不更改ViewPager的预加载状态的情况下,翻到第一页(MessageFragment)和翻到第二页(FriendFragment)的时候,两个Adapter完全相同,这是因为这个时候根据ViewPager的缓存策略,会缓存3个子View,提高加载速度和显示流畅性。看日志可以证明:翻到第二页的时候第三个Fragment(CircleFragment)已经完成了加载操作,而且这个时候还没有回调Fragment卸载的相关方法。

翻到第三页(CircleFragment)和第四页(AccountFragment)的时候,出现了不同:当翻到第三页的时候,因为要提前加载第四页(AccountFragment),又由于缓存的数量是3,所以第一页(MessageFragment)开始回调卸载方法。使用FragmentPagerAdapter的回调了 onDestroyView卸载方法;使用FragmentStatePagerAdapter的回调了onDestroyView、onDestroy、onDetach卸载方法。当翻到第四页(AccountFrag

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ViewPager是一个Android支持库中的类,它允许用户在不同的页面之间进行滑动。在Android Studio中使用ViewPager的步骤如下: 1. 在build.gradle文件中添加ViewPager的依赖: ``` dependencies { implementation 'com.android.support:viewpager:28.0.0' } ``` 2. 在XML布局文件中添加ViewPager: ``` <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3. 创建一个FragmentPagerAdapter或FragmentStatePagerAdapter的子类: ```java public class MyPagerAdapter extends FragmentPagerAdapter { private final List<Fragment> mFragmentList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>(); public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return mFragmentList.get(position); } @Override public int getCount() { return mFragmentList.size(); } public void addFragment(Fragment fragment, String title) { mFragmentList.add(fragment); mFragmentTitleList.add(title); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position); } } ``` 4. 在Activity或Fragment中设置ViewPager的适配器: ```java MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new Fragment1(), "Fragment 1"); adapter.addFragment(new Fragment2(), "Fragment 2"); adapter.addFragment(new Fragment3(), "Fragment 3"); ViewPager viewPager = findViewById(R.id.view_pager); viewPager.setAdapter(adapter); ``` 5. (可选)如果你想要使用TabLayout来帮助用户切换页面,可以使用以下代码: ```java TabLayout tabLayout = findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); ``` 这样就可以在Android应用中使用ViewPager了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值