一个和ViewPage结合使用过的指示器
package com.tictalk.tictalk.core.widget
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.os.Build
import android.support.v4.view.ViewPager
import android.util.AttributeSet
import android.view.View
import com.tictalk.tk_center.util.toPx
/**
* @Description: 一个和ViewPage结合使用过的指示器
* @Author: ice
* @Date: 2018/10/31 10:48 AM
*
*
* easy to use !
*
* ExtensibleIndicator ei = findViewById(R.id.ei);
* ei.setUpWith(viewPager);
*
* width 和 height 目前没有处理wrap_content情况
*/
class ExtensibleIndicator : View {
private var mChunkWidth = 30.toPx().toFloat()
private var mChunkHeight = 5.toPx().toFloat()
private var mChunkRadius = 2.toPx().toFloat()
private var mLongerChunkWidth = 55.toPx().toFloat()
private var mChunkBg = Color.parseColor("#FF2F3042")
private var mCurChunkBg = Color.parseColor("#FF6970FF")
private var mSpaceWidth = 10.toPx().toFloat()
private var mChunkPaint: Paint
var mChunkCount = 3
set(value) {
field = value
postInvalidate()
}
private var mCurChunkPosition = 0
private var mActiveChunkPosition = 0
private var mActiveChunkFraction = 0f
constructor(context: Context?) : this(context, null)
constructor(context: Context?, attr: AttributeSet?) : this(context, attr, 0)
constructor(context: Context?, attr: AttributeSet?, defStyleAttr: Int) : super(context, attr, defStyleAttr) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
mChunkPaint = Paint()
mChunkPaint.style = Paint.Style.FILL
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
setMeasuredDimension(resolveSize(suggestedMinimumWidth, widthMeasureSpec),
resolveSize(suggestedMinimumHeight, heightMeasureSpec))
}
private fun update(activeChunkPosition: Int, activeChunkFraction: Float) {
//支持viewPager无限轮滑
val realIndex = activeChunkPosition % mChunkCount
mActiveChunkPosition = realIndex
mActiveChunkFraction = activeChunkFraction
if (activeChunkFraction == 0f) {
mCurChunkPosition = realIndex
mActiveChunkPosition = -1
}
postInvalidate()
}
@TargetApi(Build.VERSION_CODES.M)
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
var l = 0f
for (i in 0 until mChunkCount) {
// "i=$i and l=$l".log()
var r: Float
when (i) {
mCurChunkPosition -> {
mChunkPaint.color = mCurChunkBg
r = l + mLongerChunkWidth - (mLongerChunkWidth - mChunkWidth) * mActiveChunkFraction
}
mActiveChunkPosition -> {
mChunkPaint.color = mChunkBg
r = l + mChunkWidth + (mLongerChunkWidth - mChunkWidth) * mActiveChunkFraction
}
else -> {
mChunkPaint.color = mChunkBg
r = l + mChunkWidth
}
}
canvas.drawRoundRect(l, 0f, r, mChunkHeight, mChunkRadius, mChunkRadius, mChunkPaint)
l = r
if (i != mChunkCount - 1) {
r = l + mSpaceWidth
mChunkPaint.color = Color.TRANSPARENT
canvas.drawRect(l, 0f, l + mSpaceWidth, 1f, mChunkPaint)
l = r
}
}
}
fun setUpWith(viewPager: ViewPager, chunkCount: Int = mChunkCount) {
if (chunkCount != mChunkCount) {
mChunkCount = chunkCount
}
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
private var changeSelectedPosition: Boolean = false
var isScrolling = false
var curActiviePosition = 0
var curScrollState = 0
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
if (positionOffset > 0 && positionOffset < 1) {
if (curScrollState == ViewPager.SCROLL_STATE_SETTLING && changeSelectedPosition) {
//回弹和切换都会经过SCROLL_STATE_SETTLING状态,使用changeSelectedPosition判断是不是回弹
return
}
if (!isScrolling) {
isScrolling = true
curActiviePosition = if (positionOffset > 0.5) {
//开始右滑
position
} else {
//开始左滑
position + 1
}
}
val activeChunkFraction: Float = if (curActiviePosition == position) {
//右滑
1 - positionOffset
} else {
//左滑
positionOffset
}
changeSelectedPosition = false
update(curActiviePosition, activeChunkFraction)
}
}
override fun onPageSelected(position: Int) {
changeSelectedPosition = true
update(position, 0f)
}
override fun onPageScrollStateChanged(state: Int) {
curScrollState = state
if (state == ViewPager.SCROLL_STATE_IDLE) {
isScrolling = false
}
}
})
}
}