在应用中, 动画效果提升用户体验, 主要分为View动画和属性动画. View动画变换场景图片效果, 效果包括平移(translate), 缩放(scale), 旋转(rotate), 透明(alpha); 属性动画动态地改变改变属性, 达到动画效果. 本文包含源码.

Animation

本文源码的GitHub下载地址


View动画

动画包含四种平移, 缩放, 旋转, 透明, 也支持组合使用.

  1. mAnimations = new ArrayList<>();
  2. mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_translate));
  3. mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_scale));
  4. mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_rotate));
  5. mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_alpha));
  6. mAnimations.add(AnimationUtils.loadAnimation(context, R.anim.anim_all));

平移动画: duration持续时间; fromXDelta起始X坐标, fromYDelta起始Y坐标; toXDelta终止X坐标, toYDelta终止Y坐标.

  1. <set xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:fillAfter="true"
  3. android:interpolator="@android:anim/accelerate_interpolator">
  4. <!--平移动画-->
  5. <translate
  6. android:duration="2000"
  7. android:fromXDelta="50"
  8. android:fromYDelta="-100"
  9. android:toXDelta="0"
  10. android:toYDelta="0"/>
  11. </set>

fillAfter动画完成后停留, 即在平移后不复原; interpolator变换插值器.

缩放动画: fromXScale起始宽度比例, fromYScale起始高度比例; toXScale终止宽度比例,toYScale终止高度比例.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">
  3. <!--缩放动画-->
  4. <scale
  5. android:duration="2000"
  6. android:fromXScale="0.0"
  7. android:fromYScale="0.0"
  8. android:toXScale="1.0"
  9. android:toYScale="1.0"/>
  10. </set>

旋转动画: fromDegrees起始角度, toDegrees终止角度; pivotX旋转中心X坐标, pivotY旋转中心Y坐标.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:fillAfter="true">
  4. <!--旋转动画-->
  5. <rotate
  6. android:duration="2000"
  7. android:fromDegrees="0"
  8. android:pivotX="50%"
  9. android:pivotY="50%"
  10. android:toDegrees="-720"/>
  11. </set>

透明动画: fromAlpha起始透明度, toAlpha终止透明度.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android">
  3. <!--透明动画-->
  4. <alpha
  5. android:duration="2000"
  6. android:fromAlpha="0.1"
  7. android:toAlpha="1.0"/>
  8. </set>

组合动画: 融合平移, 缩放, 旋转, 透明四种动画, 效果是图片旋转着从左上角滚入屏幕, 逐渐变大变清晰.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <set xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:duration="2000">
  4. <!--平移动画-->
  5. <translate
  6. android:fromXDelta="50"
  7. android:fromYDelta="-100"
  8. android:toXDelta="0"
  9. android:toYDelta="0"/>
  10. <!--缩放动画-->
  11. <scale
  12. android:duration="2000"
  13. android:fromXScale="0.0"
  14. android:fromYScale="0.0"
  15. android:toXScale="1.0"
  16. android:toYScale="1.0"/>
  17. <!--旋转动画-->
  18. <rotate
  19. android:duration="2000"
  20. android:fromDegrees="0"
  21. android:pivotX="50%"
  22. android:pivotY="50%"
  23. android:toDegrees="-720"/>
  24. <!--透明动画-->
  25. <alpha
  26. android:duration="2000"
  27. android:fromAlpha="0.1"
  28. android:toAlpha="1.0"/>
  29. </set>

帧动画: 特殊动画, 不断变换图片, 模拟动画效果. animation-list动画列表, 每个item表示一个图片, duration是图片停留时间. oneshot值是true持续一次, false不断循环.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <animation-list
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:oneshot="false">
  5. <!--循环显示三个图片-->
  6. <item
  7. android:drawable="@drawable/seo_square"
  8. android:duration="250"/>
  9. <item
  10. android:drawable="@drawable/kim_square"
  11. android:duration="250"/>
  12. <item
  13. android:drawable="@drawable/sunny_square"
  14. android:duration="250"/>
  15. </animation-list>

自定义动画: 重载initializeapplyTransformation方法. initialize初始化动画;applyTransformation应用转换, 参数interpolatedTime表示差值次数.

  1. public class Rotate3dAnimation extends Animation {
  2. private final float mFromDegrees;
  3. private final float mToDegrees;
  4. private final float mCenterX;
  5. private final float mCenterY;
  6. private final float mDepthZ;
  7. private final boolean mReverse;
  8. private Camera mCamera;
  9. public Rotate3dAnimation(
  10. float fromDegrees, float toDegrees,
  11. float centerX, float centerY,
  12. float depthZ, boolean reverse) {
  13. mFromDegrees = fromDegrees;
  14. mToDegrees = toDegrees;
  15. mCenterX = centerX;
  16. mCenterY = centerY;
  17. mDepthZ = depthZ;
  18. mReverse = reverse;
  19. }
  20. @Override public void initialize(int width, int height, int parentWidth, int parentHeight) {
  21. super.initialize(width, height, parentWidth, parentHeight);
  22. mCamera = new Camera();
  23. }
  24. @Override protected void applyTransformation(float interpolatedTime, Transformation t) {
  25. final float fromDegrees = mFromDegrees;
  26. float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); // 结尾度数
  27. // 中心点
  28. final float centerX = mCenterX;
  29. final float centerY = mCenterY;
  30. final Camera camera = mCamera;
  31. final Matrix matrix = t.getMatrix();
  32. camera.save(); // 照相机
  33. // Z轴平移
  34. if (mReverse) {
  35. camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
  36. } else {
  37. camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
  38. }
  39. camera.rotateY(degrees); // Y轴旋转
  40. camera.getMatrix(matrix);
  41. camera.restore();
  42. // View的中心点进行旋转
  43. matrix.preTranslate(-centerX, -centerY);
  44. matrix.postTranslate(centerX, centerX);
  45. super.applyTransformation(interpolatedTime, t);
  46. }
  47. }

RecyclerList的项也支持动画式插入.

  1. @Override public void onBindViewHolder(final GridViewHolder holder, final int position) {
  2. // ...
  3. setAnimation(holder.getContainer(), position);
  4. }
  5. private void setAnimation(View viewToAnimate, int position) {
  6. if (position > mLastPosition || mLastPosition == -1) {
  7. Animation animation = AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left);
  8. viewToAnimate.startAnimation(animation);
  9. mLastPosition = position;
  10. }
  11. }

属性动画

属性动画通过变换对象属性, 实现动画效果, 对应属性必须含有set和get方法, 支持调用. 对于自定义的属性, 则使用Wrapper或插值方式.

属性动画仅支持API 11以上版本, 以前版本使用支持库.

Wrapper: 根据View的变换属性, 提供宽度(width)的设置(set)与获取(get).

  1. private void performWrapperAnimation(final View view, final int start, final int end) {
  2. ViewWrapper vw = new ViewWrapper(view);
  3. ObjectAnimator.ofInt(vw, "width", start, end).setDuration(2000).start(); // 启动动画
  4. }
  5. // 视图包装, 提供Width的get和set方法
  6. private static class ViewWrapper {
  7. private View mView;
  8. public ViewWrapper(View view) {
  9. mView = view;
  10. }
  11. @SuppressWarnings("unused")
  12. public int getWidth() {
  13. return mView.getLayoutParams().width;
  14. }
  15. @SuppressWarnings("unused")
  16. public void setWidth(int width) {
  17. mView.getLayoutParams().width = width;
  18. mView.requestLayout();
  19. }
  20. }

requestLayout: 当View确定自身不再适合现有区域时, 调用requestLayout, 要求Parent View重新调用onMeasure和onLayout重新设置当前View的位置.
特别当View的LayoutParams发生改变时, 并且值还未应用至View上, 这时候适合调用此方法.
invalidate: View本身调用迫使View重绘.

差值: 使用ValueAnimator(属性动画), 并设置更新, 添加IntEvaluator(整数估值器), 渐进地设置View的宽度.

  1. private void performListenerAnimation(final View view, final int start, final int end) {
  2. ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
  3. valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  4. // 持有一个IntEvaluator对象,方便下面估值的时候使用
  5. private IntEvaluator mEvaluator = new IntEvaluator();
  6. @Override
  7. public void onAnimationUpdate(ValueAnimator animator) {
  8. // 获得当前动画的进度值,整型,1-100之间
  9. int currentValue = (Integer) animator.getAnimatedValue();
  10. // 获得当前进度占整个动画过程的比例,浮点型,0-1之间
  11. float fraction = animator.getAnimatedFraction();
  12. // 直接调用整型估值器通过比例计算出宽度,然后再设给Button
  13. view.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
  14. view.requestLayout();
  15. }
  16. ![
  17. ![
  18. ![ezgif.com-b9f6ca81b1.gif](https://user-gold-cdn.xitu.io/2017/1/4/5cba3a11357c16ea9129f9c7a6b9f1cc)
  19. ](http://upload-images.jianshu.io/upload_images/749674-cdf2dd08094b34fa.gif?imageMogr2/auto-orient/strip)
  20. ](http://upload-images.jianshu.io/upload_images/749674-a45e2ffca44d4f79.gif?imageMogr2/auto-orient/strip)
  21. });
  22. valueAnimator.setDuration(2000).start();
  23. }

注意LayoutParams的数值是px像素, 需要dp转换px.


效果

效果

应用使用动画, 提升用户体验, 但要注意性能. 大量使用图片可能导致OOM; 循环动画无法释放可能产生内存泄露; 注意px与dp之间的转换.

OK, that's all! Enjoy it!

View动画和属性动画的更多相关文章

  1. Android开发——View动画、帧动画和属性动画详解

    0. 前言   Android动画是面试的时候经常被问到的话题.我们都知道Android动画分为三类:View动画.帧动画和属性动画. 先对这三种动画做一个概述: View动画是一种渐进式动画,通过图 ...

  2. android 学习随笔二十六(动画:属性动画)

    属性动画,属性动画是真正改变对象的某个属性的值 * 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变1.位移:* 第一个参数target指定要显示动画的组件* 第二个参数proper ...

  3. Android开发实战之补间动画和属性动画

    说起动画,其实一点也不陌生,在使用一款app的时候为了优化用户体验,多多少少的,都会加入动画. 安卓中的动画,分为两大类:补间动画和属性动画.本篇博文会详细介绍总结这两大动画,希望本篇博文对你的学习和 ...

  4. Android动画基础——属性动画(Property Animation)

    本篇涉及例子下载:Github 本篇讲android 3.0引入的属性动画框架,上篇写视图动画View Animation时就说过ViewAnimation的缺点,那就是动画作用的是view本身的视觉 ...

  5. View体系之属性动画

    (内容省略了valueAnimator和PropertyValueHolder使用) 属性动画的使用的主要方式是AnimatorSet和ObjectAnimator配合使用.ObjectAnimato ...

  6. Android动画:模拟开关按钮点击打开动画(属性动画之平移动画)

    在Android里面,一些炫酷的动画确实是很吸引人的地方,让然看了就赏心悦目,一个好看的动画可能会提高用户对软件的使用率.另外说到动画,在Android里面支持3种动画: 逐帧动画(Frame Ani ...

  7. android104 帧动画,补间动画,属性动画

    ##帧动画FrameAnimation* 多张图片快速切换,形成动画效果* 帧动画使用xml定义 package com.itheima.frameanimation; import android. ...

  8. Android 动画及属性动画

    Android 平台提供了一套完整的动画框架,在Android3.0之前有两种动画Tween Animation(补间动画)和Frame Animation(帧动画), 对应SDK中的View Ani ...

  9. Android至ViewPager添加切换动画——使用属性动画

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/44200623 ViewPager作为Android最经常使用的的组件之中的一个.相 ...

随机推荐

  1. C# WinForm 技巧:COMBOBOX搜索提示

    comboBox和textBox支持内置的搜索提示功能, 在form的InitializeComponent()中添加如下语句:   this.comboBox1.AutoCompleteCustom ...

  2. cat命令使用

    cat:concatenate files and print on the standard output合并文件并输出 主要用法 1.cat f1.txt,查看f1.txt文件的内容. 2.cat ...

  3. Linux系统启动过程

    1. 从BIOS到KERNEL BIOS自检->MBR(GRUB)->KERNEL->KERNEL自解压->内核初始化->内核启动 BIOS自检 当电脑开机的时候,电脑会 ...

  4. Tomcat下conf下server.xml的文件配置信息

    Tomcat下conf下server.xml的文件配置信息,基本上不用做任何修改就可以使用,修改的地方就是host区域的一些配置,此文件设置端口为80. 注意:Tomcat配置文件中(即server. ...

  5. table隔行变色

    table tr:nth-child(2n) {         background: #EEF8F0;     }     table tr:nth-child(2n+1) {         b ...

  6. Android handler的使用简单示例

    Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMes ...

  7. Angularjs2 入门

    1.创建文件夹 mkdir angular2-app cd angular2-app 2.配置Typescript 需要通过一些特殊的设置来指导Typesript进行编译.新建一个 tsconfig. ...

  8. qlikview 扩展插件制作教程-EchartsGeoMap

    效果图   显示效果和echarts官方demo一样,运行速度尚可. 第一次写博客,排版很渣以后慢慢改进. 基础知识 以EchartsGeoMap为例,讲一下怎么制作一个基础的QlikView Ext ...

  9. xampp 下安装mysql-python

    pip install mysql-python修改路径PATH="$PATH":(/mysql/bin 路径)brew install mysql-connector-c

  10. org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [XXX] in DispatcherServlet with name 'springMVC'

    在web.xml中添加 <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern ...