一般来说,我试图在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();
}
});
我想它会成功的!