打造Android 最实用的ViewPager 指示器控件

为什么我说它是最实用的 ViewPager 指示器控件呢? 它有以下几个特点: 1、通过自定义 View 来实现,代码简单易懂; 2、使用起来非常方便; 3、通用性高,,大部分涉及到 ViewPager 指示器的地方都能使用此控件; 4、实现了两种指示器效果,传统版指示器和流行版指示器(具体请看效果图)

一、先来看效果图 传统版指示器的效果图:

流行版指示器的效果

二、分析 如果单纯的要实现此功能,相信,大家都能实现,而我也不会拿出来这里讲了,这里我是要把它打造成一个控件,通俗一点讲就是,在以后可以直接拿来用,而不需要修改代码。 控件,那就离不开自定义 View,我在前面也讲了一篇关于自定义 View 的文章 Android自定义View,你必须知道的几点 ,虽然讲的很浅,但我觉得还是非常有用处的,有兴趣的可以阅读一下,对理解这篇文章很有帮助。额,跑题了! 回顾下那两张效果图,整个 View 需要的资源其实只有两张图片;唯一的难点,就是对图片绘制的位置如何计算;既然是实现通用型易用的控件,那就不能再 ViewPager 的 OnPagerChangerListener 中来改变指示器的状态,所以这个时候,就得把 ViewPager 传入到这个控件中,到这里,分析的差不多了;

三、编码实现功能 像白饭要一口一口的吃,这里就得先创建一个类,然后让他继承之 View,前期步骤跟我的上一篇 blog 很像,就不累赘了,直接上代码

.Drawable mIndicator;mIndicatorSize ;mWidth ;mContextWidth ;mCount ;mMargin ;mSelectItem ;mOffset ;mSmooth ;/*因为ViewPager 的 pageChangeListener 被占用了,所以需要定义一个* 以便其他调用* */private ViewPager.OnPageChangeListener mPageChangeListener ;public IndicatorView(Context context) {this(context, null);}public IndicatorView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//通过 TypedArray 获取自定义属性TypedArray typedArray = getResources().obtainAttributes(attrs, R.styleable.IndicatorView);//获取自定义属性的个数int N = typedArray.getIndexCount();for (int i = 0; i < N; i++) {int attr = typedArray.getIndex(i);switch (attr) {case R.styleable.IndicatorView_indicator_icon://通过自定义属性拿到指示器mIndicator = typedArray.getDrawable(attr);break;case R.styleable.IndicatorView_indicator_margin:float defaultMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,5,getResources().getDisplayMetrics());mMargin = (int) typedArray.getDimension(attr , defaultMargin);break ;case R.styleable.IndicatorView_indicator_smooth:mSmooth = typedArray.getBoolean(attr,false) ;break;}}//使用完成之后记得回收typedArray.recycle();initIndicator() ;}() {//获取指示器的大小值。一般情况下是正方形的,也是时,你的美工手抖了一下,切出一个长方形来了,//不用怕,这里做了处理不会变形的mIndicatorSize = Math.max(mIndicator.getIntrinsicWidth(),mIndicator.getIntrinsicHeight()) ;/*设置指示器的边框*/mIndicator.setBounds(0,0,mIndicator.getIntrinsicWidth(),mIndicator.getIntrinsicWidth());}}

这里需要注意一点的就是 Drawable mIndicator这个成员变量,它是在 drawable 文件夹下定义的一个 drawable 文件,包含了选中和为选中两张图片。

接着是测量工作

/*** 测量View 的大小,这个方法我前面的 blog 讲了很多了,* @param widthMeasureSpec* @param heightMeasureSpec*/(int widthMeasureSpec, int heightMeasureSpec) {setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));}/*** 测量宽度,计算当前View 的宽度* @param widthMeasureSpec* @return*/(int widthMeasureSpec){int mode = MeasureSpec.getMode(widthMeasureSpec) ;int size = MeasureSpec.getSize(widthMeasureSpec) ;int width ;int desired = getPaddingLeft() + getPaddingRight() + mIndicatorSize*mCount + mMargin*(mCount -1) ;mContextWidth = desired ;if(mode == MeasureSpec.EXACTLY){width = Math.max(desired, size) ;}else {if(mode == MeasureSpec.AT_MOST){width = Math.min(desired,size) ;}else {width = desired ;}}mWidth = width ;return width ;}(int heightMeasureSpec){int mode = MeasureSpec.getMode(heightMeasureSpec) ;int size = MeasureSpec.getSize(heightMeasureSpec) ;int height ;if(mode == MeasureSpec.EXACTLY){height = size ;}else {int desired = getPaddingTop() + getPaddingBottom() + mIndicatorSize ;if(mode == MeasureSpec.AT_MOST){height = Math.min(desired,size) ;}else {height = desired ;}}return height ;}而消极的人则在每个机会都看到某种忧患。

打造Android 最实用的ViewPager 指示器控件

相关文章:

你感兴趣的文章:

标签云: