前言
案例效果的实现比较简单,利用android自带的颜色插值器argbevaluator()进行计算即可,而本文的重点就是讲讲插值器。
效果图:
typeevaluator是一个接口,在开发中可以自定义该接口实例,利用valueanimator的setevaluator(typeevaluator)方法来控制动画的更新计算表达式。在日常开发中,不可能只是需要操纵单一数值的变化,如果需要同时操纵对象的多个属性,如定义动画的x,y移动的坐标等,那就需要对typeevaluator有所了解了。
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();
@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); }
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); }
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); } }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。