动画其实很简单——视图动画使用

视图动画介绍

视图动画(Animation)是Android提供给我们的一个动画工具,API Level 1的就已经存在,使用起来其实都是按照同样的套路就可以了,而API Level 11(Android 3.0.x)后推出的属性动画也是为了想要替代它,毕竟视图动画视图动画,顾名思义就知道它是对视图进行操作,也就是View,但也就只能对View进行操作,两者的区别下次等我介绍完属性动画再讲。不过如果你已经使用了视图动画也不用着急全部都换成属性动画。

官方在介绍视图动画的时候把它分为了两类,一个是补间动画,一个逐帧动画,补间动画里面就是我们经常会用到平移、旋转、缩放、渐变,逐帧动画就是我们平常所说的帧动画,你需要有很多张图片从而组成一组图片集。

动画使用套路

在正式介绍视图动画使用之前我们先介绍一下动画本身套路,我们使用动画的时候都需要考虑什么不论是在哪里使用都可怎么考虑,如下图:

如何正确考虑动画分为哪些.png

我们分析了动画本身实现时应该考虑哪些,也分析了对应写动画时和代码实现中应该去做哪些,那么下面我们开始介绍视图动画的使用吧。

视图动画使用

既然我们已经总结了动画使用完整套路,那么我们就可以直接开始去写代码了,当然使用的过程中我会分为xml形式和code形式分开写同样效果的代码。

补间动画

效果(sorry占的地方太大了):


效果图.gif

1.渐变
其实说来渐变算是最简单的动画,因为只要考虑初始状态和结束状态和持续时间就可以了,包括了xml实现和代码实现

xml的标签表示意义可以查看 https://developer.android.com/guide/topics/resources/animation-resource.html#View

//  如果使用xml来实现动画则需要在res包下创建anim包,然后再创建xxx动画的xml 例:anim_alpha.xml
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1800"          //  动画持续时间
        android:fromAlpha="0"            //  一开始是透明的
        android:toAlpha="1.0"/>          //  最后变成完全显示
//  使用AnimationUtils加载资源文件夹下的动画
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_alpha);
//  mAnimTarget是一个我已经写好的ImageView,通过调用View的startAnimation()来执行动画
mAnimTarget.startAnimation(animation);


//  代码实现
//  从1到0表示了目标View从可见到不可见
Animation animation = new AlphaAnimation(1, 0);
//  动画持续2s
animation.setDuration(2000);
mAnimTarget.startAnimation(animation);

2.平移
其实这个名称有点不太准确,并不是说平移只是平着移动,而是从一个点到另一个点,比如我让我的View只是往下移动,根据Android的坐标系,x往右为正,y往下为正,那么从自身(0,0)出发到(0,200)就是往下移动了一段距离,代码如下:

//  xml实现
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="1800"
           android:fromXDelta="0"          //  x起始点
           android:fromYDelta="0"          //  y起始点
           android:toXDelta="150"          //  x终点
           android:toYDelta="150"/>        //  y终点
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_translate);
//  mAnimTarget是一个我已经写好的ImageView,通过调用View的startAnimation()来执行动画
mAnimTarget.startAnimation(animation);

//  代码实现
//  构造TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
Animation animation = new TranslateAnimation(0, 0, 0, 200);
//  动画持续2s
animation.setDuration(2000);
mAnimTarget.startAnimation(animation);

3.旋转
无论是旋转还是缩放默认都是从左上角开始的,而gif中是以中心点开始旋转或者缩放的,实现如下:

//  xml实现 持续1.8s 以中心点开始放大一倍
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="1800"
       android:fromXScale="1"
       android:fromYScale="1"
       android:pivotX="50%"              //  50%表示自身中心
       android:pivotY="50%"              //  50%表示自身中心         
       android:toXScale="2"
       android:toYScale="2"/>

//  pivotX和pivotY的值可以为浮点数或百分比
//  表示为:相对于对象左边缘的像素(例如“5”),
//  相对于对象左边缘的百分比(例如“5%”)
//  或相对于父容器的左边缘的百分比(例如“ 5%p“)。

//  代码实现
//  ScaleAnimation(float fromX, float toX, float fromY, float toY,
            int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//  RELATIVE_TO_SELF 0.5 以自己为中心点开始缩放
Animation animation = new ScaleAnimation(1, 2, 1, 2, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//  动画持续2s
animation.setDuration(2000);
mAnimTarget.startAnimation(animation)

4.缩放
代码如下:

//  xml 使用同其他
<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"/>

//  代码实现
//  RELATIVE_TO_SELF 0.5 以自己为中心点开始旋转
Animation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//  动画持续2s
animation.setDuration(2000);
mAnimTarget.startAnimation(animation)

<br />
看完上面四个单个的动画你可能会察觉到这些动画效果最后并没有被保留,而是又恢复了动画开始前的样子,所以如果你想要保留执行动画后的效果,只需要通过Animation调用一个方法就可以了,调用这个方法后执行效果就会被保留了,但是这里我们需要注意,View的真实位置并没有被改变,而是还是动画开始前的那个位置,你可以通过对View设置侦听就可以发现了。

//  动画结束就停在那个位置 但实际的控件位置没变
animation.setFillAfter(true);

5.组合动画
我们先来看一下效果图,这里有用到了平移,旋转,缩放,渐变,先向上平移然后另外三个同时运行,startOffset是延迟时间,xml如下:

RecScreen170209155615.gif
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 实现一个图片从底部先升起然后通过斜着飞出手机的效果,所分解为以下若干动画 -->

    <!-- 先实现平移动画向上x轴不变, y为负 -->
    <translate
        android:duration="2000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="-500"/>

    <!-- 完成向上的的动作接下里要做同时做三件事, 往屏幕外面飞, 涉及到平移、缩放和渐变 -->

    <!-- startOffset是延迟时间 -->
    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="2000"
        android:toDegrees="-45"/>

    <scale
        android:duration="2000"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="2000"
        android:toXScale="2"
        android:toYScale="2"/>

    <alpha
        android:duration="2000"
        android:fromAlpha="1"
        android:startOffset="2000"
        android:toAlpha="0"/>

</set>

6.插值器
插值器就是我们所说的时间轴,它可以让我们设置动画的变化率,通过调用Animation.setInterpolator()就可以了,然而Interpolator下面有很多之类,我们这次就不上效果图了(为啥那么大)...我们来介绍一下它的子类。

Interpolator.png
//  AccelerateDecelerateInterpolator变化率开始和结束缓慢,但加速通过中间
//  AccelerateInterpolator变化率开始缓慢,然后加速
//  AnticipateInterpolator变化开始向后然后向前
//  AnticipateOvershootInterpolator变化开始向后,然后向前和超过目标值,最后回到最终值
//  BounceInterpolator有边界的插值器
//  CycleInterpolator为了其手动设置周期
//  DecelerateInterpolator变化率快速开始然后减速, 可手动设置Factor
//  贝塞尔相关FastOutLinearInInterpolator,FastOutSlowInInterpolator,LinearOutSlowInInterpolator
//  LinearInterpolator变化率是恒定的
//  可手动设置OvershootInterpolator张力值

<br />

逐帧动画

帧动画的话,你需要很多张可以连起来的图片从而组成一个动画去展示给用户,使用如下:

//  在drawable包下创建一个xml文件并以animation-list为根目录,
//  然后每一帧都是一个Item,指明Item的资源和持续时间
 <!-- Animation frames are wheel0.png through wheel5.png
     files inside the res/drawable/ folder -->
 <animation-list android:id="@+id/selected" android:oneshot="false">
    <item android:drawable="@drawable/wheel0" android:duration="50" />
    <item android:drawable="@drawable/wheel1" android:duration="50" />
    <item android:drawable="@drawable/wheel2" android:duration="50" />
    <item android:drawable="@drawable/wheel3" android:duration="50" />
    <item android:drawable="@drawable/wheel4" android:duration="50" />
    <item android:drawable="@drawable/wheel5" android:duration="50" />
 </animation-list>

// 把写好的资源帧动画xml设置被对应的控件的背景
// Load the ImageView that will host the animation and
// set its background to our AnimationDrawable XML resource.
ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image);
img.setBackgroundResource(R.drawable.spin_animation);

// 通过VIew的getBackground()获取AnimationDrawable,
// 然后调用start()就好了,当然也可以调用stop()停止它
// Get the background, which has been compiled to an
AnimationDrawable object.
AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

// Start the animation (looped playback by default).
frameAnimation.start();

<br />
以上代码均已放到我的Github中

地址 https://github.com/GzwJaaaelu/AnimApp

我希望可以站在初学者&自学者的角度把Android中的知识点很清楚的介绍给大家,希望大家喜欢。 如果有错误希望指出来,有问题或者没看懂,都可以来问我的

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,914评论 25 707
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,478评论 6 30
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,105评论 5 13
  • 在讲解InnoDB的MVCC机制之前,我们应该了解MySQL所支持的事务,以及各个事务级别的区别和每一个事务级别所...
    wiseAaron阅读 7,609评论 3 13
  • 我渴望自由,渴望释放 渴望拥有轻盈的脚步, 带着一脸的高兴, 奔向每个善意的人, 奔向每个远方。 我不排斥苦难, ...
    浅昱阅读 244评论 0 0