这一段时间在看Activity的工作流程,奈何内容太多,涉及到的东西有点多,暂时放下这一篇,慢慢来。先总结一下自己学过的Android自定义动画与属性动画。

Android的View动画分为两类变换动画(Tweened Animation)以及帧动画(Frame by-frame Animation)。

变换动画又分为四大类:平移(translate),旋转(rotate),缩放(scale),透明度(alpha)。

View动画的使用

View动画的编程有两种方法:一种是通过xml中编写,另一种在Java代码中编程控制。
在系统支持xml的view动画中只支持ttranslate,rotate,scale,alpha四种标签,下面是一个实例:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"android:zAdjustment="normal"><translate
        android:duration="100"android:fromXDelta="0"android:fromYDelta="0"android:interpolator="@android:anim/linear_interpolator"android:toXDelta="100"android:toYDelta="0"/><rotate
        android:duration="400"android:fromDegrees="0"android:toDegrees="45"/></set>

代码则是这么调用:

        Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim1);Img.startAnimation(animation);

在这里面,值得一提的是:属性android:interpolator插值器,这是指动画的是按照怎么变化规律变化的,,比如线性变化,加速变化等等,就像初中物理那样,一个物体在做匀速运动还是变速运动。

除了使用xml配置之外,还可以使用代码配置并且控制:

                AlphaAnimation alphaAnimation = new AlphaAnimation(1, (float) 0.1);alphaAnimation.setDuration(3000);Img.startAnimation(alphaAnimation);

思路都是一样的,不过只是在xml调用的时候,声明的Animation需要调用AnimationUtils.loadAnimation(Context context,int id);代码直接声明相应类型的动画类型即可。

还有一点,那就是Activity切入切出时的动画设置,必须调用overridePendingTransition(int enterAnim,int exitAnim)。

自定义View动画

自定义View动画,我需要继承一个Animation的类,再通过矩阵变换来转换其中的动画效果。有一位大神已经通过矩阵的方式将Animation解读了一遍,让我受益良多。

这里是地址:Android动画的矩阵运用

在自定义View动画的时候,Camera类经常被用到,它相当于是一个摄像机一样从不同的角度来观察对象,其结果可以简化矩阵变换的过程。同时也要重写两个方法:
1.public void initialize(int width,int height,int parentWidth,int parentHeight)是用来初始化一些数值或者类。
2.protected void applyTransformation(float interpolateTime,Transformation t)这是用来编写矩阵的变换的。

让我们编写一个3D旋转的自定义动画吧。

public class Roate3dAnimation extends Animation{private final float mFromDegrees;private final float mToDegress;private final float mCenterX;private final float mCenterY;private final float mDepthZ;private final boolean mReverse;private Camera mCamera;//构造器获取初始角度,变化都角度,获取中心的点的x,y,z坐标public Roate3dAnimation(float fromDegress,float toDegress,float centerX,float centerY,float depthZ,boolean reverse){mFromDegrees = fromDegress;mToDegress = toDegress;mCenterX = centerX;mCenterY = centerY;mDepthZ = depthZ;mReverse = reverse;}//初始化Camera@Overridepublic void initialize(int width,int height,int parentWidth,int parentHeight){super.initialize(width, height, parentWidth, parentHeight);mCamera = new Camera();}@Overrideprotected void applyTransformation(float interpolatedTime,Transformation t){final float fromDegress = mFromDegrees;//角度变化随着时间变化而变化:当前角度=起始角度+((结束角度-起始角度)*角度/每秒)float degress = fromDegress + ((mToDegress - fromDegress) * interpolatedTime);final float centerX = mCenterX;final float centerY = mCenterY;final Camera camera = mCamera;//获取此时的矩阵final Matrix matrix = t.getMatrix();//camera保存此时camera状态camera.save();//mReverse是指是反向旋转还是正向旋转if(mReverse){camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);}else {camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));}//camera对象额旋转camera.rotateY(degress);//获取旋转后的矩阵camera.getMatrix(matrix);camera.restore();matrix.preTranslate(-centerX, -centerY);matrix.postTranslate(centerX, centerY);}}

上面就是通过camera简化了自己计算矩阵的过程。调用对象还是和之前一样:

        Roate3dAnimation dAnimation = new Roate3dAnimation(0, 180, 50, 50, 1, true);dAnimation.setDuration(3000);img.startAnimation(dAnimation);

到这里就说完了自定义View动画了,现在已经和少用这种动画,在API11之后Android加入了强大的动画器:属性动画,来更加简单的的完成更加绚烂多彩的动画了。

属性动画

属性动画,顾名思义,这不是只针对View的动画,而是可以对任意一个对象的进行动画操作,比如说,View动画就很难操作Button中的宽度,而属性动画却能弥补这些缺点。

属性动画中我们常用这么几个类:ValueAnimator,ObjectAnimator,AnimatorSet等。直接让我们看一个例子吧:

        AnimatorSet set = new AnimatorSet();set.playTogether(ObjectAnimator.ofFloat(img, "rotationX", 0.0f,306.0f),ObjectAnimator.ofFloat(img, "rotationY", 0.0f,180.0f),ObjectAnimator.ofFloat(img, "rotation", 0.0f,-90.0f),ObjectAnimator.ofFloat(img, "translationX", 0.0f,90.0f));set.setDuration(5000).start();

从上面这这一段代码,可以清晰的认知到,AnimatorSet是作为一个动画的集合,ObjectAnimator则是通过反射获取对象的属性来变化的。在这里我们值得注意的是第二个参数就是指我们要变化的属性,但是如果对象中没有该属性的get函数和set函数,动画将不会生效。
就会出现如下警告:

Method setX() with type int not found on target class class android.widget.Button

我们同样可以配置xml来处理属性动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:ordering="sequentially" ><objectAnimator
        android:propertyName="RotationX"android:duration="300"android:valueTo="90"android:valueType="intType"/><objectAnimator
        android:propertyName="RotationY"android:duration="300"android:valueTo="90"android:valueType="intType"/></set>

但是用xml来配置属性动画有个缺点就是,很多身后我们无法知道属性的起始值会导致我们的动画出现一些意外的情况,如果用xml来配置,除非提前知道这些值,我们提倡使用代码控制。
还有一个坑,那就是即使引用了本身View里面存在的属性获取,设置的函数还是有可能获取不到。我暂时在源码里面看不出原因。
所以基于以上种种问题,属性动画还是使用代码控制比较好。

那么我们遇到了,对象没有提供set,get的方法的时候,难道就素手无策了吗?不,下面提供三种方案,来解决:

  1. 我们可以获取更高级的权限来修改对象中源码,给相应的对象加上set,get的方法。这是最简单直接的方法,但是比如说Button,这是SDK中实现的,我们往往不可能因此而重新编译一个Android来。
  2. 用一个类来包装原始对象,间接的提供get和set方法。比如说:
    private static class ViewWrapper{private View mTarget;public ViewWrapper(View target){mTarget = target;}public int getWidth(){return mTarget.getLayoutParams().width;}public void setWidth(int width){mTarget.getLayoutParams().width = width;mTarget.requestLayout();}}
  1. 我们可以使用ValueAnimator来监听动画的过程,实现自己的属性的修改,ValueAnimator是ObjectAnimator的父类,它并没有指定对象确提供了修改对象属性的抽象类,我们往往可以调用valueAnimator.addUpdateListener(new AnimatorUpdateListner(){})的方法,下面是例子:
    private void performAnimate(final View target,final int start,final int end){//valueAnimator动画进度条范围ValueAnimator valueAnimator = ValueAnimator.ofInt(1,100);valueAnimator.addUpdateListener(new AnimatorUpdateListener() {//整形插值器的声明private IntEvaluator mEvaluator = new IntEvaluator();@Overridepublic void onAnimationUpdate(ValueAnimator anim) {// TODO Auto-generated method stub//获取此时动画的进度条int currentvalue = (Integer)anim.getAnimatedValue();Log.e("currentvalue", ""+currentvalue);//获取此时进度条占总进度条的百分比float fraction = anim.getAnimatedFraction();//相应属性的变化target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);//刷新对象UItarget.requestLayout();}});valueAnimator.setDuration(5000).start();}

到这里就结束了,属性动画的全部内容,为了检验自己是否明白,自己模仿了知乎的目录动画,做了一个简单的属性动画效果。下面是动画的核心源码:

public class MyFloatMenu extends RelativeLayout{private ImageView menu;private ImageView bell;private ImageView wallet;private ImageView shopping;private ImageView wait_use;private View bellView;private View waitView;private View walletView;private View shopView;private boolean isOpen = false;public MyFloatMenu(Context context){super(context);init(context);}public MyFloatMenu(Context context,AttributeSet attr){super(context,attr);init(context);}public MyFloatMenu(Context context,AttributeSet attr,int defStyle){super(context, attr, defStyle);init(context);}private void init(final Context context){LayoutInflater inflater = LayoutInflater.from(context);View view = inflater.inflate(R.layout.menu, this);menu = (ImageView)view.findViewById(R.id.plus_menu);bellView = inflater.inflate(R.layout.bell, null);waitView = inflater.inflate(R.layout.wait, null);walletView = inflater.inflate(R.layout.wallet, null);shopView = inflater.inflate(R.layout.shopping, null);this.addView(bellView);this.addView(waitView);this.addView(walletView);this.addView(shopView);bellView.setVisibility(View.GONE);waitView.setVisibility(View.GONE);walletView.setVisibility(View.GONE);shopView.setVisibility(View.GONE);menu.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubsetVisible();if(isOpen == false){perform();isOpen = true;}else if (isOpen == true) {backperform();isOpen = false;}}});bellView.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubIntent intent = new Intent(context, testActivity.class);context.startActivity(intent);}});}private void setVisible(){bellView.setVisibility(View.VISIBLE);waitView.setVisibility(View.VISIBLE);walletView.setVisibility(View.VISIBLE);shopView.setVisibility(View.VISIBLE );}public void perform(){AnimatorSet set = new AnimatorSet();set.playTogether(ObjectAnimator.ofFloat(menu, "rotation", 45.0f),ObjectAnimator.ofFloat(bellView, "translationX", 300f),ObjectAnimator.ofFloat(waitView, "rotationZ", 30.0f),ObjectAnimator.ofFloat(waitView, "translationY", 150.0f),ObjectAnimator.ofFloat(waitView, "translationX", 259.8f),ObjectAnimator.ofFloat(walletView, "rotationZ", 60.0f),ObjectAnimator.ofFloat(walletView, "translationX", 150.0f),ObjectAnimator.ofFloat(walletView, "translationY", 259.8f),ObjectAnimator.ofFloat(shopView, "translationY", 300f));set.setDuration(500).start();}public void backperform(){AnimatorSet set = new AnimatorSet();set.playTogether(ObjectAnimator.ofFloat(menu, "rotation", 90.0f),ObjectAnimator.ofFloat(bellView, "translationX", -300f),ObjectAnimator.ofFloat(waitView, "rotationZ", -30.0f),ObjectAnimator.ofFloat(waitView, "translationY", -150.0f),ObjectAnimator.ofFloat(waitView, "translationX", -259.8f),ObjectAnimator.ofFloat(walletView, "rotationZ", -60.0f),ObjectAnimator.ofFloat(walletView, "translationX", -150.0f),ObjectAnimator.ofFloat(walletView, "translationY", -259.8f),ObjectAnimator.ofFloat(shopView, "translationY", -300f));set.setDuration(500).start();}@Overrideprotected void onLayout(boolean change, int l, int t, int r, int b) {// TODO Auto-generated method stubsuper.onLayout(change, l, t, r, b);}}

感谢任玉刚大神的android开发探索艺术以及郭霖大神的博客。

这里附上Github工程的源码:Github

关于Android动画的一点愚见相关推荐

  1. android 动画引擎,一个使用openGL渲染的炫丽Android动画库

    这是一个 android 动画特效库 可以实现各种炫酷动画. github地址: ht t ps:// gith  u b.co m/g pl ib s/an dro id- ma gic-s ur ...

  2. Android动画(一)-视图动画与帧动画

    项目中好久没用过动画了,所以关于动画的知识都忘光了.知识总是不用则忘.正好最近的版本要添加比较炫酷的动画效果,所以也借着这个机会,写博客来整理和总结关于动画的一些知识.也方便自己今后的查阅. Andr ...

  3. Android 动画框架详解,第 1 部分

    2019独角兽企业重金招聘Python工程师标准>>> Android 平台提供了一套完整的动画框架,使得开发者可以用它来开发各种动画效果,本文将向读者阐述 Android 的动画框 ...

  4. android动画详解

    转自:工匠若水 http://blog.csdn.net/yanbober 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今天来一发A ...

  5. android 动画卡顿分析工具

    android 动画卡顿分析工具 Android应用性能优化之分析工具 上一次记录了解决过度绘制的过程,这一次,想先弄清个概念性的东西,就是如何判断顺不顺畅? 这东西其实最初我自己也觉得有点废话,用起 ...

  6. Android动画学习笔记

    Android实战经验之图像处理及特效处理的集锦 https://www.oschina.net/question/231733_44154 Android动画学习笔记 3.0以前,android支持 ...

  7. Android动画系列 - PropertyAnim 详解

    前言: 上一篇文章传统View动画与Property动画基础及比较简单对Android动画系统的基础做了介绍,本篇文章将对PropertyAnimation进行全面深入的探讨,本篇文章可以分为两大块, ...

  8. Android动画渲染过程及原理(matrix),matrix动画,动画优化

    -- 矩阵(Matrix), Matrix动画 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方程组的系数及常数所构成的方阵.在物理学中,矩阵于电路学.力学.光学和量子物理中都 ...

  9. Weex Android 动画揭秘

    原文地址 背景 在目前常见的交互方式中,动画扮演了一个重要的角色. 在 Weex 框架下,Weex 的动画需要屏蔽 CSS/JS 动画与 Android 动画系统的差异,并尽可能的达到60FPS. 本 ...

最新文章

  1. TP,TN,FP,FN
  2. python+appium判断元素存在_python自动化测试应用--Appium元素篇
  3. java鼠标进入高亮效果_鼠标选中文本划词高亮、再次选中划词取消高亮效果
  4. libevent源码学习-----时间管理
  5. 进击的Objective-C--------Objective-C基础(-)
  6. ajax json 封装,Ajax--json(Ajax调用返回json封装代码、格式及注意事项)
  7. Apache Flink 在 bilibili 的多元化探索与实践
  8. Linux设备驱动程序(LDD)中snull的编译问题
  9. JQuery快速入门详解
  10. 调用百度万年历接口判断输入的日期是否是工作日
  11. 常见字符的ASCII码值
  12. 110kV终端变电站电气部分设计
  13. java分布式日志组件
  14. 知识变现海哥:如何利用自己的时间和知识获得财富自由
  15. 关于微信小程序中的取整
  16. CUDA学习:GPU硬件连接模型
  17. 【产品】建立二八法则思维模式:精准定位
  18. Qt Qml 汽车仪表
  19. Google Play ASO 系列 - 最重要的长尾词
  20. Unity自定义字体 包括中文

热门文章

  1. 如何使用开源合成器Natron入门
  2. Java虚拟机学习笔记整理
  3. About Maze Problem
  4. 为什么要在完成电子邮件后存档(Archive)电子邮件
  5. 在北京的那三年——实习
  6. 分枝定界图解(含 Real-Time Loop Closure in 2D LIDAR SLAM论文部分解读及BB代码部分解读)
  7. C++ goto用法
  8. 专家:滴滴优步合并存大数据垄断隐忧
  9. MOOC哈工大2020C语言程序设计精髓编程题在线测试第五周
  10. 情人节程序员用HTML网页表白【告白气球,飞入我的心扉】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript