2016-04-19 4 views
2

子どもの背景にという背景に関する多くの疑問がありましたが、のカスタムViewGroupからは誰もこの問題を抱えていないようです。透明な領域を描画するのがドラッグリスナーで更新されない

背景:私は、カスタムFrameLayoutを作成
。このコンテナには動的にビューが追加されます。その子は透明な背景を持つ必要がありますが、コンテナの他のサーフェスは背景色を持たなければなりません。子供ビューはこのコンテナにどこでもdrag'n'droppedすることができます。

私は何を:
私は、私は白の背景で新しいキャンバスを埋め、Bitmapと新しいCanvasを作成し、dispatchDraw()をオーバーライドします。
子ビューにループを作成します。子供のサイズから新しいPaintRectを作成し、PorterDuff.Mode.DST_OUTを使用して子供のエリアをクリアします。それぞれの子に対して、新しいキャンバスにペイントとRectを追加します。
最後に、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); 
} 

DragListenerさんACTION_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 & Aについてたくさんのことを試してみましたが、何も動作していないようにみえます。
ご協力いただければ幸いです。

答えて

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); 
関連する問題