package com.fenghuajueli.module_host.widget
import android.animation.Animator
import android.animation.Animator.AnimatorListener
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import com.blankj.utilcode.util.LogUtils
import com.fenghuajueli.module_host.R
import kotlin.math.abs
class LinearBead(context: Context,attr: AttributeSet): View(context,attr) ,
GestureDetector.OnGestureListener{
private var mBeadNumber = 6
private var mBeadStyle = arrayOf(
R.mipmap.fz_6,
R.mipmap.fz_7,
R.mipmap.fz_8,
R.mipmap.fz_9,
R.mipmap.fz_10,
R.mipmap.fz_11,
)
private lateinit var mBitPaint: Paint
private lateinit var mRopeBitmap:Bitmap
private var mBeadBitmaps: MutableList<Bitmap> = arrayListOf()
private var mBeadBitmapSize = 346
private var mBeadsGap = 25
private lateinit var mDetector: GestureDetector
private lateinit var mValueAnimator: ValueAnimator
private var isPlayingAnm: Boolean = false
private var mTranslateY = 0f
private lateinit var iIOnFlingListener: IOnFlingListener
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// LogUtils.e("onDraw")
canvas.drawBitmap(
mRopeBitmap,
Rect(0,0,mRopeBitmap.width,mRopeBitmap.height),
Rect(
width / 2 - mRopeBitmap.width / 2,
0,
width / 2 + mRopeBitmap.width / 2,
mRopeBitmap.height
),
mBitPaint
)
for (i in 0 until mBeadNumber + 1) {
canvas.drawBitmap(
mBeadBitmaps[i],
Rect(0,0,mBeadBitmapSize,mBeadBitmapSize),
Rect(
width / 2 - mBeadBitmapSize / 2 ,
(mBeadsGap * (i+1) + mBeadBitmapSize * i - mTranslateY).toInt(),
width / 2 + mBeadBitmapSize / 2 ,
(mBeadsGap * (i+1) + mBeadBitmapSize * i - mTranslateY
+ mBeadBitmapSize).toInt()
),
mBitPaint
)
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
LogUtils.e("onSizeChanged",w,h,oldw,oldh,height,measuredHeight)
mDetector = GestureDetector(context,this)
mRopeBitmap = BitmapFactory.decodeResource(resources,R.mipmap.img_zhulian)
.copy(Bitmap.Config.ARGB_8888, true)
mRopeBitmap.height = h
initBitmapSize()
initBeadBitmaps()
initValueAnimator()
initPaint()
}
/**
* 初始化佛珠图
*/
private fun initBeadBitmaps(){
mBeadBitmaps.clear()
var j = 0
// 需增加屏幕底部外一颗珠子,方便动画移动显示 所以 加 1
for (i in 0 until mBeadNumber + 1) {
if (j == mBeadStyle.size) {
j = 0
}
val bitmap = BitmapFactory.decodeResource(resources, mBeadStyle[j])
mBeadBitmaps.add(imageScale(bitmap, mBeadBitmapSize,mBeadBitmapSize))
j ++
}
}
/**
* (高度 - 每个珠子的间距) / 珠子数量 = 每个珠子的大小
*/
private fun initBitmapSize(){
// 25代表10dp
mBeadBitmapSize = (height - mBeadsGap * (mBeadNumber + 1)) / mBeadNumber
LogUtils.e("mBitmapSize",mBeadBitmapSize)
}
/**
* 初始化值动画
*/
private fun initValueAnimator(){
mValueAnimator = ValueAnimator.ofFloat(0f, mBeadBitmapSize + mBeadsGap.toFloat())
mValueAnimator.duration = 500
mValueAnimator.addUpdateListener {
mTranslateY = it.animatedValue as Float
invalidate()
}
mValueAnimator.addListener(object :AnimatorListener{
override fun onAnimationStart(p0: Animator) {
isPlayingAnm = true
}
override fun onAnimationEnd(p0: Animator) {
mTranslateY = 0f
changeBeadBitmapsPosition()
invalidate()
isPlayingAnm = false
}
override fun onAnimationCancel(p0: Animator) {
}
override fun onAnimationRepeat(p0: Animator) {
}
})
}
/**
* 改变珠子位置
*/
private fun changeBeadBitmapsPosition() {
var newBeadBitmaps: MutableList<Bitmap> = arrayListOf()
for (i in 1 until mBeadBitmaps.size) {
newBeadBitmaps.add(mBeadBitmaps[i])
}
newBeadBitmaps.add(mBeadBitmaps[1])
mBeadBitmaps.clear()
mBeadBitmaps.addAll(newBeadBitmaps)
}
private fun updateValueAnimator(){
if (this::mValueAnimator.isInitialized){
mValueAnimator.cancel()
}
initValueAnimator()
}
private fun initPaint(){
mBitPaint = Paint(Paint.ANTI_ALIAS_FLAG)
mBitPaint.isFilterBitmap = true
mBitPaint.isDither = true
}
private fun imageScale(oldBitmap: Bitmap, newWidth: Int, newHeight: Int): Bitmap {
//原始bitmap的宽高
val oldWidth = oldBitmap.width
val oldHeight = oldBitmap.height
// 设置的宽高和原来的宽高的比例
val scaleW = newWidth / oldWidth.toFloat()
val scaleH = newHeight / oldHeight.toFloat()
//比例
val matrix = Matrix()
matrix.postScale(scaleW, scaleH)
return Bitmap.createBitmap(oldBitmap, 0, 0, oldWidth, oldHeight, matrix, true)
}
fun setBeadNumber(number: Int) {
mBeadNumber = number
initBitmapSize()
initBeadBitmaps()
invalidate()
updateValueAnimator()
}
fun setBeadStyle(beadStyle: Array<Int>) {
mBeadStyle = beadStyle
initBeadBitmaps()
invalidate()
}
fun setIOnFlingListener(listener: IOnFlingListener){
iIOnFlingListener = listener
}
override fun onTouchEvent(event: MotionEvent): Boolean {
mDetector.onTouchEvent(event)
return true
}
override fun onDown(p0: MotionEvent): Boolean {
return true
}
override fun onShowPress(p0: MotionEvent) {
}
override fun onSingleTapUp(p0: MotionEvent): Boolean {
return false
}
override fun onScroll(p0: MotionEvent, p1: MotionEvent, p2: Float, p3: Float): Boolean {
return false
}
override fun onLongPress(p0: MotionEvent) {
}
override fun onFling(e1: MotionEvent, e2: MotionEvent, p2: Float, p3: Float): Boolean {
return if(e1.y - e2.y > 0 && abs((e1.y - e2.y)) > 30 && !isPlayingAnm){
//向上滑动的判断,如果手指上滑动,就走这个方法
mValueAnimator.start()
iIOnFlingListener.slideUp()
true
}else {
false
}
}
interface IOnFlingListener{
fun slideUp()
}
}
需提供佛珠图片mBeadStyle