在Android上同步动画两个值



一般来说,我试图在int值数组上动画,不像典型的情况,你只是将int或float从一个数字动画到另一个。

具体来说,我正在尝试在GradientDrawable对象上动画int[]的颜色。

GradientDrawable有一个名为"setColors(int[])"的属性,其中我设置了2种颜色,起始色和结束色,它们构成了整个渐变。

我想从一种颜色组合到另一种颜色组合。如果它是纯色,我已经可以这样做了,像下面这样:

Integer colorFrom = getResources().getColor(R.color.red);
Integer colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        textView.setBackgroundColor((Integer)animator.getAnimatedValue());
    }
});
colorAnimation.start();

我需要这样写:

//Define 2 starting colors
Integer colorFrom1 = getResources().getColor(R.color.red);
Integer colorFrom2 = getResources().getColor(R.color.darkred);
int[] startColors = new int[] {colorFrom1, colorFrom2};
//Define 2 ending colors
Integer colorTo1 = getResources().getColor(R.color.blue);
Integer colorTo2 = getResources().getColor(R.color.darkblue);
int[] endColors = new int[] {colorTo1, colorTo2};
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColors, endColors);
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        gradientView.setColors((Integer)animator.getAnimatedValues()[0] , (Integer)animator.getAnimatedValues()[1]);
    }
});
colorAnimation.start();

很明显,代码将不存在,因为没有getAnimatedValues()方法返回数组,而且没有ValueAnimator。方法,该方法接受一个数组作为起始值和结束值。

任何想法?

我现在唯一的想法是并行运行两个动画器,每个动画渐变的一个维度,每个设置只有一半的数组接受gradientDrawable.setColors()....但是,这几乎是不可接受的低效率和可能的危险的不同步。

这个怎么样?

public class ArgbArrayEvaluator implements TypeEvaluator<Integer[]> {
    ArgbEvaluator evaluator = new ArgbEvaluator();
    public Integer[] evaluate(float fraction, Integer[] startValues, Integer[] endValues) {
        if(startValues.length != endValues.length) throw new ArrayIndexOutOfBoundsException();
        Integer[] values = new Integer[startValues.length];
        for(int = 0;i<startValues.length;i++) {
            values[i] = (Integer) evaluator.evaluate(fraction,startValues[i],endValues[i]);
        }
        return values;
    }
}

那么做

/* Make sure startColors and endColors are Integer[] not int[] */
final ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbArrayEvaluator(),startColors,endColors);

你的监听器代码:

public void onAnimationUpdate(ValueAnimator animator) {
    Integer[] values = (Integer[]) animator.getAnimatedValue();
    gradientView.setColors(values[0],values[1]);
}

或者,使用ObjectAnimator

final ObjectAnimator colorAnimation = ObjectAnimator.ofMultiInt(gradientView,"colors",null, new ArgbArrayEvaluator(), startColors,endColors);

同样,在start()方法的ValueAnimator文档中它说:

通过调用该方法启动的动画将在调用该方法的线程上运行。该线程上应该有一个loop(如果不是这种情况,将抛出运行时异常)。此外,如果动画将动画对象的属性在视图层次结构中,那么调用线程应该是该视图层次结构的UI线程。

所以如果你还没有在UI线程中,我会使用下面的代码。

runOnUiThread(new Runnable() {
    public void run() {
        colorAnimation.start();
    }
});

我想它会成功的!

最新更新