Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android样式的开发:Property Animation篇

Android样式的开发:Property Animation篇

作者头像
Keegan小钢
发布于 2018-08-10 06:39:56
发布于 2018-08-10 06:39:56
1.1K00
代码可运行
举报
文章被收录于专栏:Keegan小钢Keegan小钢
运行总次数:0
代码可运行

前篇文章说过,Android框架还提供了两种动画体系,前一篇已经总结了视图动画(View Animation)的用法,本篇则接着总结另一种动画体系——属性动画(Property Animation)的用法。

视图动画只能作用于View,而且视图动画改变的只是View的绘制效果,View真正的属性并没有改变。比如,一个按钮做平移的动画,虽然按钮的确做了平移,但按钮可点击的区域并没随着平移而改变,还是在原来的位置。而属性动画则可以改变真正的属性,从而实现按钮平移时点击区域也跟着平移。通俗点说,属性动画其实就是在一定时间内,按照一定规律来改变对象的属性,从而使对象展现出动画效果。

属性动画是在android 3.0引入的动画体系,如果还想适配基本已经灭绝的2.x版本,只好绕道了。 属性动画和视图动画一样,可以通过xml文件定义,不同的是,视图动画的xml文件放于res/anim/目录下,而属性动画的xml文件则放于res/animator/目录下。一个是anim,一个是animator,别搞错了。同样的,在Java代码里引用属性动画的xml文件时,则用R.animator.filename,不同于视图动画,引用时为R.anim.filename

属性动画主要有三个元素:<animator><objectAnimator><set>。 相对应的有三个类:ValueAnimatorObjectAnimatorAnimatorSetValueAnimator是基本的动画类,处理值动画,通过监听某一值的变化,进行相应的操作。ObjectAnimatorValueAnimator的子类,处理对象动画。AnimatorSet则为动画集,可以组合另外两种动画或动画集。相应的三个标签元素的关系也一样。 样式开发主要还是用xml的形式,所以这里主要还是讲标签的用法。

<animator>

<animator>标签与对应的ValueAnimator类提供了属性动画的核心功能,包括计算动画值、动画时间细节、是否重复等。执行属性动画分两个步骤:

  1. 计算动画值
  2. 将动画值应用到对象和属性上

ValuAnimiator只完成第一步,即只计算值,要实现第二步则需要在值变化的监听器里自行更新对象属性。 通过<animator>标签可以很方便的对ValuAnimiator进行设置,可设置的属性如下:

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:startOffset 设置动画执行之前的等待时长,单位为毫秒
  • android:repeatCount 设置动画重复执行的次数,默认为0,即不重复;可设为-1或infinite,表示无限重复
  • android:repeatMode 设置动画重复执行的模式,可设为以下两个值其中之一: restart 动画重复执行时从起点开始,默认为该值 reverse 动画会反方向执行
  • android:valueFrom 动画开始的值,可以为int值、float值或color值
  • android:valueTo 动画结束的值,可以为int值、float值或color值
  • android:valueType 动画值类型,若为color值,则无需设置该属性 intType 指定动画值,即以上两个value属性的值为整型 floatType 指定动画值,即以上两个value属性的值为浮点型,默认值
  • android:interpolator 设置动画速率的变化,比如加速、减速、匀速等,需要指定Interpolator资源。具体用法在View Animation篇已经讲过,这里不再重复

接着,用一个实例讲解具体的用法吧。在这个例子里,将一个按钮的宽度进行缩放,从100%缩放到20%。 xml文件的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- res/animator/value_animator.xml -->
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:valueFrom="100"
    android:valueTo="20"
    android:valueType="intType" />

可看到,值的变化从100到20,动画时长3000毫秒,以下则是目标按钮的xml代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/bg_btn_normal"
    android:onClick="onScaleWidth"
    android:text="点我"
    android:textColor="@android:color/white" />

按钮默认是填充屏幕宽度的,点击时的执行方法为onScaleWidth,以下则是onScaleWidth方法的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void onScaleWidth(final View view) {    
    // 获取屏幕宽度
    final int maxWidth = getWindowManager().getDefaultDisplay().getWidth();
    ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.value_animator);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        
        @Override
        public void onAnimationUpdate(ValueAnimator animator) {            
            // 当前动画值,即为当前宽度比例值
            int currentValue = (Integer) animator.getAnimatedValue();            
            // 根据比例更改目标view的宽度
            view.getLayoutParams().width = maxWidth * currentValue / 100;
            view.requestLayout();
        }
    });
    valueAnimator.start();
}

View Animation篇中已经知道,视图动画是通过AnimationUtils类的loadAnimation()方法获取xml文件相对应的Animation类实例,而属性动画则是通过AnimatorInflater类的loadAnimation()方法获取相应的Animator类实例。 另外,ValueAnimator通过添加AnimatorUpdateListener监听器监听值的变化,从而再手动更新目标对象的属性。 最后,通过调用valueAnimator.start()方法启动动画。

<objectAnimator>

<objectAnimator>标签对应的类为ObjectAnimator,为ValueAnimator的子类。<objectAnimator>标签与<animator>标签不同的是,<objectAnimator>可以直接指定动画的目标对象的属性。标签可设置的属性除了和<animator>一样的那些,另外多了一个:

  • android:propertyName 目标对象的属性名,要求目标对象必须提供该属性的setter方法,如果动画的时候没有初始值,还需要提供getter方法

还是用实例说明具体用法,还是用上面的例子,将一个按钮的宽度进行缩放,从100%缩放到20%,但这次改用<objectAnimator>实现。 以下为xml文件的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- res/animator/object_animator.xml -->
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:propertyName="width"
    android:valueFrom="100"
    android:valueTo="20"
    android:valueType="intType" />

<animator>的例子相比,就只是多了一个android:propertyName的属性,设置值为width。也就是说,动画改变的属性为width,值将从100逐渐减到20。另外,值是从setWidth()传递过去的,再从getWidth()获取。而且,这里设置的值代表的是比例值,因此,还需要进行计算转化为实际的宽度值。最后,对象实际的宽度值为view.getLayoutParams().width。因此,我将用一个包装类来包装原始的view对象,对其提供setWidth()和getWidth()方法,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static class ViewWrapper {
    private View target; //目标对象
    private int maxWidth; //最长宽度值
    
    public ViewWrapper(View target, int maxWidth) {
        this.target = target;        
        this.maxWidth = maxWidth;
    }    
        
    public int getWidth() {
        return target.getLayoutParams().width;
    } 
           
    public void setWidth(int widthValue) {
        //widthValue的值从100到20变化
        target.getLayoutParams().width = maxWidth * widthValue / 100;
        target.requestLayout();
    }
}

上面setWidth()的代码里,根据比例值转化为了实际的宽度值。最后,动画处理的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void onScaleWidth(View view) {    
    // 获取屏幕宽度
    int maxWidth = getWindowManager().getDefaultDisplay().getWidth();    
    // 将目标view进行包装
    ViewWrapper wrapper = new ViewWrapper(view, maxWidth);    
    // 将xml转化为ObjectAnimator对象
    ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);       // 设置动画的目标对象为包装后的view
    objectAnimator.setTarget(wrapper);    
    // 启动动画
    objectAnimator.start();
}

ObjectAnimator提供了属性的设置,但相应的需要有该属性的setter和getter方法。而ValueAnimator则只是定义了值的变化,并不指定目标属性,所以也不需要提供setter和getter方法,但只能在AnimatorUpdateListener监听器里手动更新属性。不过,也因为没有指定属性,所以其实更具灵活性了,你可以在监听器里根据值的变化做任何事情,比如更新多个属性,比如在缩放宽度的同时做垂直移动。

为了对View更方便的设置属性动画,Android系统也提供了View的一些属性和相应的setter和getter方法:

  • alpha:透明度,默认为1,表示不透明,0表示完全透明
  • pivotXpivotY:旋转的轴点和缩放的基准点,默认是View的中心点
  • scaleXscaleY:基于pivotX和pivotY的缩放,1表示无缩放,小于1表示收缩,大于1则放大
  • rotationrotationXrotationY:基于轴点(pivotX和pivotY)的旋转,rotation为平面的旋转,rotationX和rotationY为立体的旋转
  • translationXtranslationY:View的屏幕位置坐标变化量,以layout容器的左上角为坐标原点
  • xy:View在父容器内的最终位置,是左上角坐标和偏移量(translationX,translationY)的和

<set>

<set>标签对应于AnimatorSet类,可以将多个动画组合成一个动画集,如上面提到的在缩放宽度的同时做垂直移动,可以将一个缩放宽度的动画和一个垂直移动的动画组合在一起。 <set>标签有一个属性可以设置动画的时序关系:

  • android:ordering 设置动画的时序关系,取值可为以下两个值之一: together 动画同时执行,默认值 sequentially 动画按顺序执行

那如果想有些动画同时执行,有些按顺序执行,该怎么办呢?因为<set>标签是可以嵌套其他<set>标签的,也就是说可以将同时执行的组合在一个<set>标签,再嵌在按顺序执行的<set>标签内。

看实例代码吧,以下为xml文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- res/animator/animator_set.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:duration="3000"
        android:propertyName="width"
        android:valueFrom="100"
        android:valueTo="20"
        android:valueType="intType" />
    <objectAnimator
        android:duration="3000"
        android:propertyName="marginTop"
        android:valueFrom="0"
        android:valueTo="100"
        android:valueType="intType" />
</set>

以上代码可实现两个同时执行的动画,一个将width从100缩放到20,一个将marginTop从0增加到100。多了一个marginTop属性,那么,在ViewWrapper添加setMarginTop()方法,添加后的ViewWrapper类代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static class ViewWrapper {    
    private View target;    
    private int maxWidth; 
       
    public ViewWrapper(View target, int maxWidth) {        
        this.target = target;        
        this.maxWidth = maxWidth;
    } 
          
    public int getWidth() {        
        return target.getLayoutParams().width;
    }    
    
    public void setWidth(int widthValue) {
        target.getLayoutParams().width = maxWidth * widthValue / 100;
        target.requestLayout();
    } 
       
    public void setMarginTop(int margin) {
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) target.getLayoutParams();
        layoutParams.setMargins(0, margin, 0, 0);
        target.setLayoutParams(layoutParams);
    }
}

最后,动画处理的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void onScaleWidth(View view) {    
    // 获取屏幕宽度
    int maxWidth = getWindowManager().getDefaultDisplay().getWidth();    
    // 将目标view进行包装
    ViewWrapper wrapper = new ViewWrapper(view, maxWidth);    
    // 将xml转化为ObjectAnimator对象
    AnimatorSet animatorSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.animator_set);    
    // 设置动画的目标对象为包装后的view
    animatorSet.setTarget(wrapper);    
    // 启动动画
    animatorSet.start();
}

这样就搞定了,实现了宽度缩放和垂直移动的效果。

写在最后

至此,视图动画和属性动画基本的用法都总结完了。示例代码可从github上查看,github地址: https://github.com/keeganlee/kstyle.git

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2015-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Keegan小钢 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android动画效果-更新中
Android系统提供了三种实现动画的方式,一种是补间动画(Tween Animation 在SDK中成为View Animation),另一种是帧动画(Frame Animation 在SDK中称为Drawable Animation) ,第三种 属性动画(property animation )。
小小工匠
2021/08/16
3.9K0
Android动画分析
Android动画可以分3种:View动画,帧动画和属性动画;属性动画为API11的新特性,在低版本是无法直接使用属性动画的,但可以用nineoldAndroids来实现(但是本质还是viiew动画)。学习本篇内容主要掌握以下知识:
xiangzhihong
2022/11/30
9400
Android动画深入分析
动画分类 Android动画可以分3种:View动画,帧动画和属性动画;属性动画为API11的新特性,在低版本是无法直接使用属性动画的,但可以用nineoldAndroids来实现(但是本质还是viiew动画)。学习本篇内容主要掌握以下知识: 1,View动画以及自定义View动画。 2,View动画的一些特殊使用场景。 3,对属性动画做了一个全面的介绍。 4,使用动画的一些注意事项。 view动画 View动画的四种变换效果对应着Animation的四个子类:TranslateAnimation(平移动
xiangzhihong
2018/02/05
8880
Android开发之漫漫长途 XVII——动画(续)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!
LoveWFan
2018/08/21
3030
A013-animator资源
上一节课介绍了关于anim资源的知识点,这节课来给大家介绍animator资源,它跟anim资源同样是res下在资源,它是另外一种动画资源,上节课讲的是View Animation,是Android3.0之前使用较多的动画方式,然而Android 3.0推出之后,也带给我们一种新的动画实现方式——Property Animation(属性动画),它们有什么不一样的地方? 不同点: View Animation技术较老,只能作用于View Property Animation技术相对较新,可以作用于任何对象,
巫山老妖
2018/07/20
3230
Android 属性动画:这是一篇很详细的 属性动画 总结&攻略
实现动画效果在Android开发中非常常见,因此Android系统一开始就提供了两种实现动画的方式:
Carson.Ho
2019/02/22
4.1K0
Android动画-Property Animation
Property Animation故名思议就是通过动画的方式改变对象的属性了,所以他也是功能最为强大的,可以这样说前面的帧动画和视图动画能做到的,他都能做到,并且更为强大
码客说
2019/10/22
4240
Android中的动画全解!
View动画的平移、缩放、旋转、透明度 分别对应 Animation的的4个子类:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation。View可以用xml定义、也可以用代码创建。推荐使用xml,可读性好。
胡飞洋
2020/07/23
2.5K0
Android中的动画全解!
Android十八章:属性动画Android属性动画(第一话)
Android动画能给界面带来很炫的效果,如果我们要实现这些效果,在android3.0版本前实现动画主要有2种方式,帧动画和补间动画。
ppjun
2018/09/05
1.2K0
Android 动画笔记
属性动画几乎可以实现任何想要的动画效果,非常具有可扩展性并且非常稳健。属性动画可供设定的选项包括了:
zhiruili
2023/10/20
3290
Android 动画笔记
Android ObjectAnimator类:手把手带你自定义属性动画
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
Carson.Ho
2019/10/25
1.8K0
Android属性动画完全解析(上),初识属性动画的基本用法
用户1158055
2018/01/05
1.9K0
Android属性动画完全解析(上),初识属性动画的基本用法
自定义View(六)-动画- AnimatorSet与XML设置属性动画
AnimatorSet是组合动画,前面在ObjectAnimator.ofPropertyValuesHolder(),时也可以做到控制多个属性做动画,但是.ofPropertyValuesHolder(),仅仅是将多个属性同时做动画却无法灵活控制每个属性的播放顺序,针对的是一个控件,而AnimatorSet是组合动画。更侧重的是在多个动画播放时对动画的控制(可以控制动画的顺序,延时,同时可以控制多个控件的动画等等)。
g小志
2018/09/11
1.6K0
自定义View(六)-动画- AnimatorSet与XML设置属性动画
用xml来编写动画
我们可以使用代码来编写所有的动画功能,这也是最常用的一种做法。不过,过去的补间动画除了使用代码编写之外也是可以使用XML编写的,因此属性动画也提供了这一功能,即通过XML来完成和代码一样的属性动画功能。 通过XML来编写动画可能会比通过代码来编写动画要慢一些,但是在重用方面将会变得非常轻松,比如某个将通用的动画编写到XML里面,我们就可以在各个界面当中轻松去重用它。 如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。
xiangzhihong
2018/02/01
9820
Android入门之动画
Android动画 AlphaAnimation RelativeLayout rl_splash = (RelativeLayout) findViewById(R.id.rl_splash); //播放动画效果 AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f); //设置Alpha动画的持续时间 animation.setDuration(2000); //播放Alpha动画 rl_splash.setAnimation(animati
xiangzhihong
2018/01/26
8300
Android 中的属性动画 --- 1(基本用法)
动画在提高用户体验里面起了巨大的作用,可以说是提高用用户体验的“主力军”。在 Android 3.0 之前,视图动画几乎承担了所有的动画效果,但是视图动画有一个很大的局限性:它改变的只是某个 View 的外观。但是响应事件位置并没有随着 View 的改变而改变。举个 case 来说,现在有一个按钮通过视图动画在 x 轴方向上向右移动了 200 px(像素) 的距离,按钮显示的位置虽然改变了,但是点击移动后的按钮并不能相应点击事件,只有点击这个按钮没有移动之前的位置才能响应这个按钮的点击事件。由于这个巨大的局限性,Google 在 Android 3.0 以上添加了一个新的动画框架:属性动画。下面来一起看一下属性动画的用法:
指点
2019/01/18
1.3K0
Android 中的属性动画 --- 1(基本用法)
从零开始学Android自定义View之动画系列——属性动画(2)
独立的动画能够实现的视觉效果毕竟是相当有限的,因此将多个动画组合到一起播放就显得尤为重要。幸运的是,Android团队在设计属性动画的时候也充分考虑到了组合动画的功能,因此提供了一套非常丰富的API来让我们将多个动画组合到一起。 实现组合动画功能主要需要借助AnimatorSet这个类,这个类提供了一个play()方法,如果我们向这个方法中传入一个Animator对象(ValueAnimator或ObjectAnimator)将会返回一个AnimatorSet.Builder的实例,AnimatorSet.Builder中包括以下四个方法:
老马的编程之旅
2022/06/22
5550
从零开始学Android自定义View之动画系列——属性动画(2)
Android 属性动画详解,属性动画基本用法
Hello,大家好,今天又来装逼了,装逼也上瘾啊,最近公司不是特别忙,我想这也就是我出来装逼的最好时机吧!额,,哈哈,进入正题。如有疑问欢迎留言,如有谬误欢迎批评指正。 在Tween动画的讨论中,我们提到在Android中动画可以分为三类:①帧动画②Tween(补间动画)③Property Animation(属性动画),在前面的文章中,分别对帧动画和Tween动画进行了非常详细的讨论,如果有兴趣可以去上面的链接去阅读。那么今天就来和大家一起讨论下Property Animation,相信通过本系列博客的讨
非著名程序员
2018/02/02
1.4K0
Android 属性动画详解,属性动画基本用法
Android 动画总结(5) - 属性动画
属性动画改变属性值,所以几乎可以对任何对象执行动画,而不仅仅是 View,比起补间动画,适用范围更广。
三流之路
2018/09/11
1K0
深入分析Android动画(一)
  View动画顾名思义其作用对象为View,包含平移、缩放、旋转、透明,这四类变化分别对应着Animation的子类TranlateAnimation、ScaleAnimation、RotateAnimation和AlphaAnimation。虽然有对应的类,不过,在Android动画中,还是建议用XML来定义,其对应的标签如下所示
LoveWFan
2018/08/07
3920
深入分析Android动画(一)
相关推荐
Android动画效果-更新中
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验