Android - 动画

news/2024/12/2 13:04:48/

一、概念

属性动画PeopertyAnimation:view的属性根据执行的动画发生真实的改变。通过不断设置 View 的属性实现。
补间动画 ViewAnimation(Tween):不改变view的位置和属性。基于 Framework的绘制转变。
帧动画 DrawableAnimation(Frame):依次播放动画过程中每帧对应的静态图片。

二、插值器 Interpolator

即数度模型,算法对应不同时间点动画完成度的百分比。

LinearInterpolator匀速。
AccelerateInterpolator持续加速(构造中可调节变速系数)。主要用在出场效果中。
AccelerateDecelerateInterpolator先加速再减速。默认效果,最符合现实物理模型。
DecelerateInterpolator持续减速到0。主要用于入场效果。
AnticipateInterpolator先反效果一点点(平移就是先回拉,放大就是先缩小),再进行正常动画轨迹。
OvershottInterpolator超过目标值一些再弹回来。
AnticipateOvershootInterpolator两种效果的结合体,先反效果一点点,最后超过目标值一些再回弹。
BounceInterpolator在目标值处弹跳几下。
CycleInterpolator自定义动画循环播放特定次数。
PathInterpolator自定义任何想要的速度模型(动画完成度 ÷ 时间完成度)。使用一个 Path 对象来绘制出想要的曲线(y 为动画完成度,x 为时间完成度)。

FastOutLinearInInterpolator

持续加速(贝塞尔曲线,初始加速更快,肉眼并不明显)。
FastOutSlowInInterpolator先加速再减速(贝塞尔曲线,加速减速更快)。
LinearOutSlowInInterpolator持续减速(初始速度更快)。

三、属性动画PeopertyAnimation

3.1 ViewPropertyAnimator

通过 view.animate() 返回一个 ViewPropertyAnimator 对象并自动执行,局限性在于只能调用以下方法设置属性动画。

public ViewPropertyAnimator animate()

3.1.1 动画模式 

  • 这些方法调用就会执行动画,在播放中途再次调用会先停留在原处,等进度赶上了再继续播放。当动画播放完毕后,不带by的方法再次调用不会执行,任何时候调用 start( ) 都无效果,调用 cancel() 会打断动画并会停留在原处,再次这些方法等进度赶上了再继续播放。
  • 默认动画时长0.3s,通过 setDuration() 自定义。
  • 默认速度模型开始加速结束减速(AccelerateDecelerateInterpolator),通过 setInterpolator() 自定义。

3.1.2 动画监听

设置监听

public @NonNull ViewPropertyAnimator setListener(@Nullable Animator.AnimatorListener listener)

重写onAnimationStart动画开始、onAnimationEnd动画结束、onAnimationCancel动画取消(对应调用了cancel时)、onAnimationRepeat动画重复(对应通过repeat播放时)。

更新监听

public @NonNull ViewPropertyAnimator setUpdateListener(@Nullable ValueAnimator.AnimatorUpdateListener listener)

重写onAnimationUpdate每当属性值更新时,参数ValueAnimator可以获取当前动画完成度、属性值等。

一次性监听

public @NonNull ViewPropertyAnimator withStartAction(Runnable runnable) 

public @NonNull ViewPropertyAnimator withEndAction(Runnable runnable) 

重用ViewPropertyAnimator 执行别的动画也不会再执行,动画被调用cancel取消时不会再执行。

3.2 ObjectAnimator

ofFloat(Object target, String propertyName, float... values)
ofInt(Object target, String propertyName, int... values)
ofArgb(Object target, String propertyName, int... values)
ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values)
ofMultiFloat(Object target, String propertyName, TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values)
ofMultiInt(Object target, String propertyName, TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values)

通过 ObjectAnimator.ofXXX() 创建对象,XXX具体选什么类型根据该属性设置方法的参数类型决定。target是目标View,propertyName是View的哪个属性(不是找同名变量修改值,是拼接出setter方法并调用,找不到IDE会提示。若是自定义View该属性需要提供setter方法,并在最后一行调用 invalidate() 触发重绘),values是目标值(填一个就是目标值,填两个就是起始值和目标值,填多个就是增加中间转接点值。若是自定义View,只填一个值的情况就需要该属性提供getter方法,会获取当前值当作起始值)。调用 start() 才会执行动画。

class MyView2 : View {var progress = 0Fset(value) {field = valueinvalidate()    //重写getter触发重绘即调用onDraw()}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)canvas?.drawArc(...)}
}UI {val animator = ObjectAnimator.ofFloat(myView, "progress", 0, 65)animator.start()
}

3.2.1 动画监听

设置监听

public void addListener(AnimatorListener listener)

重写onAnimationStart动画开始、onAnimationEnd动画结束、onAnimationCancel动画取消(对应调用了cancel时)、onAnimationRepeat动画重复(对应通过repeat播放时)。

更新监听

public void addUpdateListener(AnimatorUpdateListener listener) 

重写onAnimationUpdate每当属性值更新时,参数ValueAnimator可以获取当前动画完成度、属性值等。

暂停监听public void addPauseListener(AnimatorPauseListener listener)
var boolean = false
onCreate {//对View启用动画val animate = imagineView.animate().apply {//动画类型不能写在里面因为调用就会执行duration = 2000 //设置动画时长interpolator = AccelerateDecelerateInterpolator()   //设置速度模型startDelay = 2000   //延迟播放setListener(object : Animator.AnimatorListener{override fun onAnimationStart(animation: Animator) { }  //动画开始override fun onAnimationEnd(animation: Animator) { }    //动画结束override fun onAnimationCancel(animation: Animator) { } //动画取消override fun onAnimationRepeat(animation: Animator) { } //动画重复})setUpdateListener { valueAnimator -> } //动画更新withStartAction { Runnable {  } }  //动画开始withEndAction { Runnable {  } }    //动画结束}button1.setOnClickListener {//中途再次点击会停留在原地等进度赶上了继续播放animate.translationXBy(200F)    //每次点击都有位移效果animate.rotation(180F)  //只执行一次,播放完后再次点击无旋转效果}button2.setOnClickListener {//每次点击在strat和cancel切换,测试结果:start()任何时候都无效,cancel()打断动画停在原地if (boolean) animate.start() else animate.cancel()boolean = !boolean  }
}

四、切换界面动画 Transition

五、补间动画 ViewAnimation(Tween)

5.1 动画模式

透明度

AlphaAnimation(float fromAlpha, float toAlpha)

fromAlpha:起始透明度。

toAlpha:结束透明度,透明度的范围为0-1。

缩放

ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例。

toXScale/toYScale:沿着X轴/Y轴缩放的结束比例。

pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的中心为中轴点。

移动

TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)

fromXDelta/fromYDelta:动画起始位置的X/Y坐标。

toXDelta/toYDelta:动画结束位置的X/Y坐标。

旋转

RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

fromDegrees/toDegrees:旋转的起始/结束角度。

动画集合

AnimationSet(boolean shareInterpolator)

可同时播放以上动画。shareInterpolator:true都用一样的插值器,false用各自的插值器。通过调用addAnimation(Animation a) 将动画添加进集合。

5.2 动画配置

持续时间public void setDuration(long durationMillis)
重复次数

public void setRepeatCount(int repeatCount) 

值为-1或者infinite时,表示动画永不停止。

重复模式

public void setRepeatMode(int repeatMode)

默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动。

设置速度模型

public void setInterpolator(Interpolator i)

停留结果

public void setFillAfter(boolean fillAfter)

设为 true 则动画结束后 view 会停留在当前效果。

开始动画

public void startAnimation(Animation animation)

传入要播放的动画。

5.3 动画监听

public void setAnimationListener(AnimationListener listener)

用动画对象调用,重写三个方法:onAnimationStart动画开始时、onAnimationEnd动画结束时、onAnimationRepeat动画重复时。

5.4 使用方式

5.4.1 xml配置动画

res目录下新建anim文件夹,创建xml文件,可选节点有alpha、rotate、scale、translate、set。

<translate xmlns:android="http://schemas.android.com/apk/res/android"  android:interpolator="@android:anim/accelerate_decelerate_interpolator"  android:fromXDelta="0"  android:toXDelta="320"  android:fromYDelta="0"  android:toYDelta="0"  android:duration="2000"/>
AnimationUtils.loadAnimation(this, R.anim.translate)    //加载Xml文件中的动画
imagineView.startAnimation(translate)    //将动画设置到指定的View上

5.4.2 代码配置动画

val imagineView = binding.imagineView
val button = binding.button
//透明
val alphaAnimation = AlphaAnimation(1.0F, 0.2F)
//旋转
val rotateAnimation = RotateAnimation(0F, 360F, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F)
//缩放
val scaleAnimation = ScaleAnimation(1.0F, 5.0F, 1.0F, 5.0F, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F)
//平移
val translateAnimation = TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0F, Animation.RELATIVE_TO_PARENT, 0F,Animation.RELATIVE_TO_PARENT, 0F, Animation.RELATIVE_TO_PARENT, 0.4F)
//动画集合
val set = AnimationSet(true).apply {addAnimation(alphaAnimation)addAnimation(rotateAnimation)addAnimation(scaleAnimation)addAnimation(translateAnimation)duration = 1     //持续时间repeatCount = 10    //重复次数repeatMode = Animation.RESTART  //重复方式interpolator = AccelerateDecelerateInterpolator() //速度模型fillAfter = true //播放完毕后停留在原地
}
//动画监听
set.setAnimationListener(object : AnimationListener {override fun onAnimationStart(animation: Animation?) { }    //动画开始override fun onAnimationEnd(animation: Animation?) { }    //动画结束override fun onAnimationRepeat(animation: Animation?) { }    //动画重复
})
button.setOnClickListener {imagineView.startAnimation(set) //开始动画
}

六、帧动画 DrawableAnimation(Frame)

6.1 xml配置

res/drawable目录下创建animation-list文件

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false">	//true表示只播放一边,默认就是false可不写<item android:drawable="@drawable/girl_1" android:duration="100" /><item android:drawable="@drawable/girl_2" android:duration="100" /><item android:drawable="@drawable/girl_3" android:duration="100" />
</animation-list>

 6.2 代码调用

imagineView.setBackgroundResource(R.drawable.anim_frame)
val animationDrawable = imagineView.background as AnimationDrawable
animationDrawable.start()

http://www.ppmy.cn/news/59207.html

相关文章

【网络原理】TCP/IP协议

目录 1.应用层 2.传输层&#xff08;核心问题&#xff09; 2.1 UDP协议 2.1.2 UDP的特点 2.1.3 基于UDP的应用层协议 2.2 TCP协议&#xff08;重点内容&#xff09; 2.2.1 TCP/IP 协议含义 2.2.2 TCP协议端格式&#xff1a; 2.2.3 TCP的特点 2.3 TCP原理 2.4 确认应…

Vue3中双向数据绑定与Pinia实践+JS数据引用的循环修改问题

Vue3 Pinia VUE3虽然出了很久了&#xff0c;但是很少深入研究&#xff0c;目前项目上遇到了一些问题&#xff0c;所以做个Note解决一下疑问&#xff1a; v-bind/v-model怎么与Pinia进行结合Object/Array数据大量处理时&#xff0c;为何有的修改不生效组合API与选项API选择 (…

在Android应用中集成使用traceroute工具

背景知识 traceroute是一个常用于Linux系统的网络工具&#xff0c;它可显示数据包在IP网络中所经过路由的IP地址&#xff0c;理想状态下可探测本机和目标地址之间的所有路由节点。 其他操作系统中也有类似的替代品&#xff0c;实现都大同小异。一般用法如下&#xff1a; 终端…

极简爬虫通用模板

网络爬虫的一般步骤如下&#xff1a; 1、确定爬取目标&#xff1a;确定需要爬取的数据类型和来源网站。 2、制定爬取策略&#xff1a;确定爬取哪些网页、如何爬取和频率等。 3、构建爬虫程序&#xff1a;使用编程语言&#xff08;如Python&#xff09;实现爬虫程序&#xff…

Spark概述

1.Spark用来干啥的&#xff1f; Spark是一个开源的大数据处理框架&#xff0c;主要用于分布式计算和数据处理。Spark可以处理大量的数据&#xff0c;并且可以在分布式计算中进行数据处理和分析&#xff0c;具有高效性和可扩展性。Spark支持多种编程语言&#xff0c;并且可以与…

SpringCloud学习(七)——统一网关Gateway

文章目录 1. 网关介绍2. 网关搭建2.1 引入依赖2.2 创建启动类2.3 编写配置2.4 测试 3. 路由断言工厂4. 路由过滤器4.1 过滤器配置4.2 全局过滤器4.3 过滤器执行顺序 5. 跨域问题处理 1. 网关介绍 到现在&#xff0c;我们可以使用Nacos对不同的微服务进行注册并管理配置文件&am…

asp.net基于web的校园美食派送配送系统

1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和验证码&#xff0c;然后对登录进来的用户判断身份信息&#xff0c;判断是管理员用户还是普通用户。 2&#xff0e;系统用户管理&#xff1a;不管是…

大规模MIMO系统中基于CSI的卷积神经网络定位

来源&#xff1a;投稿 作者&#xff1a;小灰灰 编辑&#xff1a;学姐 论文标题&#xff1a;CSI-based Positioning in Massive MIMO systems using Convolutional Neural Networks 摘要 研究了使用大规模MIMO&#xff08;MaMIMO&#xff09;系统的信道状态信息&#xff08;CS…