2014-04-25 128 views
1

我有一個應用程序,要求整個RelativeLayout(現在是一個自定義視圖擴展它)需要使用自定義圖像屏蔽。在佈局中有許多視圖需要通過觸摸來訪問並且是動態的。安卓視圖/佈局屏蔽

我已經成功地掩蓋了區域使用回答另一個問題繪製形狀:

@Override 
protected void dispatchDraw(Canvas canvas) { 
    Path path = new Path(); 
    int count = canvas.save(); 

    path.addCircle(400, 200, 300, Path.Direction.CW); 

    canvas.clipPath(path); 

    super.dispatchDraw(canvas); 
    canvas.restoreToCount(count); 

} 

不過,我需要使用圖像源作爲我的面具,而不是源的形狀,我可以創作。我已經使用了PorterDuff工具來改變位圖:

Bitmap resizedBitmap = Bitmap.createScaledBitmap(mMask, this.getWidth(), this.getHeight(), false); 
    Bitmap result = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888); //create another bitmap with same height 

    Canvas mCanvas = new Canvas(result); 
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 
    mCanvas.drawBitmap(resizedBitmap, 0, 0, paint); 
    paint.setXfermode(null); 
    onDrawCanvas.drawBitmap(result, 0,0, paint); 

,對掩蔽圖像的作品,但我需要用夾子(我認爲)來掩蓋。有沒有一種方法可以使用不同的PorterDuff模式從此圖像中獲取路徑?還是有一個更簡單的方法,就像在iOS中,您可以直接使用圖像設置layerMask?提前致謝。

回答

2

框架中沒有直接的API允許您跟蹤實體圖像蒙版並生成可用於剪裁的Path。如果您可以訪問掩碼內容SVG,你也許能夠使用路徑跟蹤技術羅曼蓋伊描述這裏: http://www.curious-creature.org/2013/12/21/android-recipe-4-path-tracing/

雖然這不是我最喜歡的技術,我見過的最好的選擇基本上是你已經描述的項目的組合。我們需要創建一個可以渲染視圖內容的屏幕外緩衝區(通過Canvas + Bitmap),然後使用傳輸模式技術將結果應用到附着在窗口上的Canvas上。我還沒有用ViewGroup來發送,但它應該可以工作。以下(未經測試)代碼將是一個起點:

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    if (w != oldw || h != oldh) { 
     //Create an area to use for content rendering 
     mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     mCanvas = new Canvas(mCanvasBitmap); 
     mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN); 
    } 
} 

@Override 
protected void dispatchDraw(Canvas canvas) { 
    //Render contents into our buffer 
    super.dispatchDraw(mCanvas); 

    //Render the mask, clipping with a PorterDuffXfermode 
    paint.setXfermode(mXfermode); 
    mCanvas.drawBitmap(mMask, 0, 0, paint); 

    //Clear state and transfer result 
    paint.setXfermode(null); 
    canvas.drawBitmap(mCanvasBitmap, 0, 0, paint); 
} 

這種方法的一個缺點是內存;如果視圖足夠大,則必須分配一個與視圖容器大小相等的額外塊。我們可以通過執行一次並重新使用緩衝區來將這種影響降至最低。

+0

我嘗試了你建議的兩種方法。使用SVG的路徑跟蹤工作,但在蒙版曲線上有點波動。我結束了與位圖解決方案。謝謝!! – user3574181