按下按钮后做扩大(扩散)动画
Posted 夜尽天明89
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按下按钮后做扩大(扩散)动画相关的知识,希望对你有一定的参考价值。
需求:
1、录音按钮,按住后,做扩散动画,显示:录音中;
2、默认状态,显示:按住录音;
3、松手后,控件做反向收缩动画
UI规定:
1、默认,按钮有个背景色(纯色),尺寸为:116 * 40;
2、按住后控件扩散,扩散过程中,出现一条描边,扩散到最远处,且,背景色变成透明;
3、控件扩散后,最大尺寸为124 * 44;
4、动效时长250毫秒;
5、松手后,控件做收缩动画,效果与上面相反
效果图示例(静态图):
分析:
1、尺寸分析:
扩散前后对比:124/116= 1.0689… ;44/40 = 1.1 。为了方便实现,这里定为1.1。即,做动画时,从原始尺寸,扩大1.1倍。116 * 1.1=127.6>124;124/1.1=112.7 ;113 * 1.1=124.3 最接近125
2、在设置布局的时候,一开始,就设置为最大尺寸,这样,可以避免其他控件挤占录音控件的位置,或者,录音控件扩大时,挤占其他控件,引起界面其他控件的不必要重绘。
3、经过上面的计算,结论:(1)在误差允许范围内,默认尺寸为:113 * 40,扩大比例为1.1,控件最大区域:125 * 44
思路:
拆分3层:1、描边;2、纯色背景;3、文字和小图片。
因为动画时间很短,且,扩大比例不大,纯色背景,就只做透明度变化。没有随着描边扩散。一般也看不出来,这里“取巧”简化了。
代码不多,也简单,就直接上源码了
代码:
用到的颜色
<color name="line_color">#55ff0000</color>
<color name="bg_color">#5500ff00</color>
<color name="color_trans">#00000000</color>
<color name="color_white">#ffffff</color>
<color name="color_black">#000000</color>
1、工具类
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.GradientDrawable;
public class UiUtils
public static int dip2px(Context context, float dpValue)
final float scale = getResources(context).getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
/**
* 获得资源
*/
public static Resources getResources(Context context)
return context.getResources();
/**
* 获取drawable 边框的自定义方法,不用每次去新建drawable文件
* @param solidColor 实体颜色
* @param cornerRadiusInDp dp表示的边角半径
* @param strokeWidthInDp dp表示的边线宽度
* @param strokeColor 边线颜色
* @return GradientDrawable
*/
public static GradientDrawable getGradientDrawable(Context context, int solidColor, int cornerRadiusInDp, float strokeWidthInDp, int strokeColor)
GradientDrawable drawable = new GradientDrawable();
drawable.setCornerRadius(UiUtils.dip2px(context,cornerRadiusInDp));
drawable.setStroke(UiUtils.dip2px(context,strokeWidthInDp), strokeColor);
drawable.setColor(solidColor);
return drawable;
/**
* 获取drawable 边框的自定义方法,适用于边线颜色与实体颜色相同的,不用每次去新建drawable文件
* @param solidColor 实体颜色
* @param cornerRadiusInDp dp表示的边角半径
* @return GradientDrawable
*/
public static GradientDrawable getGradientDrawable(Context context, int solidColor, int cornerRadiusInDp)
return getGradientDrawable(context,solidColor, cornerRadiusInDp, 0, solidColor);
2、布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#eeeeee"
tools:context=".MainActivity">
<!-- 44/40=1.1,113*1.1=124.3 -->
<RelativeLayout
android:background="@color/color_white"
android:id="@+id/voice_rl"
android:layout_width="125dp"
android:layout_height="44dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp">
<!--线的view-->
<View
android:id="@+id/line_view"
android:layout_width="113dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:visibility="invisible" />
<!--背景view-->
<View
android:id="@+id/bg_view"
android:layout_width="113dp"
android:layout_height="40dp"
android:layout_centerInParent="true" />
<LinearLayout
android:id="@+id/str_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv"
android:layout_width="15dp"
android:layout_height="15dp"
android:src="@mipmap/ic_default" />
<TextView
android:id="@+id/str_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp"
tools:text="录音" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
3、功能代码:
import android.animation.Animator
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity()
//是否拦截动画
private var isInterceptAnim: Boolean = false
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
iv.setImageResource(R.mipmap.ic_default)
str_tv.setTextColor(getColor(R.color.color_white))
str_tv.text = "按住录音"
line_view?.background = UiUtils.getGradientDrawable(
this,
ContextCompat.getColor(this, R.color.color_trans),
50,
1f,
ContextCompat.getColor(this, R.color.line_color)
)
bg_view?.background = UiUtils.getGradientDrawable(
this,
ContextCompat.getColor(this, R.color.bg_color),
50
)
voice_rl?.setOnTouchListener(object : View.OnTouchListener
override fun onTouch(p0: View?, p1: MotionEvent?): Boolean
when (p1?.action)
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE ->
if (isInterceptAnim.not())
toAnim(true)
isInterceptAnim = true
MotionEvent.ACTION_UP ->
isInterceptAnim = false
toAnim(false)
return true
)
private val maxScale = 1.1f
private val minScale = 1f
private var lineAnim: ValueAnimator? = null
private var bgAnim: ObjectAnimator? = null
private var duration: Long = 250L
private fun toAnim(isDown: Boolean)
Log.e("lineAnim ", "isDown = $isDown")
if (isDown)
lineAnim = ValueAnimator.ofFloat(minScale, maxScale)
bgAnim = ObjectAnimator.ofFloat(
bg_view,
"alpha",
1f, 0f
)
else
lineAnim = ValueAnimator.ofFloat(maxScale, minScale)
bgAnim = ObjectAnimator.ofFloat(
bg_view,
"alpha",
0f, 1f
)
lineAnim?.duration = duration
bgAnim?.duration = duration
lineAnim?.addUpdateListener
var scale = it.animatedValue as Float
line_view.scaleX = scale
line_view.scaleY = scale
bgAnim?.addListener(object : Animator.AnimatorListener
override fun onAnimationStart(animator: Animator)
bg_view.visibility = View.VISIBLE
line_view.visibility = View.VISIBLE
Log.e("bgAnim ", "onAnimationStart")
override fun onAnimationEnd(animator: Animator)
Log.e("bgAnim ", "onAnimationEnd ; isDown = $isDown")
if (isDown)
line_view.visibility = View.VISIBLE
bg_view.visibility = View.GONE
iv.setImageResource(R.mipmap.ic_down)
str_tv.setTextColor(getColor(R.color.color_black))
str_tv.text = "录音中"
else
bg_view.visibility = View.VISIBLE
line_view.visibility = View.GONE
iv.setImageResource(R.mipmap.ic_default)
str_tv.setTextColor(getColor(R.color.color_white))
str_tv.text = "按住录音"
override fun onAnimationCancel(animator: Animator)
override fun onAnimationRepeat(animator: Animator)
)
lineAnim?.start()
bgAnim?.start()
以上是关于按下按钮后做扩大(扩散)动画的主要内容,如果未能解决你的问题,请参考以下文章