1.5.37 Android Animation学习(四) ApiDemos解析:多属性动画

2024-08-21 20:32

本文主要是介绍1.5.37 Android Animation学习(四) ApiDemos解析:多属性动画,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

     如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator ,

  ( Animator可以是ValueAnimatorObjectAnimatorAnimatorSet

  然后最后把它们放在一个AnimatorSet中。

  另一种思路就是,把多个属性的改变放在同一个 ValueAnimator 中 ObjectAnimator也 ValueAnimator)。

  而这就要借助PropertyValuesHolder。本文主要讲这种方法。

PropertyValuesHolder

  PropertyValuesHolder是API Level 11加进来的。根据名字就可以判断出它是某种属性的持有者。

  使用工厂方法构造PropertyValuesHolder对象,指定属性名和一系列属性值。

  代码例子:MultiPropertyAnimation中:

 

                // ============================================================// 第二个小球:加速下落并且alpha变化ball = balls.get(1);// 利用ofFloat工厂方法构造PropertyValuesHolder类型对象,控制y属性PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y",ball.getY(), getHeight() - BALL_SIZE);// 利用ofFloat工厂方法构造另一个PropertyValuesHolder类型对象,控制alpha属性PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f);// 利用ofPropertyValuesHolder方法来构造ObjectAnimator对象// 把多个属性变化结合到一个动画中去ObjectAnimator yAlphaBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY, pvhAlpha).setDuration(DURATION / 2);yAlphaBouncer.setInterpolator(new AccelerateInterpolator());yAlphaBouncer.setRepeatCount(1);yAlphaBouncer.setRepeatMode(ValueAnimator.REVERSE);

 

关键帧Keyframe

  PropertyValuesHolder的工厂方法里面,除了整形ofInt()、浮点型ofFloat()、Object类型ofObject()之    外,还有一种:ofKeyframe()。

  Keyframe类型对象由一个time/value对组成,定义了指定时间点的指定值。

  每一个keyframe还可以拥有自己的interpolator,控制了前一个关键帧到这一个关键帧之间的时间动画行为。

  Keyframe 对象的构造也用是工厂方法:ofInt()ofFloat(), or ofObject()

  Keyframe对象构造完之后就可以用 ofKeyframe()工厂方法来构造PropertyValuesHolder对象。

  代码例子:MultiPropertyAnimation中:

 

<span style="font-size:14px;color:#333333;">                // ============================================================// 第四个小球:利用关键帧实现曲线运动ball = balls.get(3);// 属性1:Y坐标运动:下落pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(),getHeight() - BALL_SIZE);float ballX = ball.getX();// 三个关键帧Keyframe kf0 = Keyframe.ofFloat(0f, ballX);Keyframe kf1 = Keyframe.ofFloat(.5f, ballX + 100f);Keyframe kf2 = Keyframe.ofFloat(1f, ballX + 50f);// 属性2:X坐标运动:曲折// 用三个关键帧构造PropertyValuesHolder对象PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("x", kf0, kf1, kf2);// 再用两个PropertyValuesHolder对象构造一个ObjectAnimator对象ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY, pvhX).setDuration(DURATION / 2);yxBouncer.setRepeatCount(1);yxBouncer.setRepeatMode(ValueAnimator.REVERSE);</span>

 

View的多属性动画:使用ViewPropertyAnimator

  ViewPropertyAnimatorAPI Level 12引进的。

  它是用来做针对View对象的多个属性动画功能。

  (前面的PropertyValuesHolder对象是针对所有对象的,范围更广)。

  如果要同时变换一个View的多个属性的话,ViewPropertyAnimator提供了一种更方便和更适合的方法。

  而且由于多个属性的invalidate方法调用统一管理,而不是之前的分别调用,所以还会有一些性能优化。

  注意 ViewPropertyAnimator 这个类的对象不是由调用者构造的,而是通过View类的animate()方法返回的。

  比如下面的代码对比:给同一个View实现同一个动画效果:

  用多个ObjectAnimator对象:

 

<span style="font-size:14px;color:#333333;"><span style="white-space: pre; ">	</span>ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
<span style="white-space: pre; ">	</span>ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
<span style="white-space: pre; ">	</span>AnimatorSet animSetXY = new AnimatorSet();
<span style="white-space: pre; ">	</span>animSetXY.playTogether(animX, animY);
<span style="white-space: pre; ">	</span>animSetXY.start();</span>

 

  用一个ObjectAnimator对象加多个PropertyValuesHolder:

 

<span style="font-size:14px;color:#333333;"><span style="white-space: pre; ">	</span>PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
<span style="white-space: pre; ">	</span>PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
<span style="white-space: pre; ">	</span>ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();</span>

 

  用ViewPropertyAnimator:

myView.animate().x(50f).y(100f);

API Demos完整代码:

<span style="font-size:14px;color:#333333;">public class MultiPropertyAnimation extends Activity {private static final int DURATION = 1500;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.animation_multi_property);LinearLayout container = (LinearLayout) findViewById(R.id.container);final MyAnimationView animView = new MyAnimationView(this);container.addView(animView);Button starter = (Button) findViewById(R.id.startButton);starter.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {animView.startAnimation();}});}public class MyAnimationView extends View implementsValueAnimator.AnimatorUpdateListener {private static final float BALL_SIZE = 100f;public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();AnimatorSet animation = null;Animator bounceAnim = null;ShapeHolder ball = null;public MyAnimationView(Context context) {super(context);addBall(50, 0);addBall(150, 0);addBall(250, 0);addBall(350, 0);}private void createAnimation() {if (bounceAnim == null) {ShapeHolder ball;// ============================================================// 第一个小球:弹跳效果ball = balls.get(0);ObjectAnimator yBouncer = ObjectAnimator.ofFloat(ball, "y",ball.getY(), getHeight() - BALL_SIZE).setDuration(DURATION);yBouncer.setInterpolator(new BounceInterpolator());yBouncer.addUpdateListener(this);// ============================================================// 第二个小球:加速下落并且alpha变化ball = balls.get(1);// 利用ofFloat工厂方法构造PropertyValuesHolder类型对象,控制y属性PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y",ball.getY(), getHeight() - BALL_SIZE);// 利用ofFloat工厂方法构造另一个PropertyValuesHolder类型对象,控制alpha属性PropertyValuesHolder pvhAlpha = PropertyValuesHolder.ofFloat("alpha", 1.0f, 0f);// 利用ofPropertyValuesHolder方法来构造ObjectAnimator对象// 把多个属性变化结合到一个动画中去ObjectAnimator yAlphaBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY, pvhAlpha).setDuration(DURATION / 2);yAlphaBouncer.setInterpolator(new AccelerateInterpolator());yAlphaBouncer.setRepeatCount(1);yAlphaBouncer.setRepeatMode(ValueAnimator.REVERSE);// ============================================================// 第三个小球:宽度,高度,x,y同时变化ball = balls.get(2);PropertyValuesHolder pvhW = PropertyValuesHolder.ofFloat("width", ball.getWidth(), ball.getWidth() * 2);PropertyValuesHolder pvhH = PropertyValuesHolder.ofFloat("height", ball.getHeight(), ball.getHeight() * 2);PropertyValuesHolder pvTX = PropertyValuesHolder.ofFloat("x",ball.getX(), ball.getX() - BALL_SIZE / 2f);PropertyValuesHolder pvTY = PropertyValuesHolder.ofFloat("y",ball.getY(), ball.getY() - BALL_SIZE / 2f);// 利用ofPropertyValuesHolder方法来构造ObjectAnimator对象// 因为是可变参数,所以PropertyValuesHolder对象的个数不限ObjectAnimator whxyBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhW, pvhH, pvTX, pvTY).setDuration(DURATION / 2);whxyBouncer.setRepeatCount(1);whxyBouncer.setRepeatMode(ValueAnimator.REVERSE);// ============================================================// 第四个小球:利用关键帧实现曲线运动ball = balls.get(3);// 属性1:Y坐标运动:下落pvhY = PropertyValuesHolder.ofFloat("y", ball.getY(),getHeight() - BALL_SIZE);float ballX = ball.getX();// 三个关键帧Keyframe kf0 = Keyframe.ofFloat(0f, ballX);Keyframe kf1 = Keyframe.ofFloat(.5f, ballX + 100f);Keyframe kf2 = Keyframe.ofFloat(1f, ballX + 50f);// 属性2:X坐标运动:曲折// 用三个关键帧构造PropertyValuesHolder对象PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("x", kf0, kf1, kf2);// 再用两个PropertyValuesHolder对象构造一个ObjectAnimator对象ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(ball, pvhY, pvhX).setDuration(DURATION / 2);yxBouncer.setRepeatCount(1);yxBouncer.setRepeatMode(ValueAnimator.REVERSE);// ===========================================================// 所有小球动画的集合bounceAnim = new AnimatorSet();((AnimatorSet) bounceAnim).playTogether(yBouncer,yAlphaBouncer, whxyBouncer, yxBouncer);}}public void startAnimation() {createAnimation();bounceAnim.start();}private ShapeHolder addBall(float x, float y) {OvalShape circle = new OvalShape();circle.resize(BALL_SIZE, BALL_SIZE);ShapeDrawable drawable = new ShapeDrawable(circle);ShapeHolder shapeHolder = new ShapeHolder(drawable);shapeHolder.setX(x);shapeHolder.setY(y);int red = (int) (100 + Math.random() * 155);int green = (int) (100 + Math.random() * 155);int blue = (int) (100 + Math.random() * 155);int color = 0xff000000 | red << 16 | green << 8 | blue;Paint paint = drawable.getPaint();int darkColor = 0xff000000 | red / 4 << 16 | green / 4 << 8 | blue/ 4;RadialGradient gradient = new RadialGradient(37.5f, 12.5f, 50f,color, darkColor, Shader.TileMode.CLAMP);paint.setShader(gradient);shapeHolder.setPaint(paint);balls.add(shapeHolder);return shapeHolder;}@Overrideprotected void onDraw(Canvas canvas) {for (ShapeHolder ball : balls) {canvas.translate(ball.getX(), ball.getY());ball.getShape().draw(canvas);canvas.translate(-ball.getX(), -ball.getY());}}public void onAnimationUpdate(ValueAnimator animation) {invalidate();}}
}</span>

 

 

以上转载:http://www.cnblogs.com/mengdd/archive/2013/09/06/3305698.html

这篇关于1.5.37 Android Animation学习(四) ApiDemos解析:多属性动画的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1094208

相关文章

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程