Android玩转ViewPager(一) 实现循环滚动
2018-03-24 18:06
183 查看
循环滚动应用场景还是较多的,这里是支付宝一个例子
两个ImageVIew并提供了自动轮播以及手动无限翻页的功能。
先总结一下VIewPager的基础。
继承了ViewGroup所以本身用于存放View,而自动翻页的特效无非就是自身Canvas的移动,通过Scroll来实现。
我们自定义一个类直接继承它并实现抽象方法
FragmentPagerAdapter
官方实现的一个可以添加Fragment的ViewPager适配器,当然我们也需要再次继承它来放入Fragment。
可以看到使用这个适配器我们的代码量是很少的,只需要提供相对应的Fragment即可,而具体的添加移除细节我们则不用考虑。
具体加载方法适配器本身已经做到了
FragmentStatePagerAdapter
方法竟与FragmentPagerAdapter完全一样? 没错FragmentPagerAdapter与FragmentStatePagerAdapter都是实现了ViewPager加载Fragment,只是加载的机制不同,前者在内部会有一个缓存机制,也就是说不同的Fragment只调用一次getItem(int position)方法,当前页面超过了ViewPager本身的加载数量后不对其进行销毁,具体可自行百度Fragment的生命周期。所以用这个适配器时可在Fragment内部缓存View即缓存我们对View的操作,所以一般常用app的主界面。而后者体现在销毁上,当偏离了ViewPager加载的数量后对其Fragment进行销毁,所以再次需要Fragment时又要重新调用getItem(int position)方法,因此用这个适配器在Fragment内部不能缓存View,所以常用展示量较大的场景。
这是笔者演示定义的一个简单例子,这个方法提供了两个参数(page:VIewPager指定加载(缓存)几个View后,这些View都会被分别传入进来,position:这个position不同于适配器的position,这个是根据View的顺序以及在屏幕中展示的位置来确定的)
笔者方便说明画了个图,这个ViewPager宽度刚好被两个View所填充,那么此时View1的postion为-1,view2为-0.5,view3为0,view4为0.5,也就是说当一个View刚好碰到ViewPager的left时候值为0,碰到right时候值为1,在其内部则为0-1,假定ViewPager缓存的VIew为无穷大,那么最左边的postion为负无穷大,右边为正无穷大。所以我们可以根据滑动过程传入的值来自定义我们想要的动画了。
实现FragmentStatePagerAdapter
配置VIewPager
看下效果图
是不是可以多次看到这个小美女相同的照片了。 ok,手动循环滚动就搞定了,自动的无非就是多加行代码而已,
viewPager.setCurrentItem()
这个方法用于设定ViewPager的显示位置,虽说有动画效果不过速度较快,需要修改速度就要用到反射改变ViewPager内部的Scroller,具体自行百度。
ViewPager+Fragment的懒加载见下篇。
两个ImageVIew并提供了自动轮播以及手动无限翻页的功能。
先总结一下VIewPager的基础。
ViewPager是什么
继承了ViewGroup所以本身用于存放View,而自动翻页的特效无非就是自身Canvas的移动,通过Scroll来实现。
PagerAdapter是什么
PagerAdapter称ViewPager的适配器,为什么叫适配器呢,一种设计模式其实就是提供了相关的View给ViewPager,在ViewPager展示很多内容情况下如果将所有的View都添加到ViewPager上,则给内存带来了不必要的开销,所以ViewPager有个缓存机制,每次从PagerAdapter拿取设定数量的View,随着用户滑动而不断地销毁本身已展示过的View并从PagerAdapter拿取新的View。而PagerAdapter本身为抽象类,所以详见它的具体实现类。PagerAdapter的具体实现类
myPagerAdapter extends PagerAdapter我们自定义一个类直接继承它并实现抽象方法
public class myPagerAdapter extends PagerAdapter { @Override public int getCount() { return 0; //告诉ViewPager有多少View需要展示 } @Override public boolean isViewFromObject(View view, Object object) { return view == object; //确定一个页面视图是否关联到一个特定的对象,一般返回这个判断 } @Override public Object instantiateItem(ViewGroup container, int position) { //这里的container则是ViewPager本身,position是当前需要展示View的位置 {......我们的代码} //在这里我们将View添加到ViewPager //所以当ViewPager需要新的View的情况下就会调用这个方法 } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); {....我们的代码} //于此相对销毁展示过的View调用这个方法, position为需要销毁View的位置 } }
FragmentPagerAdapter
官方实现的一个可以添加Fragment的ViewPager适配器,当然我们也需要再次继承它来放入Fragment。
public class myFragementAdapter extends FragmentPagerAdapter { public myFragementAdapter(FragmentManager fm) { super(fm); //操作Fragment必然需要一个FragmentManager } @Override public Fragment getItem(int position) { {.....我们的代码} //同上ViewPager需要的Fragment从这里获取,position为需要展示的位置 } @Override public int getCount() { return 0; //需要展示Fragment的数量 } }
可以看到使用这个适配器我们的代码量是很少的,只需要提供相对应的Fragment即可,而具体的添加移除细节我们则不用考虑。
具体加载方法适配器本身已经做到了
FragmentStatePagerAdapter
public class myFragementAdapter extends FragmentStatePagerAdapter { public myFragementAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { } @Override public int getCount() { return 0; } }
方法竟与FragmentPagerAdapter完全一样? 没错FragmentPagerAdapter与FragmentStatePagerAdapter都是实现了ViewPager加载Fragment,只是加载的机制不同,前者在内部会有一个缓存机制,也就是说不同的Fragment只调用一次getItem(int position)方法,当前页面超过了ViewPager本身的加载数量后不对其进行销毁,具体可自行百度Fragment的生命周期。所以用这个适配器时可在Fragment内部缓存View即缓存我们对View的操作,所以一般常用app的主界面。而后者体现在销毁上,当偏离了ViewPager加载的数量后对其Fragment进行销毁,所以再次需要Fragment时又要重新调用getItem(int position)方法,因此用这个适配器在Fragment内部不能缓存View,所以常用展示量较大的场景。
ViewPager.PageTransformer
该接口主要规定了ViewPager在切换View这个过程中多次调用的方法,其实就是动画的实现方法public class fadeInFadeOut implements ViewPager 4000 .PageTransformer { @Override public void transformPage(View page, float position) { if(position<1&&position>0){ page.setAlpha(1-position); } else if(position>-1&&position<0){ page.setAlpha(1+position); } } }
这是笔者演示定义的一个简单例子,这个方法提供了两个参数(page:VIewPager指定加载(缓存)几个View后,这些View都会被分别传入进来,position:这个position不同于适配器的position,这个是根据View的顺序以及在屏幕中展示的位置来确定的)
笔者方便说明画了个图,这个ViewPager宽度刚好被两个View所填充,那么此时View1的postion为-1,view2为-0.5,view3为0,view4为0.5,也就是说当一个View刚好碰到ViewPager的left时候值为0,碰到right时候值为1,在其内部则为0-1,假定ViewPager缓存的VIew为无穷大,那么最左边的postion为负无穷大,右边为正无穷大。所以我们可以根据滑动过程传入的值来自定义我们想要的动画了。
ViewPager的循环滑动
实现循环滑动则需要做到将相同的View在不同的position展示出来即可,所以我们用到FragmentStatePagerAdapter实现FragmentStatePagerAdapter
public class myFragementAdapter extends FragmentStatePagerAdapter { List<Fragment> list; //方便起见我们直接创建一个List,List其实对于PagetAdapter是没有意义的 public myFragementAdapter(FragmentManager fm, List<Fragment> li) { super(fm); list = li; //在构造函数中传入包含一定数量的Fragment的List } @Override public Fragment getItem(int position) { return list.get(position % list.size()); //当读取到集合最后一位时又从第一位开始读取。 } @Override public int getCount() { return Integer.MAX_VALUE; } }
配置VIewPager
public class MainActivity extends AppCompatActivity { ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); viewPager = (ViewPager) findViewById(R.id.packager); //找到ViewPager对象 int[] ints = {R.mipmap.one, R.mipmap.two, R.mipmap.there, R.mipmap.four}; //定义一个图片资源地址数组用于产生不同的IamgeView List<android.support.v4.app.Fragment> list = ImageViewUtil.getFragmentList(this, ints); //笔者定义的一个工具类,主要就是传入资源数组生成一个包裹Fragment的List myFragementAdapter myPagerAdapter = new myFragementAdapter(getSupportFragmentManager(), list); viewPager.setOffscreenPageLimit(1); //设置ViewPager的加载(缓存)数量,默认为1,指的同时加载超出ViewPager外的View左右两端数量各为1. viewPager.setAdapter(myPagerAdapter); viewPager.setPageTransformer(true, new fadeInFadeOut()); //自定义的翻页动画 } }
看下效果图
是不是可以多次看到这个小美女相同的照片了。 ok,手动循环滚动就搞定了,自动的无非就是多加行代码而已,
handler.postDelayed(new Runnable() { @Override public void run() { viewPager.setCurrentItem(viewPager.getCurrentItem() + 1); handler.postDelayed(this, 2000); } }, 2000);
viewPager.setCurrentItem()
这个方法用于设定ViewPager的显示位置,虽说有动画效果不过速度较快,需要修改速度就要用到反射改变ViewPager内部的Scroller,具体自行百度。
ViewPager+Fragment的懒加载见下篇。
完
相关文章推荐
- Android实现真正的ViewPager【平滑过渡】+【循环滚动】!!!顺带还有【末页跳转】。
- 【Android】ViewPager实现无限循环滚动
- Android ViewPager巧用偷梁换柱实现自动循环滚动
- android ViewPager实现循环滚动效果
- Android ViewPager的无限循环与自动滚动实现
- android viewpager实现无限循环自动滚动
- Android_ViewPager_实现多个图片水平滚动
- Viewpager + Fragment +FragmentPagerAdapter实现定时循环滚动效果
- 利用ViewPager和CirclePageIndicator实现新闻循环滚动
- Android ViewPager 实现无限循环滑动
- viewpager实现无限循环滚动幻灯片
- Android使用ViewPager实现左右循环滑动及轮播效果
- Android使用ViewPager实现左右循环滑动及轮播效果
- Android自动滚动 轮播循环的ViewPager
- Android 使用ViewPager实现左右循环滑动图片
- Android_ViewPager_实现多个图片水平滚动
- Android 使用ViewPager实现左右循环滑动图片
- Android中ViewPager无限循环实现方法
- android viewpager 实现左右无限循环
- 利用ViewPager实现图片循环滚动