WX20201231-181616@2x.png
思路:利用Path绘制动画轨迹,再使用PathMeasure获取轨迹中的坐标位置实时改变view的坐标完成红包动画。
封装一个红包容器view用于管理大量红包view的显示、动画、消失、回收利用
package com.cj.customwidget.widget
import android.content.Context
import android.graphics.*
import android.os.Handler
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.Animation
import android.widget.FrameLayout
import androidx.annotation.LayoutRes
import androidx.core.view.children
/**
* File FallingView.kt
* Date 12/25/20
* Author lucas
* Introduction 飘落物件控件
* 规则:通过适配器实现
*/
class FallingView : FrameLayout, Runnable {
private val TAG = FallingView::class.java.simpleName
private var handlerTask = Handler()
private var iFallingAdapter: IFallingAdapter? = null
private var position = 0//当前item
private var fallingListener: OnFallingListener? = null
private var lastStartTime = 0L//最后一个item开始显示的延迟时间
private val cacheHolder = HashSet()//缓存holder,用于复用,减少item view创建的个数
constructor(context: Context) : super(context) {
initView(context, null)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView(context, attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initView(context, attrs)
}
private fun initView(context: Context, attrs: AttributeSet?) {
// setWillNotDraw(false)//放开注释可显示辅助线
}
//开始飘落
fun startFalling() {
if (iFallingAdapter == null) {
Log.e(TAG, "iFallingAdapter not be null.")
return
}
position = 0
handlerTask.post(this)
}
//停止飘落
fun stopFalling() {
handlerTask.removeCallbacks(this)
//停止所有动画
children.forEach {
it