Android 实现带指示器的自动轮播式ViewPager

最近在做项目的时候,有个需求就是实现自动轮播式的ViewPager,最直观的例子就是知乎日报顶部的ViewPager,它内部有着好几个子view,每个一段时间便自动滑动到下一个item view,而底部的指示器也随之跟着改变。使用这种ViewPager的好处是在有限的空间内可以展示出多样化的信息。轮播式ViewPager广泛应用于各种应用内部,用于展示广告等。抱着学习和分享的目的,笔者把轮播式ViewPager写成了一个独立的控件,以方便以后的使用。

效果展示

话不多说,我们先来看看实现的效果是怎样的:

从上面的动态图可以看到,当我们手指拖动ViewPager的时候,下方的指示器随着页面的滑动而滑动,当点击添加数据的按钮的时候,ViewPager的数据项变多,同时下方的指示器也随之改变,适应了数据项的数目。

从上面的动态图可以看到,当我们不用手指进行拖动的时候,该ViewPager会每隔4s左右的时间自动进行滚动,滚动到最后一个item view的时候,下一次会滚到第一个位置。

GitHub地址及使用介绍

读者可以直接到我的GitHub中获取源码。 GitHub:BannerViewPager,控件及其相关文件都放在了该目录下的library模块内,而app模块则是上面效果展示的一个简单应用。

通过以下几个步骤,就能方便地使用该控件了: 1、像普通的ViewPager一样,在布局文件中放入该控件如下:

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”xmlns:tools=”http://schemas.android.com/tools”android:layout_width=”match_parent”android:layout_height=”match_parent”android:orientation=”vertical”><com.chenyu.library.bannerViewPager.BannerViewPagerandroid:id=”@+id/banner”android:layout_width=”match_parent”android:layout_height=”200dp”></com.chenyu.library.bannerViewPager.BannerViewPager><!– others –></LinearLayout>

2、获取BannerViewPager的实例,进行相应的配置,比如我们使用ViewPager的时候,也需要设置它的适配器等。这里笔者实现了一个ViewPagerAdapter,用作BannerViewPager的适配器:

//获取BannerViewPager实例bannerViewPager = (BannerViewPager) findViewById(R.id.banner);//实例化ViewPagerAdapter,第一个参数是View集合,第二个参数是页面点击监听器mAdapter = new ViewPagerAdapter(mViews, new OnPageClickListener() {@Overridepublic void onPageClick(View view, int position) {Log.d(“cylog”,”position:”+position);}});//设置适配器bannerViewPager.setAdapter(mAdapter);

和一般的ViewPager没什么两样,都是:获取实例——创建适配器——设置适配器。而适配器的数据集一般都是一个View集合,用作ViewPager的item view,所以需要事先准备好相应的View集合。此外,一般轮播式ViewPager点击某一项后会打开相应的页面,所以这里提供了一个OnPageClickListener的监听器,在创建适配器的时候同时创建该监听器即可。

原理简析

接下来,笔者将简要分析BannerViewPager的实现思路,具体的请读者参考源码~

实现自动滚动

首先,我们先思考一下,系统自带的ViewPager是一个独立控件,没有指示器,也没有自动滚动的功能,但是它是一个现成的,可左右滑动的控件,我们肯定是需要ViewPager的,因此,我们可以利用一个布局,把ViewPager包裹起来,同时在这个布局里面再放入indicator(指示器)。

那么,第一步,先新建BannerViewPager.java继承自FrameLayout,而这个FrameLayout有两个子元素:ViewPager和indicator。至于indicator,下面会说到。在构造函数内对这两个控件进行初始化先:

public class BannerViewPager extends FrameLayout implements ViewPager.OnPageChangeListener {private ViewPager mViewPager;private ViewPagerIndicator mIndicator;private ViewPagerAdapter mAdapter;//…public BannerViewPager(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;initViews();}private void initViews() {//initialize the viewpagermViewPager = new ViewPager(mContext);ViewPager.LayoutParams lp = new ViewPager.LayoutParams();lp.width = ViewPager.LayoutParams.MATCH_PARENT;lp.height = ViewPager.LayoutParams.MATCH_PARENT;mViewPager.setLayoutParams(lp);//initialize the indicatormIndicator = new ViewPagerIndicator(mContext);FrameLayout.LayoutParams indicatorlp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);indicatorlp.gravity = Gravity.BOTTOM | Gravity.CENTER;indicatorlp.bottomMargin = 20;mIndicator.setLayoutParams(indicatorlp);}//省略…}

这里没什么好说的,主要是对ViewPager和ViewPagerIndicator进行初始化,设置它们的布局参数以便在FrameLayout中得到正确的显示。 接着,对ViewPager实现自动滚动,这个的实现原理也不难,我们只要知道每时每刻的ViewPager的滑动状态、当前的page position值即可,而ViewPager有这样一个监听器:ViewPager.OnPageChangeListener,只要ViewPager进行了滑动,就会回调这个监听器的如下几个方法:

public interface OnPageChangeListener {//只要ViewPager进行了滑动,该方法就会回调public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);//当前页面被选定的时候,回调public void onPageSelected(int position);//ViewPager的状态发生改变的时候,回调public void onPageScrollStateChanged(int state);}不会因为别人显赫的成功而促使自己有卓越的进步。

Android 实现带指示器的自动轮播式ViewPager

相关文章:

你感兴趣的文章:

标签云: