android小動(dòng)畫:不斷擴(kuò)散的圓點(diǎn)
?效果圖
(ps: 其實(shí)就兩個(gè)半徑和透明度一起變化的小圓, 本項(xiàng)目中用來指示指尖位置)

實(shí)現(xiàn)原理
監(jiān)聽點(diǎn)擊的位置,在父布局中動(dòng)態(tài)增加 自定義的動(dòng)畫View
代碼實(shí)現(xiàn)
(1)activity點(diǎn)擊監(jiān)聽及添加View
// 觸屏點(diǎn)擊位置
private var pointX: Int = 0
private var pointY: Int = 0
private var circleView: SpreadCircleView?= null
// 觸摸點(diǎn)擊
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
}
/**
* 添加自動(dòng)擴(kuò)散的圓點(diǎn) 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)圓點(diǎn)View實(shí)現(xiàn)(屬性動(dòng)畫,根據(jù)動(dòng)畫進(jìn)度來確定圓的當(dāng)前半徑,利用LifecycleObserver綁定周期)
/**
* Created by Liming on 2021/9/1 15:36
* 不斷擴(kuò)散的小圓, 用于顯示指尖位置
*/
class SpreadCircleView : View, LifecycleObserver {
private var paint: Paint = Paint()
// 圓圈最大半徑
val maxRadius = 25.toPx()
// 圓圈中心點(diǎn)
var centerX:Int = 0
var centerY:Int = 0
private var animator : ObjectAnimator? = null
// 是否已開始繪制第二個(gè)圓
var hasDrawCicle2 = false
// 動(dòng)畫進(jìn)度
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)
// 第一個(gè)圓
drawCircle(canvas, progress)
// 第二個(gè)圓
if(hasDrawCicle2 || progress > 0.5f ){
// 第一個(gè)圓的進(jìn)度第一次達(dá)到 0.5 時(shí),開始繪制第二個(gè)圓,
hasDrawCicle2 = true
var progress2 = progress + 0.5f
if(progress2 > 1){
progress2 = progress2 - 1
}
drawCircle(canvas, progress2)
}
}
/**
* 根據(jù)進(jìn)度繪制 半徑和透明度變化的圓
*/
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() {
// 開始動(dòng)畫
getAnimator()?.start()
hasDrawCicle2 = false
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun resume() {
// 開始動(dòng)畫
animator?.start()
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun pause() {
animator?.pause()
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun destory() {
// 清除動(dòng)畫,避免內(nèi)存泄漏,
animator?.cancel()
clearAnimation()
}
}
補(bǔ)充一個(gè)用到的擴(kuò)展函數(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 再按一次返回鍵退出程序?qū)崿F(xiàn)思路
用戶退出應(yīng)用前給出一個(gè)提示是很有必要的,因?yàn)榭赡苁怯脩舨⒉徽娴南胪顺?,而只是一不小心按下了返回鍵,大部分應(yīng)用的做法是在應(yīng)用退出去前給出一個(gè)Dialog提示框;個(gè)人覺得再按一次返回鍵退出程序很有必要,接下來介紹一些簡單實(shí)現(xiàn)2013-01-01
解決AndroidStudio無法運(yùn)行java中的mian方法問題
這篇文章主要介紹了解決AndroidStudio無法運(yùn)行java中的mian方法問題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Android實(shí)現(xiàn)狀態(tài)欄(statusbar)漸變效果的示例
本篇文章主要介紹了Android實(shí)現(xiàn)狀態(tài)欄(statusbar)漸變效果的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
Android Studio中快捷鍵實(shí)現(xiàn)try catch等功能包含代碼塊的實(shí)現(xiàn)方法
這篇文章主要介紹了 Android Studio中快捷鍵實(shí)現(xiàn)try catch等功能包含代碼塊的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09
Android動(dòng)畫之補(bǔ)間動(dòng)畫(Tween Animation)實(shí)例詳解
這篇文章主要介紹了Android動(dòng)畫之補(bǔ)間動(dòng)畫(Tween Animation)用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android補(bǔ)間動(dòng)畫的定義,原理,注意事項(xiàng)與相關(guān)使用技巧,需要的朋友可以參考下2016-01-01
Android編程之Application設(shè)置全局變量及傳值用法實(shí)例分析
這篇文章主要介紹了Android編程之Application設(shè)置全局變量及傳值用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了全局變量及傳值的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12
android 如何設(shè)置開機(jī)后屏幕亮度默認(rèn)值為自動(dòng)調(diào)節(jié)
在第一次開機(jī)后,設(shè)置>顯示>自動(dòng)亮度調(diào)節(jié) 默認(rèn)是勾選上的,具體修改方法如下,感興趣的朋友可以嘗試操作下2013-06-06

