如何在颜色变化的画布上用Android绘制渐变色?
我需要在画布的背景上涂上一种颜色,并应用阴影/渐变,但每次onDraw调用我都想更改颜色 在每次onDraw调用中,如果不创建新对象,我很难做到这一点。有人有什么想法吗?如果我使用drawPaint()并将一个新的着色器()设置为我的paint,那么我创建了一个新的着色器对象,如果我创建了一个新的GradientDrawable(),我也创建了一个新的着色器对象。我想避免GC 我想我可以重用一个GradientDrawable()对象并调用.setColor()方法,但这只是重置与之关联的任何渐变数据,并将可绘制对象绘制为该纯色如何在颜色变化的画布上用Android绘制渐变色?,android,canvas,gradient,shader,Android,Canvas,Gradient,Shader,我需要在画布的背景上涂上一种颜色,并应用阴影/渐变,但每次onDraw调用我都想更改颜色 在每次onDraw调用中,如果不创建新对象,我很难做到这一点。有人有什么想法吗?如果我使用drawPaint()并将一个新的着色器()设置为我的paint,那么我创建了一个新的着色器对象,如果我创建了一个新的GradientDrawable(),我也创建了一个新的着色器对象。我想避免GC 我想我可以重用一个GradientDrawable()对象并调用.setColor()方法,但这只是重置与之关联的任何渐
有人吗?不幸的是,您每次都必须创建一个新的LinearGradient。请注意,您不必使用GradientDrawable,您可以使用设置着色器的颜料自己绘制形状。我想您要做的就是这样。创建一个LayerDrawable,然后在其中插入两个Drawable。插入的第一个可绘制图形应将其颜色设置为您希望背景的颜色,第二个应为设置为黑色的渐变色,并从alpha 0过渡到alpha 255
有关更多信息,请参阅: < P>此问题在2017年年中仍然有效。我想为自定义视图的颜色更改创建平滑过渡。我使用了带有LinearGradient的着色器 我的意图是使我的观点在混乱和残废之间平稳过渡 由于观点的结构和目的,我的案例更为复杂。这是一个滑块。因此,我的视图由几乎两个相同的层组成,一个层使用画布绘制在第二个层的顶部。第三个元素是指针 两个图层都使用线性渐变,指针使用单一颜色 总结所有我必须同时在5种颜色之间进行转换:
- 底层的开始和结束颜色-一个线性渐变
- 顶层的开始和结束颜色-第二个LinearGradient
- 指针颜色-正常颜色李>
在开始时,我还担心在每次动画更新时创建一个新的LinearGradient,但后来我在设备上启动了GPU评测,并使用“屏幕上的条形图”。一切正常,并在安全范围内运行。campnic-谢谢,这正是我想调用canvas.drawARGB()和alpha xFF,然后是一个带有着色器或渐变的绘画,顶部有较小的alpha。我只是担心效率。我想避免用两层绘制整个画布,并想知道是否有一个内置的构造可以一次性完成这项工作。LayerDrawable实现了这一点,还是它真的实现了逐层顺序绘制?我做了一些挖掘,我看到的结果表明,您将在整个屏幕上绘制两个完整的层。LayerDrawable.draw的代码只是按索引降序迭代子Drawable。我认为LayerDRawable的性能可能不是您想要使用的。Romain在这方面有更多的经验,所以他可能会给你一个更好的主意:)我真的很感谢你看这个-这也是我在查看文档时发现和怀疑的。如果没有内置的解决方案,我将不得不为一个漂亮的动态背景想出一些创意。谢谢Romain,你能在我对campnic的评论中分享你的专业知识吗?我想知道最有效的.draw…()方法是绘制创建此效果所需的两个图层,还是LayerDrawable正是我所需要的。@Romain Guy我一直在尝试使用SweepGradient来实现锥形渐变效果。但它似乎只适用于两种颜色。如果我使用四色数组,那么“扫描渐变”似乎并不像预期的那样工作。我尝试了各种位置值的组合,也尝试了设置为空的位置,但大多数情况下,我只得到了两种颜色或不是圆锥形的渐变。任何帮助都将不胜感激。
private ValueAnimator frontStartColorAnimator;
private ValueAnimator frontEndColorAnimator;
private ValueAnimator bottomStartColorAnimator;
private ValueAnimator bottomEndColorAnimator;
private ValueAnimator pointerColorAnimator;
private AnimatorSet colorsAnimatorSet;
...
frontStartColorAnimator = ValueAnimator.ofArgb(frontLayerStartColor, frontLayerDisabledStartColor);
frontStartColorAnimator.setDuration(animationDuration);
frontStartColorAnimator.setInterpolator(new LinearInterpolator());
frontStartColorAnimator.addUpdateListener(animation
-> shaderFrontLayerStartColor = (int) animation.getAnimatedValue());
frontEndColorAnimator = ValueAnimator.ofArgb(frontLayerEndColor, frontLayerDisabledEndColor);
frontEndColorAnimator.setDuration(animationDuration);
frontEndColorAnimator.setInterpolator(new LinearInterpolator());
frontEndColorAnimator.addUpdateListener(animation -> {
shaderFrontLayerEndColor = (int) animation.getAnimatedValue();
frontLayerPaint.setShader(new LinearGradient(0, 0, getWidth(), 0, shaderFrontLayerStartColor,
shaderFrontLayerEndColor, Shader.TileMode.CLAMP));
});
bottomStartColorAnimator = ValueAnimator.ofArgb(bottomLayerStartColor, bottomLayerDisabledStartColor);
bottomStartColorAnimator.setDuration(animationDuration);
bottomStartColorAnimator.setInterpolator(new LinearInterpolator());
bottomStartColorAnimator.addUpdateListener(animation ->
shaderBottomLayerStartColor = (int) animation.getAnimatedValue());
bottomEndColorAnimator = ValueAnimator.ofArgb(bottomLayerEndColor, bottomLayerDisabledEndColor);
bottomEndColorAnimator.setDuration(animationDuration);
bottomEndColorAnimator.setInterpolator(new LinearInterpolator());
bottomEndColorAnimator.addUpdateListener(animation -> {
shaderBottomLayerEndColor = (int) animation.getAnimatedValue();
backLayerPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), shaderBottomLayerStartColor,
shaderBottomLayerEndColor, Shader.TileMode.CLAMP));
});
pointerColorAnimator = ValueAnimator.ofArgb(pointerEnabledColor, pointerDisabledColor);
pointerColorAnimator.setDuration(animationDuration);
pointerColorAnimator.setInterpolator(new LinearInterpolator());
pointerColorAnimator.addUpdateListener(animation -> {
pointerColor = (int) animation.getAnimatedValue();
pointerPaint.setColor(pointerColor);
});
colorsAnimatorSet = new AnimatorSet();
colorsAnimatorSet.playTogether(frontStartColorAnimator, frontEndColorAnimator,
bottomStartColorAnimator, bottomEndColorAnimator, pointerColorAnimator);
...
colorsAnimatorSet.start();