AndroidUI待写

高仿知乎日报无限轮播图+指示符切换动画效果

2021-05-06  本文已影响0人  孔鹏飞

先放上效果图, 因简书不支持webp格式的图片,如上传gif图片太大而无法显示,可移步掘金GitHub查看动态效果图。

仿知乎日报无限轮播图+指示符切换动画

动画分析

代码实现

TKBanner

实现无限轮播图功能,默认支持圆点和数字指示符。

仿知乎日报APP轮播图 仿品玩APP轮播图 仿虎嗅APP轮播图

CuteIndicator

自定义View,实现ViewPager页面滑动过程中指示符切换动画效果。

相关属性

属性 说明 默认值
IndicatorColor 未选中页面对应的指示符颜色 Color.GRAY
IndicatorSelectedColor 选中页面对应的指示符颜色 Color.WHITE
IndicatorWidth 未选中页面对应的指示符宽度 5dp
IndicatorSelectedWidth 选中页面对应的指示符宽度 20dp
IndicatorHeight 指示符高度 5dp
IndicatorMargin 指示符之间的间隔 5dp
IndicatorShowAnimation 是否显示指示符切换动画 true

关键代码

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
     super.onMeasure(widthMeasureSpec, heightMeasureSpec)
     if(mIndicatorCount>0) {
        val width = ((mIndicatorCount - 1) * (mIndicatorMargin + mIndicatorWidth) + mIndicatorSelectedWidth).toInt()
        setMeasuredDimension(width, mIndicatorHeight.toInt())
     }
}
override fun onDraw(canvas: Canvas) {
     super.onDraw(canvas)
     if (mIndicatorCount <= 0) {
         return
     }
     var left=0f
     var right=0f
     if (position == (mIndicatorCount - 1) && positionOffset > 0f) {
         for (i in 0 until mIndicatorCount) {
           if(i==0){
              left=0f
              right=left+mIndicatorWidth+(mIndicatorSelectedWidth - mIndicatorWidth) * positionOffset
              mIndicatorPaint.color = ColorUtils.blendARGB(mIndicatorColor, mIndicatorSelectedColor, positionOffset)
           }
           else if(i<position){
              right=left+mIndicatorWidth
              mIndicatorPaint.color = mIndicatorColor
           }
           else if(i==position){
              right=i*(mIndicatorWidth+mIndicatorMargin)+mIndicatorSelectedWidth
              mIndicatorPaint.color = ColorUtils.blendARGB(mIndicatorColor, mIndicatorSelectedColor, 1-positionOffset)
           }
           canvas.drawRoundRect(RectF(left, 0f, right, mIndicatorHeight), mIndicatorWidth / 2, mIndicatorWidth / 2, mIndicatorPaint)
           left=right+mIndicatorMargin
        }
     } else {
        for (i in 0 until mIndicatorCount) {
            if (i < position) {
                left = i * (mIndicatorWidth + mIndicatorMargin)
                right = left + mIndicatorWidth
                mIndicatorPaint.color = mIndicatorColor
             } else if (i == position) {
                left = i * (mIndicatorWidth + mIndicatorMargin)
                right = left + mIndicatorWidth + (mIndicatorSelectedWidth - mIndicatorWidth) * (1 - positionOffset)
                    mIndicatorPaint.color = ColorUtils.blendARGB(mIndicatorColor, mIndicatorSelectedColor, 1 - positionOffset)
             } else if (i == (position + 1)) {
                left = (i - 1) * (mIndicatorMargin + mIndicatorWidth) + mIndicatorWidth + (mIndicatorSelectedWidth - mIndicatorWidth) * (1 - positionOffset) + mIndicatorMargin
                right = i * (mIndicatorMargin + mIndicatorWidth) + mIndicatorSelectedWidth
                mIndicatorPaint.color = ColorUtils.blendARGB(mIndicatorColor, mIndicatorSelectedColor, positionOffset)
             } else {
                left = (i - 1) * (mIndicatorWidth + mIndicatorMargin) + (mIndicatorSelectedWidth + mIndicatorMargin)
                right = left + mIndicatorWidth
                mIndicatorPaint.color = mIndicatorColor
             }
             canvas.drawRoundRect(RectF(left, 0f, right, mIndicatorHeight), mIndicatorWidth / 2, mIndicatorWidth / 2, mIndicatorPaint)
        }
    }
}

fun setUp(count:Int) {
    mIndicatorCount = count
    requestLayout()
}

GitHub

完整的代码可以在GitHub上获取,喜欢的可以考虑给我点个赞^

https://github.com/kongpf8848/ViewWorld

参考

BGABanner

CuteIndicator

上一篇下一篇

猜你喜欢

热点阅读