利用Android實(shí)現(xiàn)一種點(diǎn)贊動(dòng)畫效果的全過程
前言
最近有個(gè)需求,需要仿照公司的H5實(shí)現(xiàn)一個(gè)游戲助手,其中一個(gè)點(diǎn)贊的按鈕有動(dòng)畫效果,如下圖:
分析一下這個(gè)動(dòng)畫,點(diǎn)擊按鈕后,拇指首先有個(gè)縮放的效果,然后有5個(gè)拇指朝不同的方向移動(dòng),其中部分有放大的效果。
點(diǎn)擊后的縮放效果
本文通過ScaleAnimation
實(shí)現(xiàn)縮放效果,代碼如下:
private fun playThumbUpScaleAnimator() { // x、y軸方向都從1倍放大到2倍,以控件的中心為原點(diǎn)進(jìn)行縮放 ScaleAnimation(1f, 2f, 1f, 2f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f).run { // 先取消控件當(dāng)前的動(dòng)畫效果(重復(fù)點(diǎn)擊時(shí)) view.clearAnimation() // 設(shè)置動(dòng)畫的持續(xù)時(shí)間 duration = 300 // 開始播放動(dòng)畫 view.startAnimation(this) } }
拇指的散開效果
有5個(gè)拇指分別往不同的方向移動(dòng),本文通過動(dòng)態(tài)添加View
,并對(duì)View
設(shè)置動(dòng)畫來實(shí)現(xiàn)。可以看到在移動(dòng)的同時(shí)還有縮放的效果,所以需要同時(shí)播放幾個(gè)動(dòng)畫。
本文通過ValueAnimator
和AnimatorSet
來實(shí)現(xiàn)該效果,代碼如圖:
// 此數(shù)組控制動(dòng)畫的效果 // 第一個(gè)參數(shù)控制X軸移動(dòng)距離 // 第二個(gè)參數(shù)控制Y軸移動(dòng)距離 // 第三個(gè)參數(shù)控制縮放的倍數(shù)(基于原大?。? val animatorConfig: ArrayList<ArrayList<Float>> = arrayListOf( arrayListOf(-160f, 150f, 1f), arrayListOf(80f, 130f, 1.1f), arrayListOf(-120f, -170f, 1.3f), arrayListOf(80f, -130f, 1f), arrayListOf(-20f, -80f, 0.8f)) private fun playDiffusionAnimator() { for (index in 0 until 5) { binding.root.run { if (this is ViewGroup) { // 創(chuàng)建控件 val ivThumbUp = AppCompatImageView(context) ivThumbUp.setImageResource(R.drawable.icon_thumb_up) // 設(shè)置與原控件一樣的大小 ivThumbUp.layoutParams = FrameLayout.LayoutParams(DensityUtil.dp2Px(25), DensityUtil.dp2Px(25)) // 先設(shè)置為全透明 ivThumbUp.alpha = 0f addView(ivThumbUp) // 設(shè)置與原控件一樣的位置 ivThumbUp.x = binding.ivThumbUp.x ivThumbUp.y = binding.ivThumbUp.y AnimatorSet().apply { // 設(shè)置動(dòng)畫集開始播放前的延遲 startDelay = 330L + index * 50L // 設(shè)置動(dòng)畫監(jiān)聽 addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator) { // 開始播放時(shí)把控件設(shè)置為不透明 ivThumbUp.alpha = 1f } override fun onAnimationEnd(animation: Animator) { // 播放結(jié)束后再次設(shè)置為透明,并從根布局中移除 ivThumbUp.alpha = 0f ivThumbUp.clearAnimation() ivThumbUp.post { removeView(ivThumbUp) } } override fun onAnimationCancel(animation: Animator) {} override fun onAnimationRepeat(animation: Animator) {} }) // 設(shè)置三個(gè)動(dòng)畫同時(shí)播放 playTogether( // 縮放動(dòng)畫 ValueAnimator.ofFloat(1f, animatorConfig[index][2]).apply { duration = 700 // 設(shè)置插值器,速度一開始快,快結(jié)束時(shí)減慢 interpolator = DecelerateInterpolator() addUpdateListener { values -> (values.animatedValue as Float).let { value -> ivThumbUp.scaleX = value ivThumbUp.scaleY = value } } }, // X軸的移動(dòng)動(dòng)畫 ValueAnimator.ofFloat(ivThumbUp.x, ivThumbUp.x + animatorConfig[index][0]).apply { duration = 700 interpolator = DecelerateInterpolator() addUpdateListener { values -> ivThumbUp.x = values.animatedValue as Float } }, // Y軸的移動(dòng)動(dòng)畫 ValueAnimator.ofFloat(ivThumbUp.y, ivThumbUp.y + animatorConfig[index][1]).apply { duration = 700 interpolator = DecelerateInterpolator() addUpdateListener { values -> ivThumbUp.y = values.animatedValue as Float } }) }.start() } } } }
示例
整合之后做了個(gè)示例Demo,完整代碼如下:
class AnimatorSetExampleActivity : BaseGestureDetectorActivity() { private lateinit var binding: LayoutAnimatorsetExampleActivityBinding private val animatorConfig: ArrayList<java.util.ArrayList<Float>> = arrayListOf( arrayListOf(-160f, 150f, 1f), arrayListOf(80f, 130f, 1.1f), arrayListOf(-120f, -170f, 1.3f), arrayListOf(80f, -130f, 1f), arrayListOf(-20f, -80f, 0.8f)) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.layout_animatorset_example_activity) binding.ivThumbUp.setOnClickListener { playThumbUpScaleAnimator() playDiffusionAnimator() } } private fun playThumbUpScaleAnimator() { // x,y軸方向都從1倍放大到2倍,以控件的中心為原點(diǎn)進(jìn)行縮放 ScaleAnimation(1f, 2f, 1f, 2f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f).run { // 先取消控件當(dāng)前的動(dòng)畫效果(重復(fù)點(diǎn)擊時(shí)) binding.ivThumbUp.clearAnimation() // 設(shè)置動(dòng)畫的持續(xù)時(shí)間 duration = 300 // 開始播放動(dòng)畫 binding.ivThumbUp.startAnimation(this) } } private fun playDiffusionAnimator() { for (index in 0 until 5) { binding.root.run { if (this is ViewGroup) { // 創(chuàng)建控件 val ivThumbUp = AppCompatImageView(context) ivThumbUp.setImageResource(R.drawable.icon_thumb_up) // 設(shè)置與原控件一樣的大小 ivThumbUp.layoutParams = FrameLayout.LayoutParams(DensityUtil.dp2Px(25), DensityUtil.dp2Px(25)) // 先設(shè)置為全透明 ivThumbUp.alpha = 0f addView(ivThumbUp) // 設(shè)置與原控件一樣的位置 ivThumbUp.x = binding.ivThumbUp.x ivThumbUp.y = binding.ivThumbUp.y AnimatorSet().apply { // 設(shè)置動(dòng)畫集開始播放前的延遲 startDelay = 330L + index * 50L // 設(shè)置動(dòng)畫監(jiān)聽 addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator) { // 開始播放時(shí)把控件設(shè)置為不透明 ivThumbUp.alpha = 1f } override fun onAnimationEnd(animation: Animator) { // 播放結(jié)束后再次設(shè)置為透明,并從根布局中移除 ivThumbUp.alpha = 0f ivThumbUp.clearAnimation() ivThumbUp.post { removeView(ivThumbUp) } } override fun onAnimationCancel(animation: Animator) {} override fun onAnimationRepeat(animation: Animator) {} }) // 設(shè)置三個(gè)動(dòng)畫同時(shí)播放 playTogether( // 縮放動(dòng)畫 ValueAnimator.ofFloat(1f, animatorConfig[index][2]).apply { duration = 700 // 設(shè)置插值器,速度一開始快,快結(jié)束時(shí)減緩 interpolator = DecelerateInterpolator() addUpdateListener { values -> (values.animatedValue as Float).let { value -> ivThumbUp.scaleX = value ivThumbUp.scaleY = value } } }, // Y軸的移動(dòng)動(dòng)畫 ValueAnimator.ofFloat(ivThumbUp.x, ivThumbUp.x + animatorConfig[index][0]).apply { duration = 700 interpolator = DecelerateInterpolator() addUpdateListener { values -> ivThumbUp.x = values.animatedValue as Float } }, // X軸的移動(dòng)動(dòng)畫 ValueAnimator.ofFloat(ivThumbUp.y, ivThumbUp.y + animatorConfig[index][1]).apply { duration = 700 interpolator = DecelerateInterpolator() addUpdateListener { values -> ivThumbUp.y = values.animatedValue as Float } }) }.start() } } } } }
效果如圖:
個(gè)人感覺還原度還是可以的哈哈。
總結(jié)
到此這篇關(guān)于利用Android實(shí)現(xiàn)一種點(diǎn)贊動(dòng)畫效果的文章就介紹到這了,更多相關(guān)Android點(diǎn)贊動(dòng)畫實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android高級(jí)UI特效仿直播點(diǎn)贊動(dòng)畫效果
- android實(shí)現(xiàn)直播點(diǎn)贊飄心動(dòng)畫效果
- Android控件實(shí)現(xiàn)直播App點(diǎn)贊飄心動(dòng)畫
- Android實(shí)現(xiàn)點(diǎn)贊動(dòng)畫(27)
- Android控件FlowLikeView實(shí)現(xiàn)點(diǎn)贊動(dòng)畫
- Android實(shí)現(xiàn)簡單點(diǎn)贊動(dòng)畫
- Android實(shí)現(xiàn)仿今日頭條點(diǎn)贊動(dòng)畫效果實(shí)例
相關(guān)文章
Android UI設(shè)計(jì)系列之自定義EditText實(shí)現(xiàn)帶清除功能的輸入框(3)
這篇文章主要介紹了Android UI設(shè)計(jì)系列之自定義EditText實(shí)現(xiàn)帶清除功能的輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06Android 動(dòng)畫之RotateAnimation應(yīng)用詳解
本節(jié)講解旋轉(zhuǎn)動(dòng)畫效果RotateAnimation方法的應(yīng)用,有需要的朋友可以參考下2012-12-12基于Android實(shí)現(xiàn)的文件同步設(shè)計(jì)方案
隨著用戶對(duì)自身數(shù)據(jù)保護(hù)意識(shí)的加強(qiáng),讓用戶自己維護(hù)自己的數(shù)據(jù)也成了獨(dú)立開發(fā)產(chǎn)品時(shí)的一個(gè)賣點(diǎn),若只針對(duì)少量的文件進(jìn)行同步,則實(shí)現(xiàn)起來比較簡單,當(dāng)針對(duì)一個(gè)多層級(jí)目錄同步時(shí),情況就復(fù)雜多了,本文我分享下我的設(shè)計(jì)思路2023-10-10android編程實(shí)現(xiàn)設(shè)置、打開wifi熱點(diǎn)共享供他人連接的方法
這篇文章主要介紹了android編程實(shí)現(xiàn)設(shè)置、打開wifi熱點(diǎn)共享供他人連接的方法,涉及Android創(chuàng)建WiFi及設(shè)置共享的相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11Android應(yīng)用開發(fā)中觸摸屏手勢識(shí)別的實(shí)現(xiàn)方法解析
這篇文章主要介紹了Android應(yīng)用開發(fā)中觸摸屏手勢識(shí)別的實(shí)現(xiàn)方法解析,深入的部分則是對(duì)左右手勢的識(shí)別給出了相關(guān)編寫思路,需要的朋友可以參考下2016-02-02