2016-04-19 47 views
2

我看過很多關於transparent背景的兒童Views背景上的自定義ViewGroup SO,但是沒有人似乎有這個問題。繪圖透明區域不與更新與拖拽監聽器

背景:
我創建了一個自定義的FrameLayout;此容器具有動態添加的視圖。它的孩子應該有一個透明背景,但容器的其他表面必須有背景顏色。孩子們的意見可以是drag'n'dropped任何地方進入這個容器。

我做什麼:
我重寫dispatchDraw(),創建一個Bitmap和新Canvas,然後我填一個白色背景的新畫布。
我在兒童視圖上製作一個循環,從兒童的尺寸創建一個新的PaintRect並使用PorterDuff.Mode.DST_OUT清除孩子的區域。對於每個孩子,我將Paint和Rect添加到新的Canvas。
最後,我使用dispatchDraw()給出的主畫布上的drawBitmap,通過傳遞創建的位圖。

問題:
這非常適用:孩子有一個透明背景和其餘爲填充白色背景。但是,當我向孩子添加DragListener時,「切割」區域未更新(而dispatchDraw被正確調用):換句話說,當我拖動子視圖時,已完全丟棄,但透明區域仍處於一樣的地方。

代碼:
定製FrameLayout

@Override 
public void dispatchDraw(Canvas canvas) { 
    super.dispatchDraw(canvas); 
    drawCanvas(canvas); 
} 

private void drawCanvas(Canvas canvas) { 
    // Create an off-screen bitmap and its canvas 
    Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
    Canvas auxCanvas = new Canvas(bitmap); 

    // Fill the canvas with the desired outside color 
    auxCanvas.drawColor(Color.WHITE); 

    // Create a paint for each child into parent 
    for (int i = 0; i < getChildCount(); ++i) { 
     // Create a transparent area for the Rect child 
     View child = this.getChildAt(i); 
     Paint childPaint = new Paint(); 
     childPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); 
     Rect childRect = new Rect(child.getLeft(), child.getTop(), child.getRight(), child.getBottom()); 
     auxCanvas.drawRect(childRect, childPaint); 
    } 

    // Draw the bitmap into the original canvas 
    canvas.drawBitmap(bitmap, 0, 0, null); 
} 

DragListenerACTION_DROP的事件:

case DragEvent.ACTION_DROP: 
    x = event.getX(); 
    y = event.getY(); 

    FrameLayout frame = (FrameLayout) v; 
    View view = (View) event.getLocalState(); 
    view.setX(x - (view.getWidth()/2)); 
    view.setY(y - (view.getHeight()/2)); 
    frame.invalidate(); 
    break; 

截圖:

我想對於所有將q &一個我發現這麼多的事情,但似乎沒有任何工作。
任何幫助將非常感激。

回答

1

最後,我發現線索:更新後,透明Paint未獲得正確的x和y軸值。

我想getLeft()getTop()getRight()getBottom()不會改變時發生下降。奇怪的是,在我的日誌中,這些值似乎被更新了。相反,我用getX()getY()來更新DragEvent.ACTION_DROP的值,並且它正確地改變了透明區域的座標。

在循環中的孩子們的解決方案:

Paint childPaint = new Paint(); 
childPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); 
// Use the x and y axis (plus the width and height) 
Rect childRect = new Rect(
    (int) child.getX(), 
    (int) child.getY(), 
    (int) child.getX() + child.getWidth(), 
    (int) child.getY() + child.getHeight() 
); 
auxCanvas.drawRect(childRect, childPaint);