Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹

时间:2022-04-02 01:50:51

属性动画主要的几个类介绍:

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性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹的更多相关文章

  1. UI特效--Android利用ViewFlipper实现屏幕切换动画效果

    .屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置页面.2.介绍ViewFilpper类ViewFl ...

  2. Android利用ViewFlipper实现屏幕切换动画效果

    1.屏幕切换指的是在同一个Activity内屏幕见的切换,最长见的情况就是在一个FrameLayout内有多个页面,比如一个系统设置页面:一个个性化设置页面. 2.介绍ViewFilpper类 Vie ...

  3. Android 利用二次贝塞尔曲线模仿购物车加入物品抛物线动画

    Android 利用二次贝塞尔曲线模仿购物车加入物品抛物线动画 0.首先.先给出一张效果gif图. 1.贝塞尔曲线原理及相关公式參考:http://www.jianshu.com/p/c0d7ad79 ...

  4. Android利用温度传感器实现带动画效果的电子温度计

    概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 代码下载:http://www.demodashi.com/demo/10631.html 一.准备工作 需要准备一部带有温度传感 ...

  5. 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  6. &lbrack;转&rsqb;Android自定义控件三部曲系列完全解析&lpar;动画&comma; 绘图&comma; 自定义View&rpar;

    来源:http://blog.csdn.net/harvic880925/article/details/50995268 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)—— ...

  7. 【Android - 基础】之Animator属性动画

    1      概述 在3.0系统之前,Android给我们提供了逐帧动画Frame Animation和补间动画Tween Animation两种动画: 1)        逐帧动画的原理很简单,就是 ...

  8. android&period;animation&lpar;4&rpar; - ObjectAnimator的ofInt&lpar;&rpar;&comma; ofFloat&lpar;&rpar;&lpar;转&rpar;

    一.概述 1.引入 上几篇给大家讲了ValueAnimator,但ValueAnimator有个缺点,就是只能对数值对动画计算.我们要想对哪个控件操作,需要监听动画过程,在监听中对控件操作.这样使用起 ...

  9. 【Android - 进阶】之Animator属性动画

    1.概述 在3.0系统之前,Android给我们提供了逐帧动画Frame Animation和补间动画Tween Animation两种动画: 逐帧动画的原理很简单,就是将一个完整的动画拆分成一张张单 ...

随机推荐

  1. iOS CALayer应用详解&lpar;2&rpar;

    参考博客:http://blog.csdn.net/hello_hwc?viewmode=list 如果你对CALayer 还没有一个清晰的理解,欢迎看一下前面的博客: http://www.cnbl ...

  2. GERBER文件

    GERBER文件 GERBER文件是一种国际标准的光绘格式文件,它包含RS-274-D和RS-274-X两种格式,其中RS-274-D称为基本GERBER格式,并 要同时附带D码文件才能完整描述一张图 ...

  3. Cocos2d-x 3&period;2 学习笔记(一)环境搭建

    目前项目无事,时间比较充裕,因此来学习下cocos2dx,当然本人也是新手一个, 写此笔记做备忘和脚步. 最近3.2版本更新出來了!官方说这是自2.x分支以来修复了超过450个bug,3.2版本是目前 ...

  4. if&lowbar;nametoindex可以检查网卡名称是否有效

    NAME if_nametoindex, if_indextoname, if_nameindex, if_freenameindex - convert interface index to nam ...

  5. Github GUI 托管代码教程

    附录:克隆仓库到本地:git clone https://github.com/chzeze/WeiboHomeCrawl.git

  6. ural 2062 Ambitious Experiment

    2062. Ambitious Experiment Time limit: 3.0 secondMemory limit: 128 MB During several decades, scient ...

  7. 20145215实验四 Android开发基础

    20145215实验四 Android开发基础 实验内容 基于Android Studio开发简单的Android应用并部署测试; 了解Android组件.布局管理器的使用: 掌握Android中事件 ...

  8. C&num; WPF定时器

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来.我们都知道计算机技术发展日新月异,速度惊人的快,你我稍不留神,就会被慢慢淘汰!因此:每日不间断的学习是避免被 ...

  9. CSS规则整理

    一. 善用css缩写规则 /*注意上.右.下.左的书写顺序*/1. 关于边距(4边):1px 2px 3px 4px (上.右.下.左)1px 2px 3px (省略的左等于右)1px 2px (省略 ...

  10. Ubuntu环境下手动配置Java环境

    /×××××××××××××××××××××××××××××××××××××××××/ Author:xxx0624 HomePage:http://www.cnblogs.com/xxx0624/ ...