Android 动画之 View动画 和 帧动画
Android 动画可以分为三大类:
1> View 动画 又称:补间
2> 帧动画
3> 属性动画
==================【View 动画】=========================
有5种:
alpha 渐变透明度动画效果
scale 渐变尺寸伸缩动画效果
translate 画面转换位置移动动画效果
rotate 画面转移旋转动画效果
layoutAnimation 容器中的控件应用统一动画
首先,创建一个 目录 具体 步骤如下:
选:anim 目录
OK,看目录,创建一个 动画文件:set
命名为: my_animat
好了 ,我们在这个set 添加我们所需要的动画。
可以既是一个动画,也可以是多个动画的组合
现在暂且先一个一个来,演示平移动画:
【translate】
看下动画目标View 的设置,用了一个TextView 注意:用了 宽高 是300px 像素,,,像素,,,像素
为什么用 px呢,会说到的
<TextViewandroid:id="@+id/tv_animator"android:layout_width="300px"android:layout_height="300px"android:background="@color/color_00a3f3"android:text="animator"android:textColor="@color/color_7e4513"android:gravity="center"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"/>
然后动画 translate_ani.xml 注意:fillAfter="true" View 最后会停留在动画结束的地方
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"><!-- 平移 对应 TranslateAnimationfromXDelta,fromYDelta 起始时X,Y座标,如果是0,0,就从远处开启toXDelta, toYDelta 动画结束时X,Y的座标 这个坐标是相对于 原始位置(0,0)的看下 toXDelta toYDelta 和TextView 宽高同是 300--><translateandroid:fromXDelta="0"android:fromYDelta="0"android:toXDelta="300"android:toYDelta="300"android:duration="500"></translate></set>
看下原始的截图
看下Activity 中的layout: activity_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".animator.AnimatorActivity"><TextViewandroid:id="@+id/tv_animator"android:layout_width="300px"android:layout_height="300px"android:background="@color/color_00a3f3"android:text="目标动画"android:textColor="@color/color_7e4513"android:gravity="center"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"/><TextViewandroid:id="@+id/tv_animator1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="@dimen/dp10"android:layout_marginTop="@dimen/dp100"android:text="平移动画"android:background="@color/color_999999"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@id/tv_animator"/><TextViewandroid:id="@+id/tv_animator2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="@dimen/dp10"android:layout_marginTop="@dimen/dp10"android:text="透明动画"android:background="@color/color_999999"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@id/tv_animator1"/><TextViewandroid:id="@+id/tv_animator3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="@dimen/dp10"android:layout_marginTop="@dimen/dp10"android:text="旋转动画"android:background="@color/color_999999"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@id/tv_animator2"/><TextViewandroid:id="@+id/tv_animator4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="@dimen/dp10"android:layout_marginTop="@dimen/dp10"android:text="缩放动画"android:background="@color/color_999999"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@id/tv_animator3"/>
</android.support.constraint.ConstraintLayout>
Activity的代码:
package com.leo.dicaprio.myutilapp.animatorimport android.content.Context
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.animation.AnimationUtils
import android.widget.Toast
import com.leo.dicaprio.myutilapp.R
import kotlinx.android.synthetic.main.activity_animator.*
import org.jetbrains.anko.startActivityclass AnimatorActivity : AppCompatActivity() {companion object {fun launch(context: Context) {context.startActivity<AnimatorActivity>()}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_animator)tv_animator.setOnClickListener { Toast.makeText(this, "被单击了", Toast.LENGTH_LONG).show() }tv_animator1.setOnClickListener { startAni1() }tv_animator2.setOnClickListener { startAni2() }tv_animator3.setOnClickListener { startAni3() }tv_animator4.setOnClickListener { startAni4() }}/*** 平移动画* */private fun startAni1() {//先加载 平移动画val animation = AnimationUtils.loadAnimation(this, R.anim.translate_ani)tv_animator.startAnimation(animation)}}
点击一下,动画过度效果就不生产 gif了,直接上最后结果
可以看到最后的结果。这时候 手机开了开发者模式的边界布局的。
分析下:
目标的 View 宽高是 300*300 像素,现在 动画 的 toXDelta和toYDelta都是300,表示向X Y 轴正方向移动 300像素。
为什么这么肯定 toXDelta 的单位是 像素呢? 从 截图看,可以理解为:目标 View 基于源点(左上角坐标)在XY方向 移动的距离,刚好是目标的宽高。。。
by the way ! 这个时候你点蓝色区域,是不会弹Taost,只有点击原始的位置,才会弹Toast。所以View动画并没有改变
View的属性。所以目标动画View是有点击事件的话,用View动画实现不了功能的。。。这个注意下。
好了,基本上可以理解完了。其实 translate 标签,是对应 TranslateAnimation()
可以用它,代码改成:
/*** 平移动画* */private fun startAni1() {//先加载 平移动画
// val animation = AnimationUtils.loadAnimation(this, R.anim.translate_ani)
// tv_animator.startAnimation(animation)//单位是像素val translateAnimation = TranslateAnimation(0F, 300F,0F , 300F)translateAnimation.fillAfter = true//停留在结束地方translateAnimation.duration = 500//时间tv_animator.startAnimation(translateAnimation)}
同样的效果!!!
另外,通过这个TranslateAnimation 还可以监听 动画的执行状态,比如:开始,结束,重复......
比如:
/*** 平移动画* */private fun startAni1() {//先加载 平移动画
// val animation = AnimationUtils.loadAnimation(this, R.anim.translate_ani)
// tv_animator.startAnimation(animation)val translateAnimation = TranslateAnimation(0F, 300F, 0F, 300F)translateAnimation.setAnimationListener(object : Animation.AnimationListener {override fun onAnimationRepeat(animation: Animation?) {//动画重复}override fun onAnimationEnd(animation: Animation?) {//动画结束}override fun onAnimationStart(animation: Animation?) {//动画开始}})translateAnimation.fillAfter = false//停留在结束地方translateAnimation.duration = 500//时间tv_animator.startAnimation(translateAnimation)}
【alpha】
透明比较简单。。。。上alpha_ani.xml 代码:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"><!--透明fromAlpha:开始时透明度 0.0- 1.0 0.0全透明 1.0不透明toAlpha: 结束时透明度 0.0- 1.0duration:动画持续时间 单位 毫秒fillAfter:动画结束后是否停留在结束位置,true停留--><alpha android:fromAlpha="1"android:toAlpha="0"android:duration="10000"></alpha></set>
Activity 引用
/*** 透明动画* */private fun startAni2() {//先加载 透明动画val animation = AnimationUtils.loadAnimation(this, R.anim.alpha_ani)tv_animator.startAnimation(animation)/** 或者* */val alphaAnimation = AlphaAnimation(1.0F, 0F)alphaAnimation.fillAfter = truealphaAnimation.duration = 5000tv_animator.startAnimation(alphaAnimation)}
【Rotate】
旋转,一般四个参数
fromDegrees 开始时的角度
toDegrees 结束时角度 ,正代表顺时针
pivotX 旋转中心轴点 X坐标 不指定 默认是View 左上角 X坐标 单位像素
pivotY 旋转中心轴点 Y坐标 不指定 默认是View 左上角 Y坐标 单位像素
不说废话,上 目标View,哈哈,同样是一个TextView,同样是 300*300 px
<TextViewandroid:id="@+id/tv_animator"android:layout_width="300px"android:layout_height="300px"android:background="@color/color_00a3f3"android:text="目标动画"android:textColor="@color/color_7e4513"android:gravity="center"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"/>
上动画文件:anim /rotate_ani.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"><!--fromDegrees 开始时的角度toDegrees 结束时角度 ,正代表顺时针pivotX 旋转中心轴点 X坐标 不指定 默认是View 左上角 X坐标pivotY 旋转中心轴点 Y坐标 不指定 默认是View 左上角 Y坐标--><rotate android:fromDegrees="0"android:toDegrees="180"android:pivotY="150"android:pivotX="150"android:duration="5000"></rotate></set>
注意!!! pivotX 和 pivotY 是150,刚好是TextView宽高的一半。
Activity调用:
/*** 旋转动画* */private fun startAni3() {//先加载 旋转动画val animation = AnimationUtils.loadAnimation(this, R.anim.rotate_ani)tv_animator.startAnimation(animation)/** 或者* */val rotateAnimation = RotateAnimation(0F, 180F, 150F, 150F)rotateAnimation.fillAfter = truerotateAnimation.duration = 5000tv_animator.startAnimation(rotateAnimation)}
测试的结果,是在TextView是 300*300 px时,
1> pivotX和pivotY都为150,旋转中心为 TextView的中心
1> pivotX和pivotY都为0, 旋转中心为 TextView的左上角
所以,结论是:这个旋转圆点坐标,是基于目标View左上角(0,0)坐标的。
【Scale】
缩放。。。。。。
fromXScale,fromYScale X Y 方向 缩放起始值
toXScale, toYScale X Y 方向 缩放结束值
pivotX ,pivotY X Y 方向 缩放中心值 中心点也是和上面的基准规则一样
代码都不贴了,都一样的·原理。。。。。
============【多个动画一起播放或者按顺序播放】=============
多个动画同时播放:
my_toget__animat.xml代码: 多个动画(透明,旋转,缩放)一起
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><alpha android:fromAlpha="1"android:toAlpha="0"android:duration="5000"></alpha><rotate android:fromDegrees="0"android:toDegrees="180"android:pivotY="150"android:pivotX="150"android:duration="5000"></rotate><scale android:fromXScale="0"android:fromYScale="0"android:toXScale="1"android:toYScale="1"android:pivotX="150"android:pivotY="150"android:duration="5000"></scale></set>
view层的处理:运行结果是 (透明,旋转,缩放)同事进行
private fun animationSet(){//加载 val animation = AnimationUtils.loadAnimation(this, R.anim.my_toget__animat)tv_animator_view.startAnimation(animation)}
这个可以不用 xml类型,可以用代码动态,比如:
private fun animationSet(){val rotateAnimation = RotateAnimation(0F, 180F, 150F, 150F)val alphaAnimation = AlphaAnimation(1.0F, 0F)val scaleAnimation = ScaleAnimation(0F, 1F, 0F, 1F, 150F, 150F)//多个动画 放进 AnimationSet val animationSet = AnimationSet(true)animationSet.addAnimation(rotateAnimation)animationSet.addAnimation(alphaAnimation)animationSet.addAnimation(scaleAnimation)animationSet.duration = 5000tv_animator_view.startAnimation(animationSet)}
动态代码设置 AnimationSet 集合,把需要的动画放进去,效果是一样的
多个动画按顺序播放:
顺序播放的思路,在xml是用延时法 通过 startOffset 指定延迟执行动画
比如:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><alpha android:fromAlpha="0"android:toAlpha="1"android:duration="3000"android:fillAfter="true"></alpha><!--第2个动画延迟3000毫秒--><rotateandroid:startOffset="3000"android:fromDegrees="0"android:toDegrees="180"android:pivotY="150"android:pivotX="150"android:duration="3000"android:fillAfter="true"></rotate></set>
加载设置用法是一样的,就不贴了
使用代码设置 顺序,监听第一个动画完成,再进行第2个动画
private fun animationOrder(){val rotateAnimation = RotateAnimation(0F, 180F, 150F, 150F)rotateAnimation.fillAfter = truerotateAnimation.duration = 5000rotateAnimation.setAnimationListener(object :Animation.AnimationListener{override fun onAnimationRepeat(animation: Animation?) {//动画重复}override fun onAnimationEnd(animation: Animation?) {//动画结束val alphaAnimation = AlphaAnimation(1.0F, 0F)alphaAnimation.fillAfter = truealphaAnimation.duration = 5000tv_animator_view.startAnimation(alphaAnimation)}override fun onAnimationStart(animation: Animation?) {//动画开始}})tv_animator_view.startAnimation(rotateAnimation)}
=======【layoutAnimation】==========
作用于 ViewGroup,为一个ViewGroup指定一个动画,他的所有子元素,出厂时都会具有这个动画效果
比如在RecycleView指定时,每个item都会有
比如在ViewGroup指定时,每个子View都会有
首先,创建 layoutAnimation : anim/layout_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"android:delay="1"android:animationOrder="random"android:animation="@anim/alpha_ani"><!--delay: 每个子View时间间隔 如果有多个子view的话,如果设定的动画周期是 duration = 1000毫秒,如果 delay=0.1,则下一个子View 会在100(duration * delay)毫秒执行动画animationOrder:子view经常顺序,normal是最前面的先进来,reverse是最后的先进来random 正看英文就知道。。。。哈哈顺序就是View.getChildView(index) 里面的这个index-->
</layoutAnimation>
创建 layoutAnimation : anim/ alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"><!--透明fromAlpha:开始时透明度 0.0- 1.0 0.0全透明 1.0不透明toAlpha: 结束时透明度 0.0- 1.0duration:动画持续时间 单位 毫秒fillAfter:动画结束后是否停留在结束位置,true停留--><alpha android:fromAlpha="0"android:toAlpha="1"android:duration="5000"></alpha></set>
父布局 layout文件:
<android.support.constraint.ConstraintLayoutandroid:id="@+id/tv_animator_contain"android:layout_width="0dp"android:layout_height="300px"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"android:layoutAnimation="@anim/layout_animation"android:visibility="invisible"><TextViewandroid:id="@+id/tv_animator_view"android:layout_width="300px"android:layout_height="300px"android:background="@color/color_00a3f3"android:text="目标动画1"android:textColor="@color/color_7e4513"android:gravity="center"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toLeftOf="@id/tv_animator_view2"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_chainStyle="spread"/><TextViewandroid:id="@+id/tv_animator_view2"android:layout_width="300px"android:layout_height="300px"android:background="@color/color_00a3f3"android:text="目标动画1"android:textColor="@color/color_7e4513"android:gravity="center"app:layout_constraintLeft_toRightOf="@id/tv_animator_view"app:layout_constraintRight_toLeftOf="@id/tv_animator_view3"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_chainStyle="spread"/><TextViewandroid:id="@+id/tv_animator_view3"android:layout_width="300px"android:layout_height="300px"android:background="@color/color_00a3f3"android:text="目标动画1"android:textColor="@color/color_7e4513"android:gravity="center"app:layout_constraintLeft_toRightOf="@id/tv_animator_view2"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintHorizontal_chainStyle="spread"/></android.support.constraint.ConstraintLayout>
注意!! 父布局的 visibility = invisible的,当父布局变成:visible后,三个子view 就会显示出来
当然,出现的形式是以动画的形式的。。。
在代码里调用:
private fun layoutAnimation() {tv_animator_contain.visibility = View.VISIBLE}
直接把父布局显示出来即可,所有子View的出现,都会有动画效果。。。。
你也可以在父布局 layout不设置,通过 LayoutAnimationController
直接上代码:
private fun layoutAnimation() {val loadAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_ani)val animationController = LayoutAnimationController(loadAnimation)animationController.delay = 0.1FanimationController.order = LayoutAnimationController.ORDER_NORMALtv_animator_contain.layoutAnimation = animationControllertv_animator_contain.visibility = View.VISIBLE}
注意!!!!!!!
代码引用的是 alpha_ani.xml,直接引用动画文件,并不是引用 layoutAnimation
==================【帧动画】=========================
首先说下,帧动画,是类似于视频播放那样,一秒显示26张图片,肉眼看到的效果就是视频了。
帧动画,会一下子把所有图片加载内存,然后每隔设定duration,就展示下一张图片。。。
不推荐!!!因为非常消耗内存!!!!!!
首先,创建帧动画,是在 drawable目录下的 。。。
然后选择 animation-list
然后
在控件里使用:
/*** 帧动画* */private fun startFrameAni() {//先设置tv_animator_view.setBackgroundResource(R.drawable.frame_animation)//再获取 强转成 AnimationDrawableval background = tv_animator_view.background as AnimationDrawable//开启动画background.start()}
再说一次,这个如果 图片过多的话,容易导致OOM
如果非得 使用帧动画,可以 把 需要的 drawable的ID全部放进一个List里面
然后自己写一个定时器(比如用Handler),隔多少秒,通过ID获取drawable 展示一个图片,这样避免一下子把所有图片加载到内存。。。。
好了。。。。。。这边就到这里
下篇写:属性动画
上面代码亲测没问题,,,,有问题请留言指正,,,谢谢!!!!
Android 动画之 View动画 和 帧动画相关推荐
- Android 动画(四)---逐帧动画
1创建逐帧动画资源---文件res/drawable/animated_rocket.xml <?xml version="1.0" encoding="utf-8 ...
- Android模仿iPhone View旋转刷新数据动画详解
因为小马很喜欢在不同的页面之间跳转时加点好玩的动画,今天无意间看到一个动画效果感觉不错,几种效果图如下,既然好玩就写在博客中,直接说就是:该效果类似于iPhone中View的切换动画效果,今天就只介绍 ...
- android 逐帧动画自动播放以及逐帧动画与渐变动画结合的停止问题
关于逐帧动画的自动播放: android 逐帧动画一般不能直接在onCreat()方法里直接调用.start(),否则只是播放动画的第一帧,可重写onWindowFocusChanged(boolea ...
- Android性能优化 _ 大图做帧动画卡?优化帧动画之 SurfaceView滑动窗口式帧复用
(ps:粗斜体表示引导方案逐步进化的关键点) SurfaceView逐帧解析 & 帧复用 简单回顾下上一篇的内容:原生帧动画在播放前解析所有帧,对内存压力大.SurfaceView可以精细地控 ...
- html逐帧动画,CSS秘密花园: 逐帧动画
<CSS Secrets>是@Lea Verou最新著作,这本书讲解了有关于CSS中一些小秘密.是一本CSSer值得一读的一本书,经过一段时间的阅读,我.@南北和@彦子一起将在W3cplu ...
- css3动画效果(旋转,帧动画)
一.css动画属性 animation是css3的动画属性,也是简写,其中包含以下几种值可配置 默认值:none 0 ease 0 1 normal 值 描述 animation-name 需要绑定到 ...
- android 仿支付宝动画,自定义view之仿支付宝动画
在学习本篇之前,你首先需要了解如下知识点: 自定义属性 实现效果图: 支付宝动画.gif 实现步骤: 绘制圆形 绘制对号的左边部分 绘制对号右边的部分 是不是感觉说了和没说一样,但思路就是这样 我们先 ...
- Android 点击View实现前后翻转动画
一个不留神又好久没写博客了,有点儿惭愧.一方面最近实验室的项目巨多-手上同时两三个新的app一起做,关键就我一个人做-(说多了都是泪)-再加上还有学车的费劲事儿,就忘了博客这个事儿了,算了,废话少说, ...
- 小程序canvas动画解决方案,绘制一个帧动画
目前还有个问题:android上面无卡顿,但是ios直接把微信卡掉! wxml <canvas style='width:{{windowWidth}}px;height:{{height}}p ...
- android动画之帧动画(drawable animation)和补间动画(view animation)
帧动画 drawable animation使用比较简单,而且支持市场上所以API版本,下面简单贴下代码.帧动画,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果. 直接代码贴上 x ...
最新文章
- linux目录默认权限是什么,linux文件目录默认权限(详解)
- 【AI初识境】给深度学习新手开始项目时的10条建议
- keil obj 文件 结构_keil下的STM32程序开发部署(一)
- Ubuntu 下安装adobe flash player
- sparklines插件_21个实用的Javascript数据图表插件
- JS原生方法实现jQuery的ready()
- Google 正式开源 Jib ,帮助 Java 应用快速容器化
- 第三周学习《对象与类》心得
- Tapestry5中的DI
- C++基础教程之类与对象
- 小米路由器r3d 安装vsftp 记事
- php实现给pdf加水印,pdf文件如何加水印 怎样给pdf文件加水印|帮你轻松实现给pdf加水印...
- 【寻找最佳小程序】03期:摩拜单车小程序——联合微信团队打造,实现不换码一扫即用
- SPC是什么,有什么用
- 2023美团面试真题
- 选一个适合自己的加密芯片,加密IC,如何才能真正的做到不被破解。
- 【环境配置】ceres solver安装
- 中国移动位置服务基地能力开放平台
- Java 学习总结 Week2
- 软件著作权(含源码、说明书、合作协议、以及提交软著的相关注意事项)