android动画机制,Android动画机制与使用技巧

`# 前言

Android群英传读书笔记

// SVG部分待补充

目录

4736c347ed2b

Android动画机制与使用技巧.png

Android View动画框架

Animation框架定义了几种常见动画

透明度 AlphaAnimation

旋转 RotateAnimation

缩放 ScaleAnimation

位移 TranslateAnimation

动画合集 AnimatorSet

实现原理

每次绘制视图View所在ViewGroup中drawChild函数获取该View的Animation的Transformation值

调用canvas.concat(transformToApply.getMatrix())

通过矩阵运算完成动画帧

如果动画没有完成,就继续调用invalidate()函数,启动下次绘制来驱动动画

从而完成整个动画的绘制

缺点:不具备交互性,视图动画结束,但响应事件位置不变

优点:效率高,使用方便

Android属性动画

可以响应事件

通常是AnimatorSet和ObjectAnimator配合

ObjectAnimator能够自动驱动

ObjectAnimator

创建一个ObjectAnimator只需要通过它的静态工厂类直接返回一个ObjectAnimator对象

参数包括一个对象和对戏那个的属性名,但这个属性必须有Set和Get方法,内部会通过反射机制调用Set方法修改对象属性值

// 简单的位移动画

ObjectAnimator animator = ObjectAnimator.ofFloat(

view,

"translationX",

300

);

animator.setDuration(300);

animator.start();

属性

作用

translationX、translationY

作为增量控制View对象从它布局容器的左上角坐标偏移的位置

rotation、rotationX、rotationY

控制View对象围绕支点进行2D和3D旋转

scaleX、scaleY

控制View对象围绕支点进行2D缩放

pivotX、pivotY

控制View对象的支点位置,围绕这个支点进行旋转和缩放变换处理,默认情况下,该支点的位置就是View对象的中心点

x、y

描述View对象在他容器的最终位置,是最初左上角坐标和translationX、translationY值得累计和

alpha

View对象的透明度,默认为1,0为完全透明

属性动画的机制是通过反射调用Set和Get方法,如果一个属性没有Get和Set方法应该怎么办?google在应用层提供了两种解决方法

通过自定义一个属性类或者包装类来间接的给这个属性增加get、set方法

通过ValueAnimator来实现

private static class WrapperView {

private View mTraget;

public WrapperView(View target) {

mTarget = target;

}

public int getWidth() {

return mTarget.getLayoutParams().width;

}

public void setWidth(int width) {

mTarget.getLayoutParams().width = width;

mTarget.requestLayout();

}

}

通过上面的方法给属性动画包装一层,并提供了Get、Set方法

ViewWrapper wrapper = new ViewWrapper(mButton);

ObjectAnimator.ofInt(wrapper,"width",500).setDuration(5000).start();

PropertyValuesHolder

针对同一个对象的多个属性,可以使用PropertyValuesHolder

PropertyValuesHolder pv1 = PropertyValuesHolder.ofFloat("translationX", 300);

PropertyValuesHolder pv2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);

PropertyValuesHolder pv3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);

ObjectAnimator.ofPropertyValuesHolder(view, pv1,pv2,pv3).setDuration(2000).start();

ValueAnimator

ObjectAnimator继承自ValueAnimator

可以看作一个数值发生器,用来产生有规律的数字

AnimatorUpdateListener监听数值变换

ValueAnimator animator = ValueAnimator.ofFloat(0,100);

animator.setTarget(view);

animator.setDuration(1000);

animator.start();

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

Float value = (Float) animation.getAnimatedValue();

//do the animation!

}

});

动画事件监听

一个完整的动画具有Start、Repeat、End、Cancel四个过程

当然一般用到最多的是End监听

ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0.5f);

animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationCancel(Animator animation) {

super.onAnimationCancel(animation);

}

@Override

public void onAnimationEnd(Animator animation) {

super.onAnimationEnd(animation);

}

@Override

public void onAnimationRepeat(Animator animation) {

super.onAnimationRepeat(animation);

}

@Override

public void onAnimationStart(Animator animation) {

super.onAnimationStart(animation);

}

});

AnimatorSet

同样是对一个控件添加多个动画,AnimatorSet比PropertyValuesHolder多了精确控制动画顺序的功能

还是上面的例子

ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300f);

ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0f, 1f);

ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0f, 1f);

AnimatorSet set = new AnimatorSet();

set.setDuration(2000);

set.playTogether(animator1,animator2,animator3);

set.start();

API

作用

playTogether()

一起播放

playSequentially()

顺序播放

animSet.play(anim1).with(anim2)

anim1和anim2一起播放

animSet.play(anim1).before(anim2)

anim1在anim2之前播放

animSet.play(anim1).after(anim2)

anim1在anim2之后播放

XML中使用属性动画

android:duration="1000"

android:propertyName="scaleX"

android:valueFrom="1.0"

android:valueTo="2.0"

android:valueType="floatType"/>

使用

Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);

anim.setTarget(view);

anim.start();

View的animate方法

Android3.0之后,View自带animate方法直接驱动属性动画(相当于简写方法)

view.animate()

.alpha(0)

.y(300)

.setDuration(3000)

.withStartAction(new Runnable() {

@Override

public void run() {

}

})

.withEndAction(new Runnable() {

@Override

public void run() {

}

}).start();

Android布局动画

作用在ViewGroup上,给ViewGroup增加View时添加一个动画过渡效果

最简单的例子

android:animateLayoutChanges="true"

或者使用LayoutAnimationController类自定义一个View过渡效果

LayoutAnimationController.ORDER_NORMAL-- 顺序

LayoutAnimationController.ORDER_RANDOM-- 随机

LayoutAnimationController.ORDER_REVERSE-- 逆序

LinearLayout ll = (LinearLayout)findViewById(R.id.ll);

// 设置过渡动画

ScaleAnimation sa = new ScaleAnimation(0,1,0,1);

sa.setDuration(2000);

// 设置布局动画的显示属性

LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5F);

lac.setOrder(LayoutAnimationController.ORDER_NORMAL);

// 为ViewGroup设置布局动画

ll.setLayoutAnimation(lac);

自定义动画

实现applyTransformation即可

根据情况覆盖父类initialize方法实现一些初始化工作

/**

* 电视机关闭效果

*/

public class CustomTV extends Animation {

// 中心点坐标

private int mCenterWidth;

private int mCenterHeight;

/**

* 实现初始化操作

*/

@Override

public void initialize(int width, int height, int parentWidth, int parentHeight) {

super.initialize(width, height, parentWidth, parentHeight);

setDuration(1000);

// 动画结束后保留状态

setFillAfter(true);

// 设置默认插值器

setInterpolator(new AccelerateInterpolator());

mCenterWidth = width / 2;

mCenterHeight = height / 2;

}

/**

* 参数1:interpolatedTime:插值器的时间因子,由动画当前完成的百分比和当前时间所对应的插值计算得来,取值范围0到1.0

* 参数2:Transformation:矩阵的封装类,一般使用这个类获得当前的矩阵对象

*/

@Override

protected void applyTransformation(float interpolatedTime, Transformation t) {

// 获得当前矩阵对象

final Matrix matrix = t.getMatrix();

// 通过改变matrix对象,实现动画效果

matrix.preScale(1, 1 - interpolatedTime, mCenterWidth, mCenterHeight);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值