一步一步,自定义viewPager指示器

一步一步,自定义viewPager指示器,第1张

概述今天看到美颜相机里的首页广告指示器有点好玩,就想着自己写一个现在开始进行分析,首先需要测量指示器的宽高,大致分为这几个部分   所以我们重写onMeasured的时候只需要根据间隔space,R小圆圈半径,滑块长度   测量好后我们进行具体的绘制,小圆圈我们直接用canvas.dr

今天看到美颜相机里的首页广告指示器有点好玩,就想着自己写一个

现在开始进行分析,首先需要测量指示器的宽高,大致分为这几个部分

 

 

 所以我们重写onMeasured的时候只需要根据 间隔 space,R小圆圈半径,滑块长度

 

 

 测量好后我们进行具体的绘制,小圆圈我们直接用 canvas.drawCircle,滑块直接使用一条横线就行,横线的strokeWIDth边缘必须是

小圆圈的直径。

vIEwPager 在当前页的时候当前小圆圈和下一个小圆圈之间会多出barWIDth - 2*R的空间用来填充滑块

 

 

 所以他的画法是

先画第一个圆圈,如果是显示当前下标再画滑块 然后画布镜头右移 barWIDth + space - 2R(这里减2R是因为画滑块的画笔是 strokeWIDth =2R,

strokeCap=Paint.Cap.ROUND的)

最后贴出效果

全部代码如下(没做相关封装,只是实现)

import androID.animation.ValueAnimatorimport androID.content.Contextimport androID.graphics.Canvasimport androID.graphics.colorimport androID.graphics.Paintimport androID.graphics.RectFimport androID.graphics.drawable.Drawableimport androID.os.Buildimport androID.util.AttributeSetimport androID.vIEw.VIEwimport androID.vIEw.VIEwGroupimport androID.vIEw.animation.AccelerateDecelerateInterpolatorimport androID.vIEw.animation.linearInterpolatorimport androID.Widget.FrameLayoutimport androID.Widget.Scrollerimport androIDx.annotation.RequiresAPIimport androIDx.vIEwpager.Widget.VIEwPagerimport androIDx.vIEwpager2.Widget.VIEwPager2import com.lu.demoy.Widget.i.YIndicatorAdapterimport java.lang.Exceptionclass YIndicator @JvmOverloads constructor(    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : VIEw(context, attrs, defStyleAttr) {    init {        initproperty()    }    overrIDe fun onMeasure(wIDthMeasureSpec: Int, heightmeasureSpec: Int) {        circleW = radius * 2        radiusdistancebar = (scrollbarWIDth-circleW).coerceAtLeast(0f)        val w = (childamount -1)*spacing + circleW*childamount + radiusdistancebar        setMeasuredDimension(w.toInt(),circleW.toInt())    }    private var radiusdistancebar = 0f    private var childamount = 0    private var spacing = 0f    private var scrollbarWIDth = 0f    private var radius = 0f    private var circleW = 0f    private var currentIndex = 1    private var currentOffset = 0f    private var crossdistance = 0f    private var valueAnimator:ValueAnimator?=null    private var onPagerchangelistener:VIEwPager2.OnPageChangeCallback?=null    private var pagerVIEwPager2:VIEwPager2? = null    private var timeInterceptor = 0L    fun setbarWIDth(setScrollbarWIDth:float):YIndicator{        this.scrollbarWIDth = setScrollbarWIDth        return this    }    fun seTradius(radius:float):YIndicator{        this.radius = radius        paintbar.strokeWIDth=radius*2        return this    }    fun setSpacing(spacing:float):YIndicator{        this.spacing = spacing        return this    }    fun setPager(vIEwPager: VIEwPager2){        if (vIEwPager.adapter !is YIndicatorAdapter<*>) {            throw Exception("adapter must be YIndicatorAdapter")        }        pagerVIEwPager2 = vIEwPager        childamount = (vIEwPager.adapter as YIndicatorAdapter<*>).getVIEwSize()        onPagerchangelistener?.let {            pagerVIEwPager2?.unregisterOnPageChangeCallback(it)        }        onPagerchangelistener =object:VIEwPager2.OnPageChangeCallback(){            overrIDe fun onPageScrolled(                position: Int,                positionOffset: float,                positionOffsetPixels: Int) {                if(System.currentTimeMillis() - timeInterceptor>100){                    timeInterceptor = System.currentTimeMillis()                    currentIndex = position % childamount +1                    val crossAll = (currentIndex == childamount) && (positionOffset > 0)                            ||(currentIndex == 1) && (positionOffset < 0)                    crossdistance = (if (crossAll)(-spacing*(childamount-1)) else spacing)                    currentOffset =crossdistance * positionOffset                    invalIDate()                }                if (positionOffset == 0.0f){                    currentIndex = position % childamount +1                    currentOffset = 0f                    println("当前页:$currentIndex,positionOffset:$positionOffset")                    invalIDate()                }            }        }        vIEwPager.registerOnPageChangeCallback(onPagerchangelistener!!)        if(childamount!=0){            requestLayout()        }    }    private fun release(){        onPagerchangelistener?.let {            pagerVIEwPager2?.unregisterOnPageChangeCallback(it)        }        pagerVIEwPager2 = null        onPagerchangelistener = null        valueAnimator?.removeAllUpdateListeners()        valueAnimator?.cancel()        valueAnimator = null    }    overrIDe fun onDetachedFromWindow() {        super.onDetachedFromWindow()        release()        super.onDetachedFromWindow()    }    lateinit var paintIndicator:Paint    lateinit var paintbar:Paint    private fun initproperty(){        paintIndicator= Paint()        paintbar = Paint()        paintIndicator.color = color.WHITE        paintIndicator.isAntiAlias = true        paintbar.color = color.WHITE        paintbar.isAntiAlias = true        paintbar.strokeCap=Paint.Cap.ROUND    }    overrIDe fun onDraw(canvas: Canvas?) {        canvas?.save()        for (a in 1..childamount){            canvas?.drawCircle(radius,radius,radius,paintIndicator)            if (a == currentIndex){                //画滚动条                canvas?.drawline(radius+currentOffset,radius,scrollbarWIDth-radius+currentOffset,radius,paintbar)            }            if(a == currentIndex){                canvas?.translate(radiusdistancebar,0f)            }            canvas?.translate(spacing+radius,0f)        }        canvas?.restore()    }}


abstract class YIndicatorAdapter<T: RecyclerVIEw.VIEwHolder>:
RecyclerVIEw.Adapter<T>() {

abstract fun getVIEwSize():Int
}
 

 

总结

以上是内存溢出为你收集整理的一步一步,自定义viewPager指示器全部内容,希望文章能够帮你解决一步一步,自定义viewPager指示器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1027152.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存