目录
  • 前言
  • 一、Android中插值器TypeEvaluator
  • 二、案例效果实现
    • 1.利用Android自带的颜色插值器ArgbEvaluator
    • 2.看看Android自带颜色插值器ArgbEvaluator核心代码
    • 3.根据ArgbEvaluator的实现来自定义一个颜色插值器
    • 4.使用自己定义的颜色插值器MyColorEvaluator
  • 三、源码

    本文实例为大家分享了Android颜色渐变动画效果的实现代码,供大家参考,具体内容如下

    前言

    案例效果的实现比较简单,利用Android自带的颜色插值器ArgbEvaluator()进行计算即可,而本文的重点就是讲讲插值器。

    效果图:

    Android实现颜色渐变动画效果

    一、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);
    
        }
    }

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。