我正在参加中秋创意投稿大赛,详情请看:中秋创意投稿大赛
序
缘起缘灭,似乎兜兜转转,却又回到原点。
惘然相望,又是一年中秋。
月饼的味道似乎传遍了大街小巷,浓浓的相思,儿时的记忆,不断涌现,一切似乎昨天。。。
仿若间,儿时那朗朗背诵诗词声音渐渐传来...
白兔捣药秋复春,嫦娥孤栖与谁邻?
今人不见古时月,今月曾经照古人。
古人今人若流水,共看明月皆如此。
唯愿当歌对酒时,月光长照金樽里。
也不知,在那广寒宫之中的嫦娥仙子🧚♀️,又在思念着谁...
浓浓的睡意席卷而来,眼睛闭上的霎那间,一扇带有古老尘封气息的大门悄然开启...
寒宫之旅,悄然开启~
此 Demo GitHub 地址
仙子,听我和你说动画
动画的出现,让普通的 View 有了更多可能,同样给予了用户更佳的舒适体验度。
一起看下 Android 中的那些动画(非完整版、后续补充,希望可以兑现):
视图动画
关于视图动画,可以参照属性动画去理解:
- 视图动画仅仅是在视觉上产生了动画行为,而 View 本身属性并没有发生改变。
帧动画
官方说法:
通过使用 AnimationDrawable 按顺序显示一系列图片来创建动画。
顾名思义,按顺序展示一系列图片已达到动画效果。
比如说,陪着仙子一起看下小玉兔在干嘛?
看一波关键属性?
- 根元素 animation-list,包含一个或者多个 item 元素。
- 属性 android:oneshot,如果执行一次,则为 true。如果循环播放则为 false。默认为 false,循环播放。
- 单帧动画 item,包含在 animation-list 中。
- 属性 android:drawable,单帧图片。
- 属性 android:duration,当前帧持续的时间。
- 单帧动画 item,包含在 animation-list 中。
一起实现一波?
一、定义 Drawable
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/img_rabbit_000"
android:duration="150" />
<item
android:drawable="@drawable/img_rabbit_001"
android:duration="150" />
<item
android:drawable="@drawable/img_rabbit_002"
android:duration="150" />
...
</animation-list>
二、定义 ImageView
<ImageView
android:id="@+id/ivFrameAnim"
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="fitXY" />
三、播放动画
还有一种方案是通过循环去不断的为 drawable addFrame,个人更倾向于下面这种方式:
private fun startFrameAnim() {
binding.ivFrameAnim.apply {
setBackgroundResource(R.drawable.animation_rabbit)
val animationDrawable = background as AnimationDrawable
animationDrawable.start()
}
}
一定注意,帧动画中的单帧图片记得压缩,切勿太大,否则会造成 OOM。
这里发现了一个问题,在启动帧动画的时候,内存会出现爆增,开始想着处理回收 bitmap,折腾半天无果,后续再说哇。
补间动画
引入官老爷说法:
通过使用 Animation 对单张图片执行一系列转换来创建动画
其实这里也不仅仅是单张图片,相关的 View 均可以。
后期个人更为习惯的方式是封装为工具类,方便一次书写,多地方调用。
rotate 爱的魔力转圈圈
一起来看仙子转圈圈~
然后我们再来跟着仙子学习~ 🧚♀️🧚♀️🧚♀️
首先来看属性列表:
- rotate 旋转动画。代表 RotateAnimation。
- android:duration 动画执行速度
- android:fromDegrees 起始角度
- android:toDegrees 结束角度
- android:pivotX 旋转的 X 轴坐标
- android:pivotY 旋转的 Y 轴坐标
先来份代码版本的尝尝鲜?
val rotateAnimation = RotateAnimation(0f, 360f).apply {
duration = 1800
}
binding.ivTweenRotate0.startAnimation(rotateAnimation)
没错,就是这么简单,当然也包含其他构造:
再来个 xml 版?
首先创建 anim 目录,并创建对应 rotate 文件:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1800"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
如何使用呢?
binding.ivTweenRotate1.apply {
val rotateAnim =
AnimationUtils.loadAnimation(this@AnimationListActivity, R.anim.anim_rotate)
startAnimation(rotateAnim)
}
alpha 喜欢仙子若隐若现
淡入淡出动画属性相对较为简单:
- alpha 淡入或淡出动画。代表 AlphaAnimation。
- android:duration 动画执行速度
- android:fromAlpha 起始不透明度偏移,0.0 表示透明,1.0 表示不透明。
- android:toAlpha 结束不透明度
同样献上一份代码版本:
val alphaAnimation = AlphaAnimation(0f, 1f).apply {
duration = 1800
}
binding.ivTweenAlpha0.startAnimation(alphaAnimation)
再来一份 xml 版本:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1800"
android:fromAlpha="1"
android:toAlpha="0" />
最后的使用:
binding.ivTweenAlpha1.apply {
val alphaAnim =
AnimationUtils.loadAnimation(this@AnimationListActivity, R.anim.anim_alpha)
startAnimation(alphaAnim)
}
这里有的小伙伴就说了,我不想让仙子消失这么快,我要知道仙子消失开始以及结束,怎么办呢?
这里同样为我们提供了监听方式,如下:
binding.ivTweenAlpha1.apply {
AnimationUtils.loadAnimation(this@AnimationListActivity, R.anim.anim_alpha).apply {
startAnimation(this)
setAnimationListener(object : Animation.AnimationListener {
/**
* 动画开始
*/
override fun onAnimationStart(animation: Animation?) {
}
/**
* 动画结束
*/
override fun onAnimationEnd(animation: Animation?) {
}
/**
* 动画重复播放
*/
override fun onAnimationRepeat(animation: Animation?) {
}
})
}
}
scale 爱你的心 永恒不变
属性一览:
- scale 缩放动画:
- android:duration 动画执行速度
- android:fromXScale 起始 X 尺寸偏移,其中 1.0 表示不变
- android:toXScale 结束 X 尺寸偏移
- android:fromYScale 起始 Y 尺寸偏移
- android:toYScale 结束 Y 尺寸偏移
- android:pivotX 在对象缩放时要保持不变的 X 坐标
- android:pivotY 在对象缩放时要保持不变的 Y 坐标
搞一份代码版本试试?
val scaleAnimation = ScaleAnimation(1f, 1.2f, 1f, 1.2f).apply {
duration = 1800
}
binding.ivTweenScale0.startAnimation(scaleAnimation)
再来一份 xml 版本:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1800"
android:fromXScale="1"
android:fromYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.2"
android:toYScale="1.2" />
同样的 load 方式:
binding.ivTweenScale1.apply {
AnimationUtils.loadAnimation(this@AnimationListActivity, R.anim.anim_scale).apply {
startAnimation(this)
}
}
translate 能否平移到你心房
属性一览:
- translate 平移动画:
- android:duration 动画执行速度
- android:fromXDelta 起始 X 偏移
- android:toXDelta 结束 X 偏移
- android:fromYDelta 起始 Y 偏移
- android:toYDelta 结束 Y 偏移
来份代码版本:
val translateAnimation = TranslateAnimation(0f,100f,0f,100f).apply {
duration = 3600
fillAfter = true // 动画结束后不回到原地
}
binding.ivTweenTranslate0.startAnimation(translateAnimation)
再来份 xml 版本:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1800"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100"
android:toYDelta="100" />
以及对应使用:
binding.ivTweenTranslate1.apply {
AnimationUtils.loadAnimation(this@AnimationListActivity, R.anim.anim_translate).apply {
startAnimation(this)
}
}
set 仙子 让我为你舞起来
太晚了,明日更新。。。
属性动画
未完待续,稍等片刻。。。
叨逼叨
害,意料之中,意料之外,又要忙于找工作啦,暂时搁置,后续继续维护~
理解万岁~
THK
前人栽树,后人乘凉,感谢前辈大佬~
附上对应参考地址链接~
参考资料
引用资源
使用工具
在此仅列举之前未使用的工具,有更好的工具欢迎推荐~