Android 属性动画(Property Animation)

2024-09-07 21:18

本文主要是介绍Android 属性动画(Property Animation),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文是学习以下三位大神之后,整理的学习笔记,彩蛋在编号6

         http://blog.csdn.net/lmj623565791/article/details/38067475

         http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html

         http://www.tuicool.com/articles/baEfAzY


1. Property Animation

        属性动画,这个是在Android 3.0中才引进的,以前学WPF时里面的动画机制好像就是这个,它更改的是对象的实际属性,在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。在Property Animation中,可以对动画应用以下属性:

  • Duration:动画的持续时间
  • TimeInterpolation:属性值的计算方式,如先快后慢
  • TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值
  • Repeat Count and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放
  • Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移
  • Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影

2. Value Animator的工作方式

一、举个例子

    1、某个对象的X坐标在40ms内从0移动到40 pixel.按默认的10ms刷新一次,这个对象会移动4次,每次移动40/4=10pixel。

    2、改变插值方式后,该对象的运动形式也随之改变

    上述例子的实现可以通关ValueAnimator来实现,现在有个印象即可


二、ValueAnimator工作流程图


        此图是理解ValueAnimator的关键,现在不理解没关系,还是大致看一下,按顺序浏览,有个印象即可,不过浏览后续部分时需回来对照参考


三、 ValueAnimator介绍

        ValueAnimator是Property Animation的执行类,ValueAnimator包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。上图大致描述了ValueAnimator的工作流程,理解了就差不多对ValueAnimator了解了,当然后面会有具体介绍。

        ValueAnimator的属性介绍:

                TimeIntepolator:时间插值

                TypeEvaluator:综合了时间插值、属性开始值、属性结束值计算出的属性当前值

                duration:动画持续时间

                startPropertyValue:属性开始值

                endPropertyValue:属性结束值

                start():动画启动方法


四、ValueAnimator实现步骤

        一、计算当前的属性值,ex.t = 5 ms时,x的值:

            1、ValueAnimator根据动画已进行的时间跟动画总时间(duration)的比计算出一个时间因子(0~1),如上例中10ms时,计算时间因子t:即经过的时间百分比:t=10ms/40ms=0.25

            2、然后根据TimeInterpolator计算出插值因子,上述例子中用了AccelerateDecelerateInterpolator,计算公式为(input即为时间因子):(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;  经插值计算(inteplator)后的插值因子:大约为0.15

            3、最后TypeEvaluator通过这个因子计算出属性值,计算方法为 :

1
2
3
4
            public  Float evaluate( float  fraction, Number startValue, Number endValue) {
                 float  startFloat = startValue.floatValue();
                 return  startFloat + fraction * (endValue.floatValue() - startFloat);
             }

            参数分别为上一步的插值因子,开始值与结束值。最后根据TypeEvaluator计算出在10ms时的属性值:0.15*(40-0)=6pixel。

    
        二、 根据属性值执行相应的动作,如改变对象的某一属性。(参照上图理解)
            1.通过注册监听器AnimatorUpdateListener,在onAnimationUpdate()回调方法中通过ValueAnimator.getAnimatedValue()方法获取步骤一中的当前属性值
            2.将属性值赋值给动画对象

五、ValueAnimator代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        ValueAnimator valueAnimator =  new  ValueAnimator();  
         valueAnimator.setDuration( 3000 );                              //设置动画时间
         valueAnimator.setObjectValues( new  PointF( 0 0 ));              //设置目标值
         valueAnimator.setInterpolator( new  LinearInterpolator());      //设置插值方式
         valueAnimator.setEvaluator( new  TypeEvaluator<PointF>()        //设置当前值得计算方式
         {
             // fraction = t / duration  
             @Override  
             public  PointF evaluate( float  fraction, PointF startValue, //设置当前属性值得计算方式
                     PointF endValue)  
             {  
                 Log.e(TAG, fraction *  3  "" );  
                 // x方向200px/s ,则y方向0.5 * 10 * t  
                 PointF point =  new  PointF();  
                 point.x =  200  * fraction *  3 ;  
                 point.y =  0 .5f *  200  * (fraction *  3 ) * (fraction *  3 );  
                 return  point;  
             }  
         });  
   
         valueAnimator.addUpdateListener( new  AnimatorUpdateListener()   //设置监听器,并在监听器中给对象赋当前属性值
         {  
             @Override  
             public  void  onAnimationUpdate(ValueAnimator animation)  
             {  
                 PointF point = (PointF) animation.getAnimatedValue();  
                 mBlueBall.setX(point.x);  
                 mBlueBall.setY(point.y);  
   
             }  
         });  
        valueAnimator.start();  

3. Object Animator的工作方式

        如果理解了Value Animator后,Object Animator理解起来也不是太难。因为他们很相似,Value Animator分两步执行,而Object Animator合二为一了,主要是省去了第二步,因为Object Animator已经在初始化时就指定了要改变的属性值了,不多说,上代码:

1
2
3
4
          ObjectAnimator
          .ofFloat(view,  "rotationX" 0 .0F,  360 .0F)
          .setDuration( 500 )
          .start();  

        对于Object Animator,有如下注意点:

                1、提供了ofInt、ofFloat、ofObject,这几个方法都是设置动画作用的元素属性。

                2、动画更新的过程中,会不断调用setPropName更新元素的属性,所有使用Object Animator更新某个属性,必须得有getter(设置一个属性值的时候)和setter方法~如果你操作对象的该属性方法里面,比如上例的setRotationX如果内部没有调用view的重绘,则你需要自己按照下面方式手动调用。

1
2
3
4
5
6
7
8
9
         anim.addUpdateListener( new  AnimatorUpdateListener()  
         {  
             @Override  
             public  void  onAnimationUpdate(ValueAnimator animation)  
             {  
                view.postInvalidate();  
                view.invalidate();  
             }  
         });  

4. 动画事件的监听

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
         ObjectAnimator anim = ObjectAnimator.ofFloat(mBlueBall,  "alpha" 0 .5f);  
           
         anim.addListener( new  AnimatorListener()  
         {  
   
             @Override  
             public  void  onAnimationStart(Animator animation)  
             {  
                 Log.e(TAG,  "onAnimationStart" );  
             }  
   
             @Override  
             public  void  onAnimationRepeat(Animator animation)  
             {  
                 // TODO Auto-generated method stub  
                 Log.e(TAG,  "onAnimationRepeat" );  
             }  
   
             @Override  
             public  void  onAnimationEnd(Animator animation)  
             {  
                 Log.e(TAG,  "onAnimationEnd" );  
                 ViewGroup parent = (ViewGroup) mBlueBall.getParent();  
                 if  (parent !=  null )  
                     parent.removeView(mBlueBall);  
             }  
   
             @Override  
             public  void  onAnimationCancel(Animator animation)  
             {  
                 // TODO Auto-generated method stub  
                 Log.e(TAG,  "onAnimationCancel" );  
             }  
         });  
         anim.addListener( new  AnimatorListenerAdapter()  
         {  
                @Override  
                public  void  onAnimationEnd(Animator animation)  
                {  
                      Log.e(TAG,  "onAnimationEnd" );  
                      ViewGroup parent = (ViewGroup) mBlueBall.getParent();  
                      if  (parent !=  null )  
                            parent.removeView(mBlueBall);  
                }  
         });  
         anim.start();
  

5. 动画的组合Animator Set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
         ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall,  "scaleX" ,   1 .0f, 2f);  
         ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall,  "scaleY" ,   1 .0f, 2f);  
         ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall,   "x" ,  cx ,  0f);  
         ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall,   "x" , cx);  
           
         /** 
          * anim1,anim2,anim3同时执行 
          * anim4接着执行 
          */  
         AnimatorSet animSet =  new  AnimatorSet();  
         animSet.play(anim1).with(anim2);  
         animSet.play(anim2).with(anim3);  
         animSet.play(anim4).after(anim3);  
         animSet.setDuration( 1000 );  
         animSet.start();  

6. ViewPropertyAnimator

        不知道为了什么,网上的教程,把这个东西放到了最后,但是这个可是超级好用的啊,搞不懂
    1. 这个类操作View对象的。
    2. 提供链式调用设置多个属性动画,这些动画同时进行的。
    3. 更好的性能,多个属性动画是一次同时变化,只执行一次UI刷新。
    4. 每个属性提供两种类型方法设置。
    5. 这个类只能通过View的animate()获取引用进行通话设置。
       imageView.animate()
.setDuration(4000)
.rotationY(45f)
.translationX(imageView.getWidth())
.alpha(0f);























这篇关于Android 属性动画(Property Animation)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146179

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使