2013-11-27 74 views
8

我正在繪製自定義視圖。在這個視圖中,我使用了兩個不同的繪畫和路徑對象來繪製到畫布上。我基本上是繪製兩個重疊的形狀。添加alpha後,重疊的視圖部分比圖像的其餘部分更暗。這是不受歡迎的,但我不知道如何解決它。Android自定義視圖不處理透明度/ alpha正確的方式

這是我的代碼裁剪,以顯示我如何使用阿爾法在我NewButtonView.java

Paint paint = new Paint(); 
int color = 0x33ffffff; 
int borderColor = 0xFF000000; 

paint.setColor(color); 
paint.setAntiAlias(true); 
paint.setStrokeWidth(strokeWidth); 
paint.setStrokeJoin(Paint.Join.ROUND); 
paint.setStrokeCap(Paint.Cap.ROUND); 
paint.setStyle(Paint.Style.FILL); 

約31分鐘後該Google I/O video ...他們顯示我想要的效果。

他們基本上顯示此圖像: enter image description here

添加透明度和得到這個圖片:令人失望的結果

enter image description here

他們結束了這一點:期望的結果

enter image description here

有沒有人有任何IDE一個關於如何獲得這種期望的影響?

+3

你確定它是你想改變的alpha嗎?似乎你想要的效果仍然是零透明的,它只是減輕了。 – Scott

+0

是的,我需要透明度,因爲我正在使用必須看到的紋理背景。 – EGHDK

+1

我的最佳想法是看看是否有方法將重疊形狀繪製爲一個形狀(或在繪製後將它們合併爲一個形狀)。將Alpha添加到複合形狀應該是他們想要的方式 – Scott

回答

12

正如視頻中提到的那樣,您可以使用Canvas#saveLayerAlpha(....)這個。您也可以在不使用它的情況下獲得類似的效果。我會在稍後討論。

讓我們創建一個示例視圖:

public class SampleView extends View { 

    // Declare Paint objects 
    Paint paintColor, paintBorder; 

    public SampleView(Context context) { 
     super(context); 

     // Initialize and set up Paint objects 
     paintColor = new Paint(); 
     paintBorder = new Paint(); 

     paintColor.setAntiAlias(true); 
     paintBorder.setAntiAlias(true); 

     paintBorder.setColor(Color.BLACK); 
     paintBorder.setStyle(Style.STROKE); 
     paintBorder.setStrokeWidth(10); 

     // Just a random image to 'see' the difference 
     setBackground(getResources().getDrawable(R.drawable.hor_lines)); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     // Save layer alpha for Rect that covers the view : alpha is 90/255 
     canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), 90, 
              Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); 

     // Draw first circle, and then the border 
     paintColor.setColor(Color.RED); 
     canvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 

     canvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

     // Draw second circle, and then the border 
     paintColor.setColor(Color.BLUE); 
     canvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 
     canvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

     // Finally, restore the canvas 
     canvas.restore(); 
    } 
} 

會發生什麼:saveLayerAlpha(....)被稱爲

  1. 脫屏位圖進行分配。

  2. 所有繪圖操作都發生在這個位圖上。

  3. 當調用canvas.restore()時,會將此位圖傳輸到屏幕畫布上,並將我們在saveLayerAlpha(....)中提供的alpha值應用於離屏位圖。

(我認爲)以下是在不使用saveLayerAlpha(....)產生這種效果的等效方式:

public class SView extends View { 

    Paint paintColor, paintBorder, paintAlpha; 

    Bitmap toDrawOn; 

    public SView(Context context) { 
     super(context); 

     paintAlpha = new Paint(); 

     paintAlpha.setColor(Color.parseColor("#90FFFFFF")); 
     paintAlpha.setAntiAlias(true); 

     .... 
     .... 

    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     if (toDrawOn == null) { 

      // Create a new Bitmap 
      toDrawOn = Bitmap.createBitmap(getWidth(), getHeight(), 
                Config.ARGB_8888); 

      // Create a new Canvas; drawing operations 
      // will happen on 'toDrawOn' 
      Canvas offScreen = new Canvas(toDrawOn); 

      // First circle 
      paintColor.setColor(Color.RED); 
      offScreenCanvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 
      offScreenCanvas.drawCircle(getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

      // Second circle 
      paintColor.setColor(Color.BLUE); 
      offScreenCanvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 20, paintColor); 
      offScreenCanvas.drawCircle(2 * getWidth()/3, getHeight()/2, 
              getWidth()/4 - 15, paintBorder); 

      // Draw bitmap 'toDrawOn' to canvas using 'paintAlpha' 
      canvas.drawBitmap(toDrawOn, 0, 0, paintAlpha); 

     } else { 

      // 'toDrawOn' is not null; draw it 
      canvas.drawBitmap(toDrawOn, 0, 0, paintAlpha); 
     } 
    } 
} 

輸出:

enter image description here

只是參考,上圖中的基礎容器是LinearLayout,背景設置爲此jpeg:Link

而且,用作SampleView的背景中的繪製:here

// Just a random image to 'see' the difference 
setBackground(getResources().getDrawable(R.drawable.hor_lines)); 

取自。

+1

你也可以用100%不透明度創建一個cavanas繪製圖像,然後減少cavanas的不透明度。 –

+0

@MarcosEusebi您將如何更改畫布的透明度/不透明度? – Vikram

+0

對不起,我不介意。將圖像加入到位圖中,然後將位圖繪製到cavnas並設置位圖的不透明度。 –

0

你可以用完整的alpha位圖繪製的一切,然後更改位圖的Alpha

(對不起,這是一個多答案,但堆棧溢出不會讓我要發表評論,評論)

相關問題