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.BannerViewPager
        android: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() {
    @Override
    public 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 viewpager
        mViewPager = 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 indicator
        mIndicator = n
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值