android动画颜色渐变,android – 如何动画渐变?

本文介绍了如何在Android中实现颜色渐变动画,通过预计算的LinearGradient避免频繁调用onDraw()方法。关键在于创建一个颜色数大于View宽度的渐变,并在每次绘制时使用canvas.translate()和shapePath.offset()更新渐变位置,从而实现平滑的颜色过渡。此外,还提到了使用TimeAnimator控制更新频率和渐变偏移量,以达到动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在谷歌搜索时,我找到了两种方法来为android:

use ShaderFactory或扩展View,使用新的Shader(新的LinearGradient()).两个答案都是一样的 – 每次调用View.onDraw(Canvas canvas)方法调用新的Shader().如果这样的动画渐变数量超过~3,它真的很贵.

所以我采取了另一种方式.我使用单个预先计算的LinearGradient避免使用onDraw()调用new.这就是它的样子(gif,所以动画衰败):

诀窍是创建LinearGradient,它的colorsCount大于View.getWidth().之后,您可以使用canvas.translate(),同时绘制渐变,以更改其颜色,因此onDraw()中根本没有新的调用.

要创建渐变,您需要当前的宽度和高度.我是在onSizeChanged()中完成的.我也在这里设置了Shader.

@Override

protected void onSizeChanged(int w,int h,int oldw,int oldh) {

super.onSizeChanged(w,h,oldw,oldh);

width = getWidth();

height = getHeight();

LinearGradient gradient = new LinearGradient(

0,height / 2,width * colors.length - 1,colors,null,Shader.TileMode.REPEAT);

fillPaint.setShader(gradient);

shapePath = getParallelogrammPath(width,height,sidesGap);

shapeBorderPath = getParallelogrammPath(width,sidesGap);

}

我使用路径因为平行四边形视图,你可以使用你想要的任何东西.在实现绘图时,您应该注意两件事:您需要在当前偏移量上翻译()整个画布,并在填充形状上使用offset():

@Override

protected void onDraw(Canvas canvas) {

canvas.save();

canvas.translate(-gradientOffset,0);

shapePath.offset(gradientOffset,0f,tempPath);

canvas.drawPath(tempPath,fillPaint);

canvas.restore();

canvas.drawPath(shapeBorderPath,borderPaint);

super.onDraw(canvas); // my View is FrameLayout,so need to call it after

}

你也应该使用canvas.save()& canvas.restore().它会将canvas的内部矩阵保存到堆栈中并相应地恢复它.

所以你需要做的最后一件事是为gradientOffset设置动画.你可以使用你想要的一切,如ObjectAnimator (Property Animation).我使用TimeAnimator,因为我需要控制updateTick并直接开始偏移.这是我的认识(有点困难和苛刻):

static public final int LIFETIME_DEAFULT = 2300;

private long lifetime = LIFETIME_DEAFULT,updateTickMs = 25,timeElapsed = 0;

private long accumulatorMs = 0;

private float gradientOffset = 0f;

public void startGradientAnimation() {

stopGradientAnimation();

resolveTimeElapsed();

final float gradientOffsetCoef = (float) (updateTickMs) / lifetime;

final int colorsCount = this.colors.length - 1;

gradientAnimation.setTimeListener(new TimeAnimator.TimeListener() {

@Override

public void onTimeUpdate(TimeAnimator animation,long totalTime,long deltaTime) {

final long gradientWidth = width * colorsCount;

if (totalTime > (lifetime - timeElapsed)) {

animation.cancel();

gradientOffset = gradientWidth;

invalidate();

} else {

accumulatorMs += deltaTime;

final long gradientOffsetsCount = accumulatorMs / updateTickMs;

gradientOffset += (gradientOffsetsCount * gradientWidth) * gradientOffsetCoef;

accumulatorMs %= updateTickMs;

boolean gradientOffsetChanged = (gradientOffsetsCount > 0) ? true : false;

if (gradientOffsetChanged) {

invalidate();

}

}

}

});

gradientAnimation.start();

}

您可以找到完整的View代码here

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值