android小動畫:不斷擴散的圓點
?效果圖
(ps: 其實就兩個半徑和透明度一起變化的小圓, 本項目中用來指示指尖位置)
實現(xiàn)原理
監(jiān)聽點擊的位置,在父布局中動態(tài)增加 自定義的動畫View
代碼實現(xiàn)
(1)activity
點擊監(jiān)聽及添加View
// 觸屏點擊位置 private var pointX: Int = 0 private var pointY: Int = 0 private var circleView: SpreadCircleView?= null // 觸摸點擊 override fun onTouchEvent(event: MotionEvent?): Boolean { when (event!!.action) { MotionEvent.ACTION_DOWN -> { pointX = event.x.toInt() pointY = event.y.toInt() } MotionEvent.ACTION_MOVE -> { } MotionEvent.ACTION_UP ->{ addPointCircle() } else -> { } } return true }
/** * 添加自動擴散的圓點 View */ fun addPointCircle(){ if(circleView == null){ circleView = SpreadCircleView(this); circleView?.let{ lifecycle.addObserver(it) } } binding.rootLayout.removeView(circleView) circleView?.let{ // 寬度和高度相同 val width = it.maxRadius.toInt() * 2 var lp = FrameLayout.LayoutParams(width, width ) lp.marginStart = pointX - width/2 lp.topMargin = pointY - width/2 binding.rootLayout.addView(it, lp) it.startAnimation() } }
(2)圓點View
實現(xiàn)(屬性動畫,根據(jù)動畫進度來確定圓的當(dāng)前半徑,利用LifecycleObserver
綁定周期)
/**
* Created by Liming on 2021/9/1 15:36
* 不斷擴散的小圓, 用于顯示指尖位置
*/
class SpreadCircleView : View, LifecycleObserver {
private var paint: Paint = Paint()
// 圓圈最大半徑
val maxRadius = 25.toPx()
// 圓圈中心點
var centerX:Int = 0
var centerY:Int = 0
private var animator : ObjectAnimator? = null
// 是否已開始繪制第二個圓
var hasDrawCicle2 = false
// 動畫進度
private var progress = 0f
set(value){
field = value
// 刷新界面
invalidate()
}
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context,
attrs,
defStyleAttr)
init{
paint.style = Paint.Style.FILL
paint.color = ContextCompat.getColor(context, R.color.rect_orange) // #ffa200
paint.strokeWidth = 3.toPx()
paint.isAntiAlias = true // 防鋸齒
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
//圓心位置
centerX = w / 2;
centerY = h / 2;
}
override fun draw(canvas: Canvas?) {
super.draw(canvas)
// 第一個圓
drawCircle(canvas, progress)
// 第二個圓
if(hasDrawCicle2 || progress > 0.5f ){
// 第一個圓的進度第一次達(dá)到 0.5 時,開始繪制第二個圓,
hasDrawCicle2 = true
var progress2 = progress + 0.5f
if(progress2 > 1){
progress2 = progress2 - 1
}
drawCircle(canvas, progress2)
}
}
/**
* 根據(jù)進度繪制 半徑和透明度變化的圓
*/
fun drawCircle(canvas: Canvas?, animProgress: Float){
// 透明度 0 - 255
var alpha = 255 * (1 - animProgress)
paint.alpha = alpha.toInt()
var radius = maxRadius * animProgress
// 繪制圓
canvas?.drawCircle(centerX.toFloat(), centerY.toFloat(), radius, paint )
}
private fun getAnimator(): ObjectAnimator?{
if(animator == null){
animator = ObjectAnimator.ofFloat(this,
"progress", 0f, 0.99f)
animator?.duration = 1500
animator?.repeatCount = -1 //-1代表無限循環(huán)
animator?.interpolator = LinearInterpolator()
}
return animator
}
fun startAnimation() {
// 開始動畫
getAnimator()?.start()
hasDrawCicle2 = false
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun resume() {
// 開始動畫
animator?.start()
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun pause() {
animator?.pause()
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun destory() {
// 清除動畫,避免內(nèi)存泄漏,
animator?.cancel()
clearAnimation()
}
}
補充一個用到的擴展函數(shù)
fun Int.toPx(): Float{ val resources = Resources.getSystem() return TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), resources.displayMetrics ) }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android快速開發(fā)之定制BaseTemplate
這篇文章主要為大家詳細(xì)介紹了Android快速開發(fā)之定制BaseTemplate的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02android開發(fā)設(shè)計模式之——單例模式詳解
本篇文章主要介紹了android開發(fā)設(shè)計模式之——單例模式詳解,具有一定的參考價值,有需要的可以了解一下。2016-11-11Android通過Java sdk的方式接入OpenCv的方法
這篇文章主要介紹了Android通過Java sdk的方式接入OpenCv的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04recycleview實現(xiàn)拼多多首頁水平滑動效果
這篇文章主要為大家詳細(xì)介紹了recycleview實現(xiàn)拼多多首頁水平滑動效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05Android如何使用Bmob后端云實現(xiàn)失物招領(lǐng)功能
這篇文章主要介紹了Android如何使用Bmob后端云實現(xiàn)失物招領(lǐng)功能,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下2021-03-03