nineoldandroid使用_高级UI - Android动画初步

本文详细介绍了Android中的2D动画,包括补间动画和平移、缩放、旋转、透明度等基本操作。接着深入讨论了属性动画的原理,如ObjectAnimator、ValueAnimator、PropertyValuesHolder、TypeEvaluator和Interpolator,并通过多个实例展示了如何使用这些工具实现平移、缩放、旋转等效果。此外,还探讨了如何通过监听器同步操作其他属性、使用估值器实现抛物线动画以及插值器的应用。
摘要由CSDN通过智能技术生成

一、传统的2D动画—补间动画+帧动画

实现的本质是什么?canvas绘制的---矩阵变换Matrix

补间动画是一种设定动画开始状态、结束状态,其中间的变化由系统计算补充。这也是他叫做补间动画的原因。

补间动画由Animation类来实现具体效果,包括平移(TranslateAnimation)、缩放(ScaleAnimation)、旋转(RotateAnimation)、透明度(AlphaAnimation)四个子类,四种变化。

二、属性动画

属性动画基础

API 3.0以后。

1.属性动画的系统使用;

2.案例

3.源码解析

4.结合前面一些特效+属性动画—综合案例

1.什么是属性动画?属性动画有什么特点?

比如

button.setTranslationX(200);

和传统补间动画的区别:—会改变view的实际属性。比如:改变button的位置,平移后的状态还是可以被点击的

2.属性动画

3.0_API以下的兼容方案:NineOldAndroid.jar

主要几个类

1.ObjectAnimator

2.ValueAnimator

3.PropertyValueHolder

4. TypeEvaluator 估值器---改变算法--改变值

5. Interpolator 插值器---控制计算的速度

Facebook Rebound 弹性动画库

属性动画效率高 还是补间动画效率高– 补间动画

动画基本使用

动画1. 直接操作属性

对应代码

private void startAnimation1() { //补间动画 //Animation loadAnimation = AnimationUtils.loadAnimation(this,R.anim) //属性动画 的属性 ivTest.setTranslationX(120);//平移 ivTest.setScaleX(1.3f);//缩放 ivTest.setAlpha(0.5f);//透明度 ivTest.setRotation(20);//旋转 // ivTest.setBackgroundColor(color);//颜色渐变 }

动画2. OjbectAnimator基本使用

使用ObjectAnimator 平移

对应代码

//属性动画基本使用

private void startAnimation2() {

//参数 1 那个控件 参数2 属性的那种动画 (通过反射的方式) 参数3 数值 不断赋值 从0 到200

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivTest, "translationX", 0f, 200f);//平移

// ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivTest,"backgroundColor", red,green);//颜色

objectAnimator.setDuration(500);

objectAnimator.start();

}

多个动画同时执行

动画3 方法1: 设置动画监听 同步操作其他属性

//多个动画同时执行

private void startAnimation3() {

//方法1;----------------------- 设置动画监听 同步操作其他属性-------------

//参数 1 那个控件 参数2 属性的那种动画 (通过反射的方式) 参数3 数值 不断赋值 从0 到200

// @SuppressLint("ObjectAnimatorBinding") ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivTest, "test", 0f, 200f);//平移

@SuppressLint("ObjectAnimatorBinding") ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivTest, "setTranslationX", 0f, 100f);//平移

//实际这个操作 是 ivTest 身上的属性 叫做test; 如果参数 1 是this 则是当前java类的方法

//TODO 第二个参数是正在动画化的属性的名称 如果随便写 也可以 需要在AnimatorUpdateListener 中完成相应的动画

objectAnimator.setDuration(500);//持续时间

//添加监听 同步操作其他属性

objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

//监听动画回调

// animation.getAnimatedFraction(); //得到动画执行的百分比 0 - 1;

// animation.getAnimatedValue();//得到0f-100f当中的这个时间点对应的值

float value = (float) animation.getAnimatedValue();//得到0f-100f当中的这个时间点对应的值

Log.d(TAG, "onAnimationUpdate: value = " + value);

// ivTest.setScaleX(value/100);

// ivTest.setScaleY(value/100);

ivTest.setScaleX(0.5f + value / 200);

ivTest.setScaleY(0.5f + value / 200);

// ivTest.setTranslationX(value);

}

});

objectAnimator.start();

objectAnimator.setRepeatCount(2);//设置重复次数

// objectAnimator.setRepeatCount(ValueAnimator.INFINITE);//无限

// objectAnimator.setRepeatMode(ValueAnimator.RESTART);//重新开始

// objectAnimator.setRepeatMode(ValueAnimator.REVERSE);//翻转

// 设置其他监听

objectAnimator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

}

动画4 ,方法2 使用valueAnimator 只需要监听值的变化

同样的动画

public void startAnimator4() {

//添加监听 适配器模式

// objectAnimator.addListener(new AnimatorListenerAdapter() {

// });

//方法2;----------------------- 使用 ValueAnimator -----只需要监听值的变化-------

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

animator.setDuration(200);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float value = (float) animation.getAnimatedValue();//得到0f-100f当中的这个时间点对应的值

Log.d(TAG, "onAnimationUpdate: value = " + value);

// ivTest.setScaleX(value/100);

// ivTest.setScaleY(value/100);

ivTest.setScaleX(0.5f + value / 200);

ivTest.setScaleY(0.5f + value / 200);

}

});

animator.start();

}

动画5 方法3 PropertyValuesHolder

对应代码

public void startAnimator5() {

//方法3 PropertyValuesHolder

PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("alpha", 1f, 0.5f);

PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0.5f);

PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0.5f);

ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(ivTest, holder1, holder2, holder3);

objectAnimator.setDuration(200);

objectAnimator.start();

}

动画6 动画集合AnimatorSet

对应代码

public void startAnimator6() {

//动画集合 AnimatorSet

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(ivTest, "translationX", 0f, 100f);//平移

ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(ivTest, "scaleX", 1f, 2f);//平移

ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(ivTest, "scaleY", 1f, 2f);//平移

AnimatorSet animatorSet = new AnimatorSet();

animatorSet.setDuration(200);

// animatorSet.playTogether(objectAnimator1);

animatorSet.playTogether(objectAnimator1, objectAnimator2, objectAnimator3);

// animatorSet.playSequentially(objectAnimator1,objectAnimator2,objectAnimator3);//按照顺序执行

animatorSet.start();

// objectAnimator1和 objectAnimator2同时开启动画, objectAnimator2 在 objectAnimator3 的后面

// animatorSet.play(objectAnimator1).with(objectAnimator2).after(objectAnimator3);

}

动画7 实现抛物线动画 估值器的使用

对应代码

/** * 实现一个抛物线的效果--购物车动画.股指数-- 重力加速度 */

public void startAnimator7() {

//思路

/** * X:匀速 * y: 加速度 y = vt = 1/2*g*t*t * 使用估值器 setEvaluator * */

ValueAnimator valueAnimator = new ValueAnimator();

// valueAnimator.setInterpolator(); //设置

// valueAnimator.setEvaluator();

valueAnimator.setDuration(1000);

//这里约束 animator 的约束 是pointf

valueAnimator.setObjectValues(new PointF(0, 0));

//这是从 00 到100,100 按照3000 的时间自己进行估值计算

// valueAnimator.setObjectValues(new PointF(0,0),new PointF(100,100));

//对这个点进行操作

final PointF pointF = new PointF();

// valueAnimator.setEvaluator(new ArgbEvaluator());//颜色估值器

valueAnimator.setEvaluator(new TypeEvaluator() {

/** * *@param fraction 执行的百分比 *@param startValue *@param endValue *@return */

@Override

public PointF evaluate(float fraction, PointF startValue, PointF endValue) {

//evaluate 估值计算方法--可以在执行的过程当中干预改变属性的值---做效果:用自己的算法来控制

//不断的计算修改坐标

//X 坐标匀速运动 x = vt; 为了看起来效果好让t变成fraction*5

pointF.x = 100f * (fraction * 5);

//y 坐标是根据重力加速度公式来计算 加速度 y = vt = 1/2*g*t*t;

// pointF.y = 0.5f * 9.8f * (fraction * 5) * (fraction * 5);

pointF.y = 10f * 0.5f * 9.8f * (fraction * 5) * (fraction * 5);//Y 做大一点

return pointF;

}

});

//设置监听

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

//为什么可以从 animation 里面 取到pointf 因为 setObjectValues 约束 和在估值器中 也设置了约束

PointF f = (PointF) animation.getAnimatedValue();

ivTest.setX(f.x);

ivTest.setY(f.y);

}

});

valueAnimator.start();

}

动画8 插值器的使用

对应代码

/** * 插值器 加速器 使用 setInterpolator */

public void startAnimator8() {

ObjectAnimator animator = ObjectAnimator.ofFloat(ivTest, "translationY", 0f, 1000f);

animator.setDuration(500);

// Interpolator interpolator = new Interpolator()

// animator.setInterpolator(new AccelerateInterpolator(1));//加速度

// animator.setInterpolator(new AccelerateDecelerateInterpolator());//先快后慢

animator.setInterpolator(new BounceInterpolator());//一个内插器,它的变化在末端反弹。

// animator.setInterpolator(new AnticipateInterpolator());//一个内插器,在那里,变化开始向后,然后向前移动。

// animator.setInterpolator(new CycleInterpolator(5));//往返运动

animator.start();

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值