Android 属性动画使用(二)
首先扯点别的:晚上稍微跑了一会步,然后逛了超市,晚饭喝的南瓜粥,吃了一碗面条,今天不是太饿,现在正一边吃着葡萄一边学习,也是没谁了。
比如说,我们想要实现从0过渡到100,使用ValueAnimator 就可以这样写:
ValueAnimator va = ValueAnimator.ofInt(1, 00);
va.setDuration(3000);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {Log.e("tag", "value : " + animation.getAnimatedValue());}
});
va.start();
打印出来的结果就是从1到100;但是这是怎么实现的呢,这是因为系统内置了一个IntEvaluator(相当于一个计算器)来实现计算如何从动画的初始值过渡到结束值。
//IntEvaluator 的evaluate方法
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {int startInt = startValue;//就返回初始值加上fraction乘上结束值减去初始值fraction变化范围0到1return (int)(startInt + fraction * (endValue - startInt));
}
ValueAnimator有一个ofObject方法,用来操作对象的动画。但是和ofInt或者ofFloat方法相比,ofObject没法内置一个Evaluator,因为对象不同,计算的方式也不一样,所以要自己实现一个继承自TypeEvaluator的Evaluator。
使用场景:自定义一个View,View中有一个Point()对象用来管理坐标,View在onDraw方法中根据Point()对象的坐标进行绘制,然后使用ValueAnimator来改变Poin对象的坐标值,那么自定义View就会实现动画效果。
//具有x,y两个属性和相应的get,set函数
public class MyPoint {private float x;private float y;public MyPoint(float x, float y) {this.x = x;this.y = y;}public float getX() {return x;}public float getY() {return y;}
}
自定义PointEvaluator
public class PointEvaluator implements TypeEvaluator<MyPoint> {@Overridepublic MyPoint evaluate(float fraction, MyPoint startValue, MyPoint endValue) {//改变x值float x = startValue.getX() + fraction * (endValue.getX() - startValue.getX());//改变y值float y = startValue.getY() + fraction * (endValue.getY() - startValue.getY());MyPoint point = new MyPoint(x, y);//返回一个新的Point对象,坐标已经改变了return point;}
}
新建一个PointAnimView 继承自View
public class PointAnimView extends View {public static final float RADIUS = 50f; //point点的半径private MyPoint currentPoint;private Paint mPaint;public PointAnimView(Context context, AttributeSet attrs) {super(context, attrs);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.BLUE);}@Overrideprotected void onDraw(Canvas canvas) {//第一次绘制初始的点之后就启动动画if (currentPoint == null) {currentPoint = new MyPoint(RADIUS, RADIUS);drawCircle(canvas);startAnimation();} else {drawCircle(canvas);}}private void drawCircle(Canvas canvas) {float x = currentPoint.getX();float y = currentPoint.getY();canvas.drawCircle(x, y, RADIUS, mPaint);}private void startAnimation() {MyPoint startPoint = new MyPoint(RADIUS, RADIUS);MyPoint endPoint = new MyPoint(getWidth() - RADIUS, getHeight() - RADIUS);ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {currentPoint = (MyPoint) animation.getAnimatedValue();invalidate(); }});anim.setDuration(5000);anim.start();}
}
将PointAnimView 引入布局文件使用。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.hm.animationdemo.widget.PointAnimViewandroid:id="@+id/point_view"android:layout_width="match_parent"android:layout_height="match_parent" />
</RelativeLayout>
效果图
ObjectAnimator的高级用法
实现动态改变PointAnimView的颜色,那就得给PointAnimView添加color属性并提供相应的getColor方法和setColor方法,在setColor方法中改变View里面画笔的颜色,然后调用invalidate方法刷新视图,在绘制的时候,View的颜色就会发生变化
private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; mPaint.setColor(Color.parseColor(color)); invalidate(); }
ObjectAnimator的ofObject方法
//可以看到第三个参数是一个TypeEvaluator ,用来计算Object的属性,在这里就是我们的color如何变化,
//所以要重写一个TypeEvaluator来计算颜色的变化
public static ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)
//这个实现细节,就愉快的略过吧。
public class ColorEvaluator implements TypeEvaluator { private int mCurrentRed = -1; private int mCurrentGreen = -1; private int mCurrentBlue = -1; @Override public Object evaluate(float fraction, Object startValue, Object endValue) { String startColor = (String) startValue; String endColor = (String) endValue; int startRed = Integer.parseInt(startColor.substring(1, 3), 16); int startGreen = Integer.parseInt(startColor.substring(3, 5), 16); int startBlue = Integer.parseInt(startColor.substring(5, 7), 16); int endRed = Integer.parseInt(endColor.substring(1, 3), 16); int endGreen = Integer.parseInt(endColor.substring(3, 5), 16); int endBlue = Integer.parseInt(endColor.substring(5, 7), 16); // 初始化颜色的值 if (mCurrentRed == -1) { mCurrentRed = startRed; } if (mCurrentGreen == -1) { mCurrentGreen = startGreen; } if (mCurrentBlue == -1) { mCurrentBlue = startBlue; } // 计算初始颜色和结束颜色之间的差值 int redDiff = Math.abs(startRed - endRed); int greenDiff = Math.abs(startGreen - endGreen); int blueDiff = Math.abs(startBlue - endBlue); int colorDiff = redDiff + greenDiff + blueDiff; if (mCurrentRed != endRed) { mCurrentRed = getCurrentColor(startRed, endRed, colorDiff, 0, fraction); } else if (mCurrentGreen != endGreen) { mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff, redDiff, fraction); } else if (mCurrentBlue != endBlue) { mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff, redDiff + greenDiff, fraction); } // 将计算出的当前颜色的值组装返回 String currentColor = "#" + getHexString(mCurrentRed) + getHexString(mCurrentGreen) + getHexString(mCurrentBlue); return currentColor; } /** * 根据fraction值来计算当前的颜色。 */ private int getCurrentColor(int startColor, int endColor, int colorDiff, int offset, float fraction) { int currentColor; if (startColor > endColor) { currentColor = (int) (startColor - (fraction * colorDiff - offset)); if (currentColor < endColor) { currentColor = endColor; } } else { currentColor = (int) (startColor + (fraction * colorDiff - offset)); if (currentColor > endColor) { currentColor = endColor; } } return currentColor; } /** * 将10进制颜色值转换成16进制。 */ private String getHexString(int value) { String hexString = Integer.toHexString(value); if (hexString.length() == 1) { hexString = "0" + hexString; } return hexString; } }
定义好了ColorEvaluator ,就可以改变颜色了,改变MyAinmView中的startAnimation方法,就可以实现在改变view的位置的同时改变view的颜色了。
private void startAnimation() {MyPoint startPoint = new MyPoint(RADIUS, RADIUS);MyPoint endPoint = new MyPoint(getWidth() - RADIUS, getHeight() - RADIUS);ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {currentPoint = (MyPoint) animation.getAnimatedValue();invalidate();}});ObjectAnimator anim2 = ObjectAnimator.ofObject(this, "color", new ColorEvaluator(),"#0000FF", "#FF0000");AnimatorSet animSet = new AnimatorSet();animSet.play(anim).with(anim2);animSet.setDuration(5000);animSet.start();
}
效果如下
结尾:文章中的代码来自部分摘自郭霖老师的博客。是时候睡觉了。
- Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
Android 属性动画使用(二)相关推荐
- Android 属性动画(二)
仔细想了一下,发现之前写的东西有很多漏了,改又不好改,只好在这里另写一篇补充了 之前讲到ObjectAnimator但是没有说xml设置方法,在这里提一下 <?xml version=" ...
- Android 属性动画(一)新手入门
一.属性动画简介 Android 中动画有很多种,属性动画就是其中的一种.所谓的属性动画,就是在指定的时间内,通过改变对象的属性达到变化效果的动画.在 Android 中,属性动画系统是一个强健的框架 ...
- Android自定义动画专题二
android自定义动画专题二 在上篇文章中给大家介绍了android自定义动画的第一种表现形式:view的绘制:不过这只是一种单纯利用自定义控件绘制的方式去实现:这篇文章会给大家演示如何通过自定义控 ...
- Android属性动画完全解析(上),初识属性动画的基本用法
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系 ...
- 【Android 属性动画】属性动画 Property Animation 简介 ( 属性动画简介 | 属性动画特性 )
文章目录 一.属性动画简介 二.属性动画特性 一.属性动画简介 属性动画简介 : 1.动画制作框架 : 属性动画系统 , 允许你 将任何可变的操作制作成动画 , 其功能很强大 ; 2.基本功能 : 使 ...
- android动画封装,Android属性动画封装,快速构建动画
Android实现动画效果的方式主要有帧动画.补间动画.属性动画.关于安桌动画的基础知识可以查看这篇文章Android属性动画完全解析 这里我要讲的是如何快速构建出一个动画效果,如下图: 如果我们用属 ...
- Android属性动画 ObjectAnimator
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/118709616 本文出自[赵彦军的博客] 文章目录 ObjectAnimator ...
- (转)Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
版权声明:本文出自郭霖的博客,转载必须注明出处. 目录(?)[-] ValueAnimator的高级用法 ObjectAnimator的高级用法 转载请注明出处:http://blog.csdn.ne ...
- android 属性动画实例,Android属性动画完全解析 中 ,ValueAnimator和ObjectAnimator的高级用法...
大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画进行了 ...
最新文章
- HTTP协议处理流程
- git命令行删除远程分支
- 不疯狂的外星人,已疯狂的资本
- 语言主程序和子程序的写法_汇编语言程序设计第三篇——汇编程序结构
- 官方公布94本预警期刊名单,其中5本高风险
- 活动回顾丨从技术创新到行业实践——泛娱乐社交产品专场
- C# socket编程第二篇
- localhost,127.0.0.1 与 本机IP的区别
- 前端学习(2630):git安装包下载
- e.printstacktrace()为什么没有输出信息_不输入内容,能不能直接输出内容?
- python 3中 的subprocess
- RHEL6.1在字符模式下安装图形界面
- OracleERP-采购管理
- sklearn 决策树例子_sklearn CART决策树分类
- erlang Error in process with exit value: {undef,[{M,F,[A],[]}]}
- 李嘉诚:孤独是他的能量
- HTTP超文本传输协议详解
- 面试计算机应用技术自我介绍,计算机应用专业面试的自我介绍
- ESP8266-D1 mini-V2 认识
- 【刷题】洛谷 P3613 睡觉困难综合征
热门文章
- 滴滴如何调度_怎么看待滴滴的调度小助手?_科技数码通
- 2020 年 1 月 14 日外延支持结束后继续接收安全更新的过程
- Dlink DIR-615L 和水星(mercury) MW300R桥接方法!
- 大数据、互联网、机器人成大热门
- 蓝桥杯模拟赛第二场(web)
- Java 将两个日期的时间段按照一定天数进行周期切割
- Linux arm 下载程序,在Linux下使用kermit和dnw给ARM板下载程序
- 奔腾的芯——英特尔公司
- 谷歌浏览器设置启动页被hao123劫持_win10系统打开chrome主页会被hao123劫持的故障原因及解决方法...
- Windows设备信息获取:(摄像头,声卡为例)Qt,WindowsAPI对比说明(2)