Android实现颜色渐变动画效果
作者:计蒙不吃鱼 发布时间:2022-05-31 09:52:53
标签:Android,颜色渐变
本文实例为大家分享了Android颜色渐变动画效果的实现代码,供大家参考,具体内容如下
前言
案例效果的实现比较简单,利用Android自带的颜色插值器ArgbEvaluator()进行计算即可,而本文的重点就是讲讲插值器。
效果图:
一、Android中插值器TypeEvaluator
TypeEvaluator是一个接口,在开发中可以自定义该接口实例,利用ValueAnimator的setEvaluator(TypeEvaluator)方法来控制动画的更新计算表达式。在日常开发中,不可能只是需要操纵单一数值的变化,如果需要同时操纵对象的多个属性,如定义动画的x,y移动的坐标等,那就需要对TypeEvaluator有所了解了。
二、案例效果实现
1.利用Android自带的颜色插值器ArgbEvaluator
ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
colorAnim.setDuration(4000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
2.看看Android自带颜色插值器ArgbEvaluator核心代码
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
float startA = ((startInt >> 24) & 0xff) / 255.0f;
float startR = ((startInt >> 16) & 0xff) / 255.0f;
float startG = ((startInt >> 8) & 0xff) / 255.0f;
float startB = ( startInt & 0xff) / 255.0f;
int endInt = (Integer) endValue;
float endA = ((endInt >> 24) & 0xff) / 255.0f;
float endR = ((endInt >> 16) & 0xff) / 255.0f;
float endG = ((endInt >> 8) & 0xff) / 255.0f;
float endB = ( endInt & 0xff) / 255.0f;
// 将sRGB转化成线性
startR = (float) Math.pow(startR, 2.2);
startG = (float) Math.pow(startG, 2.2);
startB = (float) Math.pow(startB, 2.2);
endR = (float) Math.pow(endR, 2.2);
endG = (float) Math.pow(endG, 2.2);
endB = (float) Math.pow(endB, 2.2);
//在线性空间中计算插值的颜色
float a = startA + fraction * (endA - startA);
float r = startR + fraction * (endR - startR);
float g = startG + fraction * (endG - startG);
float b = startB + fraction * (endB - startB);
//转换回sRGB在[0..255]范围
a = a * 255.0f;
r = (float) Math.pow(r, 1.0 / 2.2) * 255.0f;
g = (float) Math.pow(g, 1.0 / 2.2) * 255.0f;
b = (float) Math.pow(b, 1.0 / 2.2) * 255.0f;
return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);
}
3.根据ArgbEvaluator的实现来自定义一个颜色插值器
public class MyColorEvaluator implements TypeEvaluator
接下来换一种颜色的计算方式,在本人看相关api的过程中,发现Color中有colorToHSV和HSVToColor的方法,于是在网上找了一个HVS的计算方式。(以下代码来源于网络)。
@Override
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
Color.colorToHSV(startValue,startHsv);
Color.colorToHSV(endValue,endHsv);
int alpha = startValue >> 24 + (int) ((endValue >> 24 - startValue >> 24) * fraction);
// 计算当前动画完成度(fraction)所对应的颜色值
if (endHsv[0] - startHsv[0] > 180) {
endHsv[0] -= 360;
} else if (endHsv[0] - startHsv[0] < -180) {
endHsv[0] += 360;
}
outHsv[0] = startHsv[0] + (endHsv[0] - startHsv[0]) * fraction;
if (outHsv[0] > 360) {
outHsv[0] -= 360;
} else if (outHsv[0] < 0) {
outHsv[0] += 360;
}
outHsv[1]=startHsv[1]+(endHsv[1]-startHsv[1])*fraction;
outHsv[2]=startHsv[2]+(endHsv[2]-startHsv[2])*fraction;
return Color.HSVToColor(alpha,outHsv);
}
4.使用自己定义的颜色插值器MyColorEvaluator
ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
colorAnim.setDuration(4000);
colorAnim.setEvaluator(new MyColorEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
三、源码
ColorGradient.java:
public class ColorGradient extends View {
public ColorGradient(Context context) {
super(context);
}
public ColorGradient(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
animation();
}
public ColorGradient(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void animation(){
ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);
colorAnim.setDuration(4000);
colorAnim.setEvaluator(new MyColorEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
}
}
MyColorEvaluator.java:
public class MyColorEvaluator implements TypeEvaluator<Integer> {
float[] startHsv=new float[3];
float[] endHsv=new float[3];
float[] outHsv=new float[3];
@Override
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
Color.colorToHSV(startValue,startHsv);
Color.colorToHSV(endValue,endHsv);
int alpha = startValue >> 24 + (int) ((endValue >> 24 - startValue >> 24) * fraction);
// 计算当前动画完成度(fraction)所对应的颜色值
if (endHsv[0] - startHsv[0] > 180) {
endHsv[0] -= 360;
} else if (endHsv[0] - startHsv[0] < -180) {
endHsv[0] += 360;
}
outHsv[0] = startHsv[0] + (endHsv[0] - startHsv[0]) * fraction;
if (outHsv[0] > 360) {
outHsv[0] -= 360;
} else if (outHsv[0] < 0) {
outHsv[0] += 360;
}
outHsv[1]=startHsv[1]+(endHsv[1]-startHsv[1])*fraction;
outHsv[2]=startHsv[2]+(endHsv[2]-startHsv[2])*fraction;
return Color.HSVToColor(alpha,outHsv);
}
}
来源:https://blog.csdn.net/qq_42761395/article/details/119918232


猜你喜欢
- 1.springboot 2.0 默认连接池就是Hikari了,所以引用parents后不用专门加依赖2.贴我自己的配置(时间单位都是毫秒)
- 本文实例讲述了Android选项菜单用法。分享给大家供大家参考。具体如下:Android平台下所提供的菜单大体上可分为三类:选项菜单、上下文
- 前言:本质上来说,CoreCLR 也是 C++ 写的,所以也逃不过用 虚表 来实现多态的玩法, 不过玩法也稍微复杂了一些,希望本篇对大家有帮
- 结构型设计模式创建型设计模式主要是为了解决创建对象的问题,而结构型设计模式则是为了解决已有对象的使用问题。适配器模式适配器模式比较好理解,因
- 从C#3.0开始,可以使用lambda表达式把实现代码赋予委托。lambda表达式与委托(https://www.jb51.net/arti
- 电话号码的字母组合中等给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下
- 在使用JDBC的时候,数据库据连接是非常宝贵的资源。为了复用这些资源,可以将连接保存在一个队列中。当需要的时候可以从队列中取出未使用的连接。
- 前言convert 叫强制转换,可以是其他类型。最近在工作中遇到一个问题,需要将字符串形式的数值转换回数值,很正常的要求吧。却遇到了问题,下
- 1. 前言ResultSetMetaData 叫元数据,是数据库 列对象,以列为单位封装为对象。元数据,指的是其包含列名,列值,列类型,列长
- 本文实例为大家分享了java实现图片反色处理的具体代码,供大家参考,具体内容如下效果对比原图反色处理原图反色处理核心代码实现import j
- 本文实例为大家分享了TextView绘制背景的方法,供大家参考,具体内容如下效果:实现流程:1.初始化:对画笔进行设置mPaintIn =
- 使用AES算法可用于对数据进行加密码与解密,使用的时候需要注意两点:1)被加密的串越长,加密后的字符串越长,注意数据库字段的设计;2)Lin
- 类和类有关联,将查询的结果注入到对象和对象的关联关系中Mybatis处理的关联关系 包括一对一关联 和 一对多关联 ,例如学生关联班级是一对
- Result 类型是许多编程语言中处理错误的常用方式,包括 C# 的 dotNext 库。在本文中,我们将通过例子回顾 C# 中 using
- 本文实例讲述了在C#中实现多线程中调用winform窗体控件的方法,对于C#程序设计的学习有着很好的借鉴参考价值。具体方法如下:首先,由于W
- AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProces
- 【一】背景6.0运行时申请权限已经是一个老生常谈的内容了,最近项目TargetSDKVersion升到23以上,所以我们也需要做权限管理,我
- 先上效果图,如果大家感觉不错,请参考实现代码。 重要的是如何实现自定义的
- 准备数据data class ContactEntity( val letter: Char, &n
- AlarmManager通常用来开发手机闹钟,并且它是一个全局定时器,可在指定时间或指定周期启动其他组件(包括Activity,Servic