Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹
属性动画主要的几个类介绍:
1.ValueAnimator:这个类提供了一个简单的计时引擎运行动画动画计算值和设置目标对象。注意:使用该类时一般都是用:ObjectAnimator,而基于ObjectAnimator执行的属性动画,都是根据java的反射机制来设置的,因此设置动画的目标对象的属性必须有getter 和setter方法。
setDuration:设置动画的时间
setInterpolator:设置一个插入器,例如:减速器(DecelerateInterpolator),加速器(AccelerateInterpolator),当然也可以自定义,自定义时只需要继承这两个类就行了,这里就不做讨论了。
setEvaluator:设置评估者
1.ArgbEvaluator:这种评估者可以用来执行类型之间的插值整数值代表ARGB颜色。
2.FloatEvaluator:这种评估者可以用来执行浮点值之间的插值。
3.IntEvaluator:这种评估者可以用来执行类型int值之间的插值。
4.RectEvaluator:这种评估者可以用来执行类型之间的插值矩形值。
setRepeatCount:设置动画的重复次数(是一个int类型的值)
setRepeatMode:设置动画模式
start:启动动画
2.AnimatorSet:这个类为一组特定的动画指定顺序。
总要方法如下:
play:该方法创建一个构造器对象用于创建约束。
playTogether:设置同时运行一组动画
pase:暂停一个正在运行的动画
resume:重新运行暂停后的动画
isRunning:判断动画是否正在运行
isStarted:判断动画是否已经运行了
start:开始动画
3.AnimatorSet.Builder创建一个用于约束动画的建造器
after(Animator):执行前面的动画后执行该动画
after(long delay):延迟n毫秒之后执行动画
before(Animator):执行前面动画前执行动画
with(Animator):和前面动画一块执行
4.ShapeDrawable:模型drawable,创建时需要传入一个图形模型
以下是一个简单的Demo例子用于测试以上情况(小球加速下落挤压后减速上弹)
一、BackgroundView.java
- package cn.yw.lib.animation;
- import android.animation.AnimatorSet;
- import android.animation.ArgbEvaluator;
- import android.animation.ObjectAnimator;
- import android.animation.ValueAnimator;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.RadialGradient;
- import android.graphics.Shader;
- import android.graphics.drawable.ShapeDrawable;
- import android.graphics.drawable.shapes.OvalShape;
- import android.view.MotionEvent;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.animation.AccelerateInterpolator;
- import android.view.animation.DecelerateInterpolator;
- /**
- * 属性动画,背景轮询切换
- * 为什么要使用SurfaceView而不是用View:
- * 1.这里稍作解释,由于SurfaceView继承了View,绘制起来和SurfaceView没有太大的区别,
- * 2.SurfaceView本身自带双缓冲技术,能够更好的支持动画操作
- *
- *
- * @author yw-tony
- *
- */
- @SuppressLint("NewApi")
- public class BackgroundView extends SurfaceView implements
- SurfaceHolder.Callback, Runnable {
- private SurfaceHolder holder;
- private ShapeHolder shapHolder;
- public BackgroundView(Context context) {
- super(context);
- this.holder = this.getHolder();
- this.holder.addCallback(this);
- }
- /**
- * 创建一个小球
- */
- private void createABall(float x, float y) {
- OvalShape oval = new OvalShape();
- //设置拓原模型的宽高都为50f,即模型为原型
- oval.resize(50f, 50f);
- //创建一个模型drawable
- ShapeDrawable drawable = new ShapeDrawable(oval);
- shapHolder = new ShapeHolder(drawable);
- int red = (int) (Math.random() * 255);
- int green = (int) (Math.random() * 255);
- int blue = (int) (Math.random() * 255);
- int color = 0xff000000 | red << 16 | green << 8 | blue;
- Paint paint = drawable.getPaint(); // new Paint(Paint.ANTI_ALIAS_FLAG);
- 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);
- shapHolder.setPaint(paint);
- //设置小球的初始位置
- shapHolder.setX(x);
- shapHolder.setY(y);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() != MotionEvent.ACTION_DOWN
- && event.getAction() != MotionEvent.ACTION_MOVE) {
- return false;
- }
- //创建一个小球
- createABall(event.getX(), event.getY());
- //设置动画的Y轴活动范围
- float startY = shapHolder.getY();
- float endY = getHeight() - 50f;
- // int duration = (int)(500 * ((h - eventY)/h));
- // 小球弹跳动画的时间为500毫秒
- int duration = 500;
- ValueAnimator bounceAnim = ObjectAnimator.ofFloat(shapHolder, "y",
- startY, endY);
- bounceAnim.setDuration(duration);
- // 加速器,小球会加速下落
- bounceAnim.setInterpolator(new AccelerateInterpolator());
- // 以下几个是挤压动画
- ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(shapHolder, "x",
- ////设置x周的动画范围
- shapHolder.getX(), shapHolder.getX() - 25f);
- //设置压缩动画时间为下落动画时间的四分之一
- squashAnim1.setDuration(duration / 4);
- squashAnim1.setRepeatCount(1);
- squashAnim1.setRepeatMode(ValueAnimator.REVERSE);
- //挤压是做减速运动
- squashAnim1.setInterpolator(new DecelerateInterpolator());
- ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(shapHolder, "width",
- //设置小球宽度动画
- shapHolder.getWidth(), shapHolder.getWidth() + 50);
- squashAnim2.setDuration(duration / 4);
- squashAnim2.setRepeatCount(1);
- squashAnim2.setRepeatMode(ValueAnimator.REVERSE);
- //小球做减速运动
- squashAnim2.setInterpolator(new DecelerateInterpolator());
- //设置伸展动画
- ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(shapHolder, "y",
- endY, endY + 25f);
- stretchAnim1.setDuration(duration / 4);
- stretchAnim1.setRepeatCount(1);
- stretchAnim1.setInterpolator(new DecelerateInterpolator());
- stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);
- ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(shapHolder,
- "height", shapHolder.getHeight(), shapHolder.getHeight() - 25);
- stretchAnim2.setDuration(duration / 4);
- stretchAnim2.setRepeatCount(1);
- stretchAnim2.setInterpolator(new DecelerateInterpolator());
- stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);
- ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(shapHolder, "y",
- endY, startY);
- bounceBackAnim.setDuration(duration);
- // 减速器
- bounceBackAnim.setInterpolator(new DecelerateInterpolator());
- //设置动画对象的顺序
- AnimatorSet bouncer = new AnimatorSet();
- //先加速下落然后再执行挤压动画1
- bouncer.play(bounceAnim).before(squashAnim1);
- //播放挤压动画1的同事播放挤压动画2
- bouncer.play(squashAnim1).with(squashAnim2);
- bouncer.play(squashAnim1).with(stretchAnim1);
- bouncer.play(squashAnim1).with(stretchAnim2);
- //执行完挤压动画后执行小球弹起动画
- bouncer.play(bounceBackAnim).after(stretchAnim2);
- //开始执行动画
- bouncer.start();
- return true;
- }
- private void drawBall() {
- Canvas canvas = null;
- try {
- canvas = holder.lockCanvas();
- if (canvas != null) {
- canvas.drawColor(Color.GRAY);
- canvas.save();
- //如果小球为空则不执行绘制动作
- if (shapHolder != null) {
- canvas.translate(shapHolder.getX(), shapHolder.getY());
- shapHolder.getShape().draw(canvas);
- }
- canvas.restore();
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- //解锁画布
- if (holder != null) {
- holder.unlockCanvasAndPost(canvas);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- //开启绘制线程
- new Thread(this).start();
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
- @Override
- public void run() {
- try {
- //此处为死循环,大家在写的时候可以加上一个boolean变量值,当用户点击回退键(back)时,结束线程
- while (true) {
- drawBall();
- Thread.sleep(200);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
二、BackgroundViewActivity.java
- package cn.yw.lib.animation;
- import android.app.Activity;
- import android.os.Bundle;
- public class BackgroundViewActivity extends Activity{
- private BackgroundView view;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- view = new BackgroundView(this);
- setContentView(view);
- }
- }
Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹的更多相关文章
- UI特效--Android利用ViewFlipper实现屏幕切换动画效果
.屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置页面.2.介绍ViewFilpper类ViewFl ...
- Android利用ViewFlipper实现屏幕切换动画效果
1.屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置页面. 2.介绍ViewFilpper类 Vie ...
- Android 利用二次贝塞尔曲线模仿购物车加入物品抛物线动画
Android 利用二次贝塞尔曲线模仿购物车加入物品抛物线动画 0.首先.先给出一张效果gif图. 1.贝塞尔曲线原理及相关公式參考:http://www.jianshu.com/p/c0d7ad79 ...
- Android利用温度传感器实现带动画效果的电子温度计
概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 代码下载:http://www.demodashi.com/demo/10631.html 一.准备工作 需要准备一部带有温度传感 ...
- 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计
要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...
- [转]Android自定义控件三部曲系列完全解析(动画, 绘图, 自定义View)
来源:http://blog.csdn.net/harvic880925/article/details/50995268 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)—— ...
- 【Android - 基础】之Animator属性动画
1 概述 在3.0系统之前,Android给我们提供了逐帧动画Frame Animation和补间动画Tween Animation两种动画: 1) 逐帧动画的原理很简单,就是 ...
- android.animation(4) - ObjectAnimator的ofInt(), ofFloat()(转)
一.概述 1.引入 上几篇给大家讲了ValueAnimator,但ValueAnimator有个缺点,就是只能对数值对动画计算.我们要想对哪个控件操作,需要监听动画过程,在监听中对控件操作.这样使用起 ...
- 【Android - 进阶】之Animator属性动画
1.概述 在3.0系统之前,Android给我们提供了逐帧动画Frame Animation和补间动画Tween Animation两种动画: 逐帧动画的原理很简单,就是将一个完整的动画拆分成一张张单 ...
随机推荐
- css居中的方法
- 洛谷P4719 【模板】动态dp(ddp LCT)
题意 题目链接 Sol 动态dp板子题.有些细节还没搞懂,待我研究明白后再补题解... #include<bits/stdc++.h> #define LL long long using ...
- 一次关于()=>({})的使用
今天遇到了一个问题,值得一记 首先在我看项目代码时发现了一个问题 有一个JS的export如下 大家可以注意一下config 这里为什么要如此写法呢? 首先这里用的时ES6的箭头函数 ()=>{ ...
- Java设计模式之十一 ---- 策略模式和模板方法模式
前言 在上一篇中我们学习了行为型模式的访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern).本篇则来学习下行为型模式的两个模式,策略模式(Strategy Pa ...
- JS思维导图(转)
思维导图不得不说是学习及温习的极佳方法,这里转载一波网上他人的精品JS思维导图十张,共同学习,如有冒犯原著可联系本人及时处理.
- Base64编码/解码
/// <summary> /// Base64编码 /// </summary> /// <param name="str">字符串</ ...
- 启用crontab
1.登录到root用户. 2.在root下输入:crontab -e 3.可能会提示你: no crontab for root - using an empty one 然后会叫你“Select a ...
- web自动化--如何在不同页面间游刃有余
大家都知道,selenium中对页面元素的操作都是基于当前页面进行操作的,有时会有这种情况,在这个页面操作完一个步骤后,要去另一个页面查看,这就涉及到页面间的操作 # -*- coding:utf-8 ...
- .whl文件打开方式 Python
wheel文件本质上就是zip或者rar,只不过他更加方便python的安装以及使用.在之前的图片中我们只要使用pip install wheel 就可以安装wheel. 在安装了wheel之后我们可 ...
- centos7下安装docker(3.1创建镜像commit)
docker commit创建镜像 步骤:1.运行容器 2.修改容器 3.将容器保存为镜像 1. 注:-it是以交互模式进入容器,并打开终端 2.安装一个vim进行修改镜像 yum install - ...