2011-01-18 158 views
9

我需要绘制背景我的画布单色与应用阴影/渐变,但每个onDraw调用我想潜在地改变颜色。如何在颜色变化的画布上在Android上绘制渐变颜色?

我有麻烦,而无需创建一个新的对象的每个电话的onDraw这样做。有人有主意吗?如果我使用drawPaint()并为我的paint设置了一个新的着色器(),那么我创建了一个新的着色器对象,并且如果我创建了一个新的GradientDrawable(),我也有。我想避免GC。

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

有人吗?

回答

5

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

+0

感谢罗曼,你能分享一下你对我下面campnic的评论吗?我想知道什么最有效的.draw ...()方法将绘制创建此效果所需的两个图层,或者如果LayerDrawable正是我所需要的。 – Greg 2011-01-19 01:33:13

+0

@Romain Guy我一直在试图使用SweepGradient来实现圆锥渐变效果。但它似乎只适用于两种颜色。如果我使用四色数组,那么** SweepGradient **似乎不像预期的那样工作。我尝试过**位置**值的各种组合,并尝试设置位置为** NULL **,但大多数我只能获得两种颜色或不是圆锥形的渐变。任何帮助将非常感激。 – 2016-07-05 06:49:01

0

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

For more信息,请参见:​​

0

这个问题仍然是有效的,几乎在2017年中旬,我想为我的自定义视图颜色变化的平稳过渡。我使用了LinearGradients着色器。

我的目的是让betweeen我的观点的anabled和禁用状态的平稳过渡。

我的情况就更加复杂了,由于观点的建设和目的。这是一个滑块。所以我的视图由几乎2个相同的图层组成,使用画布在第二个图层上绘制一个图层。第三个元素是一个指针。

两个层使用LinearGradients,指针使用单一颜色。

总结所有我在同一时间做5种颜色之间的过渡:

  • 开始和底层端颜色 - 酮的LinearGradient,
  • 开始和结束颜色顶层 - 第二的LinearGradient ,
  • 指针颜色 - 正常颜色;

解决方案是为具有5个独立的ValueAnimators。最重要的是使用ValueAnimator.ofArgb():

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(); 

我也是在开始关注建立在每个动画更新一个新的LinearGradient但后来我推出GPU分析设备上以“在屏幕上吧” 。一切都很好,并在安全范围内运行。