2013-11-27 15 views
8

私はカスタムビューを描画しています。このビューでは、キャンバスにペイントするために2つの異なるペイントオブジェクトとパスオブジェクトを使用します。私は基本的に重なり合う2つの図形を描きます。アルファを追加すると、重なっているビューの部分は残りの部分よりも暗くなります。これは望ましくないですが、私はそれを修正する方法がわかりません。Androidカスタムビューで透明/アルファが正しく処理されない

これは私がこのGoogle I/O videoに私の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分でアルファを使用しています...彼らは私の所望の効果を示し、どのように表示する私のコードのクリッピングです。 enter image description here

この画像の透明性を追加し、取得::

は、彼らは基本的にこのイメージを示し望ましくない結果を

enter image description here

彼らはこれで終わる:望ましい結果を

enter image description here

誰かがideを持っていますか?どのようにこの希望の影響を取得するには?

+3

あなたは変更したいアルファですか?あなたの望む効果がまだ透明度ゼロであるように思えますが、それはちょうど明るくなります。 – Scott

+0

はい、私は見えなければならないテクスチャ付きの背景を使用しているので、透明度が必要です。 – EGHDK

+1

次に、重なり合った図形を1つの図形として描画する方法があるかどうかを確認することです。コンポジットシェイプにアルファを追加すると、彼らの望むようになります – 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(....)で指定したアルファ値がオフスクリーンビットマップに適用されます。

(と思う)次は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描画イメージを作成してから、キャビナス不透明度を減らすこともできます。 –

+0

@ MarcosEusebiどのようにキャンバスの透明度/不透明度を変更しますか? – Vikram

+0

申し訳ありませんが、私は気にしませんでした。イメージをビットマップに結合し、ビットマップをcavnasに描画し、ビットマップの不透明度を設定します。 –

0

あなたは完全なアルファでビットマップ内のすべてを描き、その後、ビットマップのアルファ

を変更することができます(申し訳ありませんが、これは答えよりも多くのコメントであるが、スタックオーバーフローが、私はコメントを投稿することができません)

関連する問題