Gradient color animation
What I want to achieve:
The radial gradient that starts and ends colors smoothly changes over time from one specific color to another.
What I have tried so far:
Using ObjectAnimator like this:
searchAnimator = ObjectAnimator.ofFloat(drawThread, new Property<DrawThread, Float>(Float.TYPE, "fraction") {
@Override
public Float get(DrawThread object) {
return object.fraction;
}
@Override
public void set(DrawThread object, Float value) {
object.setFraction(value);
}
}, 0, 1);
searchAnimator.setDuration(maxSearchDuration);
searchAnimator.setInterpolator(new LinearInterpolator());
This will cause DrawThread.setFraction(value);
over time. Inside the thread, I am doing the drawing Canvas
with the SurfaceView
following:
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
radius = (int) Math.sqrt(canvas.getWidth() / 2 * canvas.getWidth() / 2 + canvas.getHeight() / 2 * canvas.getHeight() / 2);
//calculating colors for current fraction using ARGBEvaluator
int start = (int) argbEvaluator.evaluate(fraction, colors[0].start, colors[1].start);
int end = (int) argbEvaluator.evaluate(fraction, colors[0].end, colors[1].end);
//end
mPaint.setShader(new RadialGradient(canvas.getWidth() / 2, canvas.getHeight() / 2,
radius, start, end, Shader.TileMode.CLAMP));
canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, radius, mPaint);
Problems:
- The gradient is not smooth. The image looks like a low color
- The performance is very low. I am getting aprox 16 FPS on a FullHD Snapdragon 801 device.
So what I want to ask is is any help to improve performance (even in a completely different way) and improve image quality.
+3
source to share
2 answers
You can animate color changes in a gradient like this:
int colorFrom = ContextCompat.getColor(this, R.color.red);
int colorTo = ContextCompat.getColor(this, R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(2000);
int color1 = ContextCompat.getColor(this, R.color.red);
int color2 = ContextCompat.getColor(this, R.color.green);
GradientDrawable gradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, new int[]{color1, color2});
gradientDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
gradientDrawable.setColors(new int[]{(int) animator.getAnimatedValue(), color2});
viewWithGradientBg.setBackground(gradientDrawable);
}
}
});
colorAnimation.start();
+1
source to share
Perhaps this piece of pseudocode helps:
private ValueAnimator colorAnimation;
colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor);
// you can add more colors here
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
yourView.setBackgroundColor((Integer) animator
.getAnimatedValue());
}
});
colorAnimation.setDuration(maxSearchDuration);
colorAnimation.start();
}
0
source to share