val start = Color.DKGRAY
val mid = Color.MAGENTA
val end = Color.BLUE
//content.background is set as a GradientDrawable in layout xml file
val gradient = content.background as GradientDrawable
val evaluator = ArgbEvaluator()
val animator = TimeAnimator.ofFloat(0.0f, 1.0f)
animator.duration = 1500
animator.repeatCount = ValueAnimator.INFINITE
animator.repeatMode = ValueAnimator.REVERSE
animator.addUpdateListener {
val fraction = it.animatedFraction
val newStart = evaluator.evaluate(fraction, start, end) as Int
val newMid = evaluator.evaluate(fraction, mid, start) as Int
val newEnd = evaluator.evaluate(fraction, end, mid) as Int
gradient.colors = intArrayOf(newStart, newMid, newEnd)
}
animator.start()
@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
}
4条答案
按热度按时间cfh9epnr1#
我想出了不同的,短得多的方法。简单使用
setColors (int[] colors)
方法GradientDrawable
并随着时间的推移将其动画化。这是一个如何做到这一点的例子:
结果是:
kse8i1jr2#
刚刚重写了@krzysztof misztal对
java
:在哪里
view
是一个简单的View
具有渐变背景:视图:
希望我的回答能有所帮助
j7dteeu83#
在谷歌上搜索时,我发现了两种android的方法:使用shaderfactory或extends view,使用
new Shader(new LinearGradient())
. 两个答案都是一样的new Shader()
每View.onDraw(Canvas canvas)
方法的调用。如果这样的动画渐变的数量超过~3,那么它就非常昂贵。所以我换了个方法。我没有打电话
new
每onDraw()
,使用单个预先计算LinearGradient
. 这就是它的样子(gif,所以动画衰减了):诀窍是创造
LinearGradient
哪个是colorsCount
倍于View.getWidth()
. 之后你可以使用canvas.translate()
,在绘制渐变时,要改变其颜色,所以没有new
来电onDraw()
完全。要创建渐变,需要当前的宽度和高度。我是在家里做的
onSizeChanged()
. 我也设置了Shader
这里也是。我使用路径,因为平行四边形视图,你可以使用任何你想要的。在实现绘图时,您应该注意两件事:您需要
translate()
整个canvas
当前偏移和offset()
您的填充形状:你也应该使用
canvas.save()
&canvas.restore()
. 它将画布的内部矩阵保存到堆栈中,并进行相应的恢复。所以最后你需要做的就是制作动画
gradientOffset
. 你可以使用任何你想要的东西,比如objectanimator(属性动画)。我用了timeanimator,因为我需要控制updateTick
直接开始偏移。以下是我的体会(有点困难和苛刻):完整的
View
代码可以在这里找到zhte4eai4#
最新的替代答案。