2011-01-18 155 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分析設備上以「在屏幕上吧」 。一切都很好,並在安全範圍內運行。