2014-07-19 108 views
1

我想創建一個ImageView剪輯它的內容到一個多邊形內(在這種情況下是一個六邊形)。我的觀點的層類型設置爲軟件,這樣我就可以使用canvas.clipPath()ImageView剪切到Polygon

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
    setLayerType (LAYER_TYPE_SOFTWARE, null); 
} 

產生六角似乎精細的做工代碼:

Without clipping

下面是計算頂點的代碼:

@Override public void calculateVertices() { 
    width = 2f * radius; 
    side = 1.5f * radius; 
    height = (float) Math.sqrt (3f) * radius; 

    vertices = new Point[6]; 

    int minX = Integer.MAX_VALUE; 
    int minY = Integer.MAX_VALUE; 
    int maxX = Integer.MIN_VALUE; 
    int maxY = Integer.MIN_VALUE; 

    final float[] p0 = new float[] {center.x - radius, center.y}; 

    final Matrix m = new Matrix(); 
    final float r = getRotation(); 

    for (int i = 0; i < vertices.length; i++) { 
     final float ptRot = rotateBy (r, (float) i * 60f); 
     final float[] point = new float[2]; 

     if (ptRot != 0f) { 
      m.reset(); 
      m.postRotate (ptRot, center.x, center.y); 
      m.mapPoints (point, p0); 
     } else { 
      point[0] = p0[0]; 
      point[1] = p0[1]; 
     } 

     if (point[0] < minX) { 
      minX = Math.round (point[0]); 
     } else if (point[0] > maxX) { 
      maxX = Math.round (point[0]); 
     } 

     if (point[1] < minY) { 
      minY = Math.round (point[1]); 
     } else if (point[1] > maxY) { 
      maxY = Math.round (point[1]); 
     } 

     vertices[i] = fromFloat (point); 
    } 

    path.reset(); 
    clipPath.reset(); 

    path.moveTo (vertices[0].x, vertices[0].y); 
    clipPath.moveTo (vertices[0].x, vertices[0].y); 

    for (int i = 1; i < vertices.length; i++) { 
     path.lineTo (vertices[i].x, vertices[i].y); 
     clipPath.lineTo (vertices[i].x, vertices[i].y); 
    } 

    path.lineTo (vertices[0].x, vertices[0].y); 
    clipPath.lineTo (vertices[0].x, vertices[0].y); 
    path.close(); 
    clipPath.close(); 
    enclosure.set (minX, minY, maxX, maxY); 
} 

正如您在上面看到的,同樣的方法生成邊界矩形以及定義th的路徑e多邊形和多邊形的剪切路徑。

在該視圖中的構造,pathclipPath被定義爲這樣

path = new Path(); 
clipPath = new Path(); 
clipPath.setFillType (Path.FillType.INVERSE_EVEN_ODD); 

視圖的onDraw方法被重寫爲這樣:當我使線

@Override protected void onDraw (final Canvas canvas) { 
    final int count = canvas.save(); 
    canvas.clipPath (hexagon.getClipPath()); 
    super.onDraw (canvas); 
    hexagon.draw (canvas, selectBackgroundPaint()); 
    canvas.restoreToCount (count); 
} 

canvas.clipPath (hexagon.getClipPath());視圖顯示爲:

Clipping enabled

4個剪輯點中的2個甚至不在我的路徑上!

我在這裏做錯了什麼?有沒有更好的方法來做到這一點?

最終我希望多邊形以外的所有東西都是透明的。總是。包括選擇突出顯示。

我很感激幫助。我不能發佈太多的代碼(公司IP等),但如果您需要更多的細節,請告訴我,我會更新。這裏

+0

試圖達到什麼樣的?你想要什麼 – MilapTank

+0

一個ImageView,它的內容剪輯到一個多邊形 – copolii

+0

這意味着你的圖像視圖是六角形的權利? – MilapTank

回答

0

哥們是解決..

https://github.com/MostafaGazar/CustomShapeImageView更多細節https://coderwall.com/p/hmzf4w

使用這個庫ü會發現,在這個庫中的圓形,也容易使用。

U也可以讓你的自定義形狀像雲這樣的圖書館等這個庫支持SVG文件格式,他們做了圓角Imageview的SVG文件。

只要使用,讓我知道,如果有任何問題

+0

我不想要圓形圖像。我需要一個剪輯到路徑的ImageView。你讀過這個問題了嗎? – copolii

1

我有回答一個問題正是你想要的。 @SceLus也已被接受answer是那麼好,和獎金獲得者,所以你可以從它那裏得到幫助,因爲鏈接可能會改變,所以我複製粘貼代碼

HexagonMaskView。java的

public class HexagonMaskView extends View { 
private Path hexagonPath; 
private Path hexagonBorderPath; 
private float radius; 
private float width, height; 
private int maskColor; 

public HexagonMaskView(Context context) { 
    super(context); 
    init(); 
} 

public HexagonMaskView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(); 
} 

public HexagonMaskView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    init(); 
} 

private void init() { 
    hexagonPath = new Path(); 
    hexagonBorderPath = new Path(); 
    maskColor = 0xFF01FF77; 
} 

public void setRadius(float r) { 
    this.radius = r; 
    calculatePath(); 
} 

public void setMaskColor(int color) { 
    this.maskColor = color; 
    invalidate(); 
} 

private void calculatePath() { 
    float triangleHeight = (float) (Math.sqrt(3) * radius/2); 
    float centerX = width/2; 
    float centerY = height/2; 
    hexagonPath.moveTo(centerX, centerY + radius); 
    hexagonPath.lineTo(centerX - triangleHeight, centerY + radius/2); 
    hexagonPath.lineTo(centerX - triangleHeight, centerY - radius/2); 
    hexagonPath.lineTo(centerX, centerY - radius); 
    hexagonPath.lineTo(centerX + triangleHeight, centerY - radius/2); 
    hexagonPath.lineTo(centerX + triangleHeight, centerY + radius/2); 
    hexagonPath.moveTo(centerX, centerY + radius); 

    float radiusBorder = radius - 5; 
    float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder/2); 
    hexagonBorderPath.moveTo(centerX, centerY + radiusBorder); 
    hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY 
      + radiusBorder/2); 
    hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY 
      - radiusBorder/2); 
    hexagonBorderPath.lineTo(centerX, centerY - radiusBorder); 
    hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY 
      - radiusBorder/2); 
    hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY 
      + radiusBorder/2); 
    hexagonBorderPath.moveTo(centerX, centerY + radiusBorder); 
    invalidate(); 
} 

@Override 
public void onDraw(Canvas c) { 
    super.onDraw(c); 
    c.clipPath(hexagonBorderPath, Region.Op.DIFFERENCE); 
    c.drawColor(Color.WHITE); 
    c.save(); 
    c.clipPath(hexagonPath, Region.Op.DIFFERENCE); 
    c.drawColor(maskColor); 
    c.save(); 
} 

// getting the view size and default radius 
@Override 
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    width = MeasureSpec.getSize(widthMeasureSpec); 
    height = MeasureSpec.getSize(heightMeasureSpec); 
    radius = height/2 - 10; 
    calculatePath(); 
} 
} 

enter image description here

+0

有沒有辦法去除白色邊框之外的區域?我假設該區域是蒙版顏色,但如果您刪除蒙版顏色,事情會變得混亂。任何關於消除外部區域的想法? – mike20132013