安卓学习笔记之动画(下)
来源:互联网 发布:mysql update 2张表 编辑:程序博客网 时间:2024/05/23 12:10
一、内容概述
本篇侧重讲述属性动画,接上一篇安卓学习笔记之动画(上) ,包含如下内容
- 属性动画
- ObjectAnimator 的使用 - ValueAnimator 的使用 - PropertyValuesHolder 的使用 - ViewPropertyAnimator 的使用 - AnimatorSet的使用
- 插值器与估值器浅析
二、属性动画
属性动画概述
- 属性动画是在API11中加入的新特性,在android2.3以下可以使用nineoldandroids兼容库。- 属性动画是真实改变一个view的相关属性。而view动画不能改变一个view的真实属性。- 属性动画作用对象更加宽泛,不仅限于作用于view,甚至可以没有作用的对象。
ViewPropertyAnimator的使用
1.示例
@TargetApi(Build.VERSION_CODES.KITKAT) public void animate(View view) { final ViewPropertyAnimator animator = view.animate().x(200).y(300).alphaBy(-0.5f).rotationBy(60f).setInterpolator(new BounceInterpolator()).scaleXBy(0.3f).xBy(20).setDuration(2000); Log.e("TAG", view.getTranslationX() + " : " + view.getX()); animator.setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { animator.alpha(1f).xBy(100).scaleY(2f).translationY(100).setDuration(3000).setInterpolator(new CycleInterpolator(5)).start(); Log.e("TAG", "animating..."); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); // 使用此方法 api>19// animator.setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {// @Override// public void onAnimationUpdate(ValueAnimator animation) {//// }// }); animator.start(); }
2.使用解析
1、获取ViewPropertyAnimator对象
通过view.animate()方法获取ViewPropertyAnimator对象animator
2、通过animator来改变一个view的属性
animator.alpha(1f).xBy(100).scaleY(2f).translationY(100).setDuration(3000).setInterpolator(new CycleInterpolator(5));
方法解析:
* x(),y()方法分别改变view的x,y坐标到特定的值,绝对移动 * xBy(offset),yBy(offset),view的x,y坐标的相对改变,相对值(offset),即相对当前移动多少,相对移动(alphaBy,translationXBy()等类似) * translationX(),translationY()改变的是view的translationX,translationY值,即偏移量 * rotation() 旋转view到特定的角度 * scaleX(),scaleY() 缩放 * setInterpolator() 设置插值器 * withStartAction(Runnable runnable) 动画开始动作 API level 16 * withEndAction(Runnable runnable) 动画结束动作,只有动画正常结束时进行 API level 16
注:
1、translationX表示的是view的x方向的偏移量(offset,左移为负,右移为正),x表示view的x坐标 2、没有调用start()方法,动画依然可以运行,内部隐式启动,自己也可调用start启动
3、监听动画执行
- animator.setListener 设置动画状态监听 - onAnimationStart 当动画开始 - onAnimationEnd 当动画结束 - onAnimationCancel 当动画取消 - onAnimationRepeat 当动画重复- animator.setUpdateListener 设置更新监听, 使用此方法 api>=19
4、Activity退出时停止动画,防止内存泄漏
@Override protected void onDestroy() { super.onDestroy(); if (animator != null) { animator.cancel(); animator = null; } }
ObjectAnimator 的使用
示例
/** * ObjectAnimator * * @param view */ public void objectAnimator(final View view) { final ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleX", 1, 0.5f, 1); animator.addListener(new Animator.AnimatorListener() { // 设置动画监听 @Override public void onAnimationStart(Animator animation) { ObjectAnimator.ofFloat(view, "scaleY", 1, 0.5f, 1).setDuration(1000).start(); } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animator.setDuration(1000).start(); }
使用解析
ObjectAnimator是ValueAnimator的继承类,相比Animation动画,它并不提供直接的四种动画子类,而是以of方法来操作view的相关属性,
常见of方法
- ofArgb(Object target, String propertyName, int... values)- ofFloat(Object target, String propertyName, float... values)- ofInt(Object target, String propertyName, int... values)- ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)- ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)
offXXX方法分析
target:指要操作的目标view或对象 propertyName: 指属性名,诸如alpha,scaleX,scaleY,rotationX,rotationY,translationX,translationY values: 指操作的属性的值变化,比如ofFloat(targetView,"alpha",0,1);表示透明度从0到1
- PropertyValuesHolder的使用
PropertyValuesHolder可以将设置的属性变化效果临时存储起来,最后一起设置给view
/** * PropertyValuesHolder的使用 * @param view */ public void propertyValuesHolder(View view) { final PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1, 0.5f, 1); final PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1, 0.5f, 1); final PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1, 0.5f, 1); final ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(ivBall, alpha, scaleX, scaleY); animator.setDuration(1000).start(); }
4.设置动画监听
- addListener 添加动画监听,可以监听动画的开始,取消,结束,重复- addUpdateListener 添加更新监听,- addPauseListener 添加动画暂停监听
可以使用AnimatorListenerAdapter选择性的监听
animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); } });
5.xml中的写法
<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:propertyName="scaleX" android:valueFrom="1" android:valueTo="0.5f" android:valueType="floatType"></objectAnimator>
6.防止内存泄漏
Activity退出时取消动画,防止内存泄漏,调用cancel方法即可、
7.使用原则
使用ObjectAnimator 要注意,1、被操作的view的属性(property)要有set与get方法,2、同时set方法对view的操作能够反映出来,否则操作失败
8.对任意对象做动画
针对以上使用原则若有一条不满足则会使动画无效,官方给出三种解决方案
1、如果你有权限的话,给你的对象添加set与get方法2、用一个类来包装原始对象,间接为其提供set与get方法3、采用ViewAnimator,监听动画过程,自己实现属性的改变
ValueAnimator 的使用的使用
ValueAnimator相对ObjectAnimator来说,可以不用操作任何对象,通常是操纵一个值的变化过程,监听变化的过程,在其中做相应的属性操作
使用示例
public void valueAnimator(final View view) { final ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1); valueAnimator.setDuration(1000); valueAnimator.start(); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { final float fraction = animation.getAnimatedFraction(); Log.e("TAG", "fraction=" + fraction); view.setTranslationY((float) (Math.sin(fraction*2*3.14159) * 200)); view.setTranslationX((float) (Math.sin(fraction*2*3.14159) * 200)); } }); }
使用解析
1、常见ofXXX方法
ofArgb(int... values)ofFloat(float... values)ofInt(int... values)ofPropertyValuesHolder(PropertyValuesHolder... values)ofObject(TypeEvaluator evaluator, Object... values)
2、设置监听(同ObjectAnimator)
3、xml中定义ValueAnimator
<?xml version="1.0" encoding="utf-8"?><animator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"></animator>
4、在java代码中加载动画
final Animator animator = AnimatorInflater.loadAnimator(AnimatorActivity.this,R.animator.animator_value);
5、还可以设置估值器与插值器
valueAnimator.setEvaluator(new FloatEvaluator()); valueAnimator.setInterpolator(new AccelerateInterpolator());
AnimatorSet的使用
使用示例
1.使用java代码
public void set(View view) { AnimatorSet set = new AnimatorSet(); final ObjectAnimator scaleX = ObjectAnimator.ofFloat(ivBall, "scaleX", 1, 0.5f, 1); final ObjectAnimator scaleY = ObjectAnimator.ofFloat(ivBall, "scaleY", 1, 0.5f, 1); final ObjectAnimator translationX = ObjectAnimator.ofFloat(ivBall, "translationX", 0, 100, 0); final ObjectAnimator translationY = ObjectAnimator.ofFloat(ivBall, "translationY", 0, 100, 0); final ObjectAnimator rotationX = ObjectAnimator.ofFloat(ivBall, "rotationX", 0, 360); final ObjectAnimator rotationY = ObjectAnimator.ofFloat(ivBall, "rotationY", 0, 360); final ObjectAnimator alpha = ObjectAnimator.ofFloat(ivBall, "alpha", 1, 0.5f, 1);// set.playTogether(scaleX, scaleY, translationX, translationY, rotationX, rotationY, alpha); // 一起// set.playSequentially(scaleX, scaleY, translationX, translationY, rotationX, rotationY, alpha); // 顺序 set.play(scaleX).with(scaleY).with(translationX).with(translationY).before(rotationX); set.play(rotationX).with(rotationY).after(alpha); // 按指定顺序 set.setDuration(2000).start(); }
2.在xml中定义动画
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleY" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="alpha" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /></set>
在java代码中使用定义的动画
final Animator set = AnimatorInflater.loadAnimator(context,R.animator.animator_set); set.setTarget(target); set.start();
3、添加监听 (同上,三种监听方式)
使用解析
通过playTogether可以使动画一起播放,playSequentially使动画按次序播放,通过play方法结合with、before、after可以明确指定播放次序,with指两个动画一起播放,before、after分别指一个动画先/后于另一个动画播放
插值器与估值器浅析
插值器(TimeInterpolator)
1、插值器的概念
插值器定义了动画变化的速率,通过不同的函数实现,来完成动画的加速,减速,回弹,弹跳等效果。根据时间流逝的百分比来计算出当前属性改变的百分比。
2、常见插值器
OvershootInterpolator@android:anim/overshoot_interpolator快速到达终点并超出一小步最后回到终点 AccelerateDecelerateInterpolator@android:anim/accelerate_decelerate_interpolator先加速再减速 AccelerateInterpolator@android:anim/accelerate_interpolator加速 AnticipateInterpolator@android:anim/anticipate_interpolator先回退一小步然后加速前进 AnticipateOvershootInterpolator@android:anim/anticipate_overshoot_interpolator在上一个基础上超出终点一小步再回到终点 DecelerateInterpolator@android:anim/decelerate_interpolator减速 LinearInterpolator@android:anim/linear_interpolator匀速 BounceInterpolator@android:anim/bounce_interpolator最后阶段弹球效果 CycleInterpolator@android:anim/cycle_interpolator周期运动
3、分析CycleInterpolator 源码
由源码可以看到插值器输入的值与返回值关系表达式为:(float)(Math.sin(2 * mCycles * Math.PI * input)),当输入一直增大时,输出值在成sin曲线值来回交变,形成所需要的cycle效果
@HasNativeInterpolatorpublic class CycleInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public CycleInterpolator(float cycles) { mCycles = cycles; } public CycleInterpolator(Context context, AttributeSet attrs) { this(context.getResources(), context.getTheme(), attrs); } /** @hide */ public CycleInterpolator(Resources resources, Theme theme, AttributeSet attrs) { } public float getInterpolation(float input) { return (float)(Math.sin(2 * mCycles * Math.PI * input)); } private float mCycles;}
4、自定义插值器
自定义Interpolator类实现Interpolator,并实现getInterpolation方法即可
简单示例:
package com.yu.propertyanimator;import android.annotation.TargetApi;import android.os.Build;import android.view.animation.Interpolator;/** * Created by pecu on 2016/08/27. */@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)public class MyInterpolator implements Interpolator { @Override public float getInterpolation(float input) { return (float) Math.abs(Math.sin(input * Math.PI)); // 折回效果 }}
估值器(TypeEvaluator)
通过插值器所获的属性改变百分比来估算当前的属性值
1、 TypeEvaluator接口
先看TypeEvaluator接口,发现只有一个抽象方法evaluate,用于通过fraction来估算出当前值
package android.animation;public interface TypeEvaluator<T> { /** * This function returns the result of linearly interpolating the start and end values, with * <code>fraction</code> representing the proportion between the start and end values. The * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>, * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>, * and <code>t</code> is <code>fraction</code>. * * @param fraction The fraction from the starting to the ending values * @param startValue The start value. * @param endValue The end value. * @return A linear interpolation between the start and end values, given the * <code>fraction</code> parameter. public T evaluate(float fraction, T startValue, T endValue);}
2、查看FloatEvaluator 源码
可以发现,evaluate方法的返回值是通过这样一个公式计算所得result = x0 + t * (x1 - x0);
package android.animation;public class FloatEvaluator implements TypeEvaluator<Number> { /** * @param fraction The fraction from the starting to the ending values * @param startValue The start value; should be of type <code>float</code> or * <code>Float</code> * @param endValue The end value; should be of type <code>float</code> or <code>Float</code> * @return A linear interpolation between the start and end values, given the * <code>fraction</code> parameter. */ public Float evaluate(float fraction, Number startValue, Number endValue) { float startFloat = startValue.floatValue(); return startFloat + fraction * (endValue.floatValue() - startFloat); }}
3、自定义TypeEvaluator
自定义估值器较为简单,只需要实现TypeEvaluator接口,并重写evaluate方法即可
一个简单自定义TypeEvaluator
package com.yu.propertyanimator;import android.animation.TypeEvaluator;import android.graphics.Point;/** * Created by pecu on 2016/08/27. */public class MyEvaluator implements TypeEvaluator<Point> { Point point; @Override public Point evaluate(float fraction, Point startValue, Point endValue) { if (point == null) { point = new Point(); point.x = (int) (startValue.x + fraction * (endValue.x - startValue.x)); point.y = (int) (startValue.y + fraction * (endValue.y - startValue.y)); } else { point.x = (int) (startValue.x + fraction * (endValue.x - startValue.x)); point.y = (int) (startValue.y + fraction * (endValue.y - startValue.y)); } return point; }}
4、使用自定义的Evaluator
/** * 仿小球落地后回弹几次 * @param view */ public void evaluate(View view) { final ValueAnimator valueAnimator = ValueAnimator.ofObject(new MyEvaluator(), new Point(0, 0), new Point(0, screenHeight - 2*ivBall.getHeight())); valueAnimator.setInterpolator(new BounceInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { Point point = (Point) animation.getAnimatedValue(); ivBall.setX(point.x); ivBall.setY(point.y); } }); valueAnimator.setDuration(1000); valueAnimator.start(); }
源码下载
- 安卓学习笔记之动画(下)
- 安卓学习笔记之动画(上)
- 安卓动画学习笔记
- 安卓动画学习笔记
- 安卓学习之笔记(二)
- 安卓动画学习
- 安卓学习之控件学习笔记
- 工作笔记之安卓开机动画与logo修改
- 安卓属性动画-笔记
- 安卓动画效果笔记
- 安卓动画之补间动画(Tween Animations)
- 安卓动画之帧动画(Frame Animations)
- 安卓动画之属性动画(Property Animation)
- 安卓动画之Frame Animation(逐帧动画)
- 安卓学习笔记之四(布局)
- 安卓学习笔记之Activity(一)
- 安卓学习笔记之service(一)
- 安卓学习之文件存储(笔记)
- 树莓派GPIO学习--1.语言选择
- 编译优化
- [C/C++笔面试]不使用库函数将整数转换为字符串
- 傻瓜也会lua-bindings(Cocos2d-x 3.8.1)(二)
- [LeetCode] 116. Populating Next Right Pointers in Each Node
- 安卓学习笔记之动画(下)
- Android 属性动画(Property Animation) 完全解析 (上)
- Markdown 语法说明
- hadoop中执行jar时一直卡在INFO mapreduce.Job: Running job
- angularjs Controller
- python 学习(十九)之浅谈闭包
- 【linux系统学习笔记】Linux系统初识
- 数据库知识点总结(发展,约束,索引,触发器,连接池,视图,事务)
- Spring AOP 注解配置