博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android动画
阅读量:6397 次
发布时间:2019-06-23

本文共 6612 字,大约阅读时间需要 22 分钟。

前言

在Android开发中,UI的变化非常常见,如果不使用动画来进行过度,那么用户体验就会不怎么好。我将动画分为大三类View动画、帧动画、属性动画三种,下面先从View动画开始

一、View动画

View动画包括以下几种

  • ScaleAnimation(缩放动画)
  • TranslateAnimation(平移动画)
  • AlphaAnimation(透明度动画)
  • RotateAnimation(旋转动画)

并且还提供了一个AnimationSet类来把多个View动画进行组合显示,我们可以直接在代码中创建这些Animation对象也可以在xml中进行指定

缩放动画

  • 代码中定义
ScaleAnimation sAnimation = new ScaleAnimation(0, 1, 0,                1, Animation.RELATIVE_TO_SELF, 0.5f,                 Animation.RELATIVE_TO_SELF, 0.5f);animation.setDuration(2000);imageView.startAnimation(sAnimation);复制代码
  • xml中定义
复制代码

平移动画

  • 代码中定义
TranslateAnimation tAnimation = new TranslateAnimation(0, 100, 0, 100);tAnimation.setDuration(2000);imageView.startAnimation(tAnimation);复制代码
  • xml中定义
imageView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate));复制代码

透明度动画

  • 代码中定义
AlphaAnimation aAnimation = new AlphaAnimation(0, 1);aAnimation.setDuration(2000);imageView.startAnimation(aAnimation);复制代码
  • xml中定义
复制代码

旋转动画

  • 代码中定义
RotateAnimation rAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,                Animation.RELATIVE_TO_SELF, 0.5f);rAnimation.setDuration(2000);imageView.startAnimation(rAnimation);复制代码
  • xml中定义
复制代码

组合动画

  • 代码中定义
AnimationSet set = new AnimationSet(true);set.addAnimation(sAnimation);set.addAnimation(aAnimation);set.addAnimation(tAnimation);set.addAnimation(rAnimation);// 所有子动画都会被设置成该超时时间set.setDuration(5000);imageView.startAnimation(set);复制代码
  • xml中定义
复制代码

以上代码有几个需要注意

  • 在xml中定义的动画可以通过AnimationUtils.loadAnimation(context, resId))拿到对应的Animation对象
  • 如果想让一个动画延时执行可以设置startOffset
  • 如果想让一个动画循环执行可以设置repeatCount
  • 动画执行完后默认会返回到原始位置如果不需要返回那么需要将setFillAfter设置为true,但是虽然执行完后保留在了执行完后的位置但是该位置并不能响应点击事件,原位置能够响应点击事件
  • 上述动画都没有设置插值器,采用默认的插值器AccelerateDecelerateInterpolator,如果想要动画按照不停的速率运行,那么可以设置以下几种插值器
插值器类 对应xml资源id 变化方式
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 先加速后减速
AccelerateInterpolator @android:anim/accelerate_interpolator 一直加速
AnticipateInterpolator @android:anim/anticipate_interpolator 先往反方向运动一段距离再前进
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 先往反方向运动再前进并且超过目标点,最后回到目标点
BounceInterpolator @android:anim/bounce_interpolator 类似球落地时的反弹效果
CycleInterpolator @android:anim/cycle_interpolatorr 循环,先往正向运动到终点,然后向反方向运动知道运动到-终点处再回来
DecelerateInterpolator @android:anim/decelerate_interpolator 一直减速
LinearInterpolator @android:anim/linear_interpolator 匀速运动
OvershootInterpolator @android:anim/overshoot_interpolator 移动超过目标点,然后再回来

LayoutAnimation

如果一个ViewGroup被设置了该属性那么在第一次显示该ViewGroup时会执行所设置的动画,用法如下。

首先定义一个AnimationSet

复制代码

然后再res/anim里面建立一个根节点为layoutAnimation文件,引用上述的文件,其中的delay表示对应ViewGroup中的每个View都要延迟动画duration * delay的时间,现在动画持续时间是2000ms,那么第一个item就会在600ms的时候执行动画,第二个会在1200ms的时候执行

复制代码

最后给目标ViewGroup设置LayoutAnimation

复制代码

运行效果如下图所示,当然有点丑,需要的时候可以慢慢调整

二、帧动画

帧动画就是将一组图片按照特定的顺序进行播放, 使用方式如下所示

imageView.setImageResource(R.drawable.list);mDrawable = (AnimationDrawable)imageView.getDrawable();imageView.post(new Runnable() { @Override public void run() { mDrawable.start(); }});复制代码

这里有几个注意点

  • oneshot表示是否只播放一次,该值默认是false表示循环播放
  • 帧动画在View三大流程执行完毕前,只会显示第一帧所以要在三大流程执行完成后再开启

三、属性动画

前面讲到的View动画其实并不会真正改变View的属性比如位置等等,而属性动画会真正的改变View的属性,其主要类包括以下几个,其中ObjectAnimator继承于ValueAnimator,先来看看ViewPropertyAnimator

  • ViewPropertyAnimator
  • ValueAnimator
  • ObjectAnimator
  • AnimatorSet

ViewPropertyAnimator

这个类内部其实是通过ValueAnimator实现的,我们可以通过view.animator()得到该类的对象

// translation从当前值慢慢的变为100imageView.animate().translationX(100);// translation从当前值慢慢的变为原来值+100imageView.animate().translationXBy(100);// 反转180度imageView.animate().rotation(180);复制代码

注意我们不需要手动调用start方法其就会自动运行,默认持续时间是300ms

ValueAnimator

我们可以通过ofInt、ofFloat、ofArgb等获取到ValueAnimator实例,下面以通过属性动画动态改变图片的高度为例

在代码中定义

ValueAnimator vAnimator = ValueAnimator.ofInt(400, 0);vAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {        ViewGroup.LayoutParams params = imageView.getLayoutParams();        params.height = (int) animation.getAnimatedValue();        imageView.setLayoutParams(params);    }});vAnimator.setDuration(3000);vAnimator.start();复制代码

在xml中定义

ValueAnimator vAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);复制代码

ObjectAnimator

我们可以通过ofInt、ofFloat、ofArgb等获取到ObjectAnimator实例,一般会操作以下几个属性

  • translationX、translationY 平移
  • rotation、rotationX、rotationY 旋转
  • privotX、privotY 控制旋转缩放的支点位置
  • alpha 透明度
  • x 、y 、z位置

下面以通过属性动画动态改变图片的透明度为例

在代码中定义

ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "alpha", 0, 1);animator.setDuration(3000);animator.start();复制代码

在xml中定义

ObjectAnimator animator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);animator.setTarget(imageView);animator.start();复制代码

几个注意点:

  • 当ofXXX属性名参数后面只有一个参数时那个参数表示的是目标值,系统会调用getter获取初始化值,然后不停的调用setter设置,当超过一个参数时第一个就变为初始值最后一个变成目标值,中间的都是转接点这个时候可以不提供setter方法
  • 当一个类的某个属性没有提供setter方法时我们需要对其运用属性动画,我们可以建一个包装类
  • 如果发现使用了属性动画改变自定义View的属性发现界面并没有发生变化,请检查下你的setter方法有没有触发重绘

AnimatorSet

AnimatorSet类似AnimationSet,作用是把多个属性动画组合起来执行

在代码中定义

ValueAnimator vAnimator =                (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.animator);vAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {        ViewGroup.LayoutParams params = imageView.getLayoutParams();        params.height = (int) animation.getAnimatedValue();        imageView.setLayoutParams(params);    }});vAnimator.setDuration(3000);vAnimator.start();ObjectAnimator oAnimator = (ObjectAnimator)        AnimatorInflater.loadAnimator(this, R.animator.object_animator);oAnimator.setTarget(imageView);oAnimator.start();AnimatorSet set = new AnimatorSet();// 同时执行set.playTogether(vAnimator, oAnimator);// 顺序执行set.playSequentially(vAnimator, oAnimator);复制代码

在xml中定义 其中ordering表示同时执行还是顺序执行

复制代码

PropertyValuesHolder

使用PropertyValuesHolder也能实现多动画同时执行

PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 0, 1);PropertyValuesHolder holder2 = PropertyValuesHolder.ofInt("rotation", 0, 360);ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(holder1, holder2);animator.setDuration(3000);animator.setTarget(imageView);animator.start();复制代码

Tips: 将ViewGroup的animateLayoutChanges属性设置为true,在添加View或者移除View的时候会有动画

转载于:https://juejin.im/post/5c9b1c2be51d455090640973

你可能感兴趣的文章
用python操作mysql数据库(之代码归类)
查看>>
ArcGIS Server 10.1 SP1连续查询出现Unable to complete operation错误
查看>>
执行./configure报checking for g++... no错误
查看>>
Dojo学习笔记(十一):Dojo布局——嵌套样例
查看>>
Appium for Android元素定位方法
查看>>
pfSense LAGG(链路聚合)设置
查看>>
教学思路SQL之入门习题《学生成绩》 七.存储过程基础知识
查看>>
createrepo 无法使用解决
查看>>
.net安全类库
查看>>
tablespace backup模式一个没用的技术
查看>>
PostgreSQL安装
查看>>
七牛实时音视频云视频连线demo(web部分)
查看>>
Mysql 权限
查看>>
Spring事务管理(详解+实例)
查看>>
ubuntu apt-get install 出现无法定位软件包...
查看>>
centos7 下 基于docker搭建java/tomcat (方式一)
查看>>
全世界最好的编辑器VIM之Windows配置(gvim)[未测试]
查看>>
2018年你需要知道的13个JavaScript工具库
查看>>
当你点击按钮的时候如何设置其他按钮不可点击
查看>>
spring 高级装配
查看>>