Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在颜色变化的画布上用Android绘制渐变色?_Android_Canvas_Gradient_Shader - Fatal编程技术网

如何在颜色变化的画布上用Android绘制渐变色?

如何在颜色变化的画布上用Android绘制渐变色?,android,canvas,gradient,shader,Android,Canvas,Gradient,Shader,我需要在画布的背景上涂上一种颜色,并应用阴影/渐变,但每次onDraw调用我都想更改颜色 在每次onDraw调用中,如果不创建新对象,我很难做到这一点。有人有什么想法吗?如果我使用drawPaint()并将一个新的着色器()设置为我的paint,那么我创建了一个新的着色器对象,如果我创建了一个新的GradientDrawable(),我也创建了一个新的着色器对象。我想避免GC 我想我可以重用一个GradientDrawable()对象并调用.setColor()方法,但这只是重置与之关联的任何渐

我需要在画布的背景上涂上一种颜色,并应用阴影/渐变,但每次onDraw调用我都想更改颜色

在每次onDraw调用中,如果不创建新对象,我很难做到这一点。有人有什么想法吗?如果我使用drawPaint()并将一个新的着色器()设置为我的paint,那么我创建了一个新的着色器对象,如果我创建了一个新的GradientDrawable(),我也创建了一个新的着色器对象。我想避免GC

我想我可以重用一个GradientDrawable()对象并调用.setColor()方法,但这只是重置与之关联的任何渐变数据,并将可绘制对象绘制为该纯色


有人吗?

不幸的是,您每次都必须创建一个新的LinearGradient。请注意,您不必使用GradientDrawable,您可以使用设置着色器的颜料自己绘制形状。

我想您要做的就是这样。创建一个LayerDrawable,然后在其中插入两个Drawable。插入的第一个可绘制图形应将其颜色设置为您希望背景的颜色,第二个应为设置为黑色的渐变色,并从alpha 0过渡到alpha 255


有关更多信息,请参阅:

< P>此问题在2017年年中仍然有效。我想为自定义视图的颜色更改创建平滑过渡。我使用了带有LinearGradient的着色器

我的意图是使我的观点在混乱和残废之间平稳过渡

由于观点的结构和目的,我的案例更为复杂。这是一个滑块。因此,我的视图由几乎两个相同的层组成,一个层使用画布绘制在第二个层的顶部。第三个元素是指针

两个图层都使用线性渐变,指针使用单一颜色

总结所有我必须同时在5种颜色之间进行转换:

  • 底层的开始和结束颜色-一个线性渐变
  • 顶层的开始和结束颜色-第二个LinearGradient
  • 指针颜色-正常颜色
解决方法是有5个独立的值Animator。最重要的是使用ValueAnimator.ofArgb():


在开始时,我还担心在每次动画更新时创建一个新的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();