2014-09-30 88 views
1

我如何實現如下所示的六角形圖像視圖。Android Hexagon ImageView

http://imgur.com/1PEGuQu

請注意,我試圖解決方案是在這個問題: How to give hexagon shape to ImageView

而且我也試過這個解決方案: Masking(crop) image in frame

但我不想填充顏色六邊形之外。我希望它是透明的,所以可以看到背後的意見和圖像。

順便說一句,我試過,BitmapShader,PorterDuffXFermode等,但無法設法得到我想要的結果。

在此先感謝。

回答

2

我終於解決了我的問題。我找到一個非常有用的圖書館,專門做我想要的技巧。它用svg類型的矢量圖像來掩蓋imageview。

庫:

CustomShapeImageView

結果:

Screenshot

編輯:我也想與大家分享的六邊形SVG,在必要的情況下。

<svg width="205" height="237" xmlns="http://www.w3.org/2000/svg"> 
<title>hexagon</title> 
<metadata id="metadata3064">image/svg+xml</metadata> 
<g> 
<title>Layer 1</title> 
<polygon points="0,59.27092742919922 0,177.8127899169922 102.66026306152344,237.08370971679688 205.3205108642578,177.8127899169922 205.3205108642578,59.27092742919922 102.66026306152344,0 " id="svg_1" fill="#000000"/> 
</g> 
</svg> 
+0

嗨。 SafaOrhan,svg必須保存在哪個文件夾和哪個擴展名中? – Jack 2016-02-12 07:07:57

+1

@Jack你可以把它放到/ res/raw文件夾中而不需要任何擴展名。 – SafaOrhan 2016-02-12 08:43:10

3

這裏是我的這個代碼,這個支持陰影:

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapShader; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.PorterDuff; 
import android.graphics.Shader; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.widget.ImageView; 

public class HexagonImageView extends ImageView { 

    private Path hexagonPath; 
    private Path hexagonBorderPath; 
    private float radius; 
    private Bitmap image; 
    private int viewWidth; 
    private int viewHeight; 
    private Paint paint; 
    private BitmapShader shader; 
    private Paint paintBorder; 
    private int borderWidth = 4; 

    public HexagonImageView(Context context) { 
     super(context); 
     setup(); 
    } 

    public HexagonImageView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setup(); 
    } 

    public HexagonImageView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
     setup(); 
    } 

    private void setup() { 
     paint = new Paint(); 
     paint.setAntiAlias(true); 

     paintBorder = new Paint(); 
     setBorderColor(Color.WHITE); 
     paintBorder.setAntiAlias(true); 
     this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); 
     paintBorder.setShadowLayer(4.0f, 1.0f, 1.0f, Color.BLACK); 

     hexagonPath = new Path(); 
     hexagonBorderPath = new Path(); 
    } 

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

    public void setBorderWidth(int borderWidth) { 
     this.borderWidth = borderWidth; 
     this.invalidate(); 
    } 

    public void setBorderColor(int borderColor) { 
     if (paintBorder != null) 
      paintBorder.setColor(borderColor); 

     this.invalidate(); 
    } 

    private void calculatePath() { 

     float triangleHeight = (float) (Math.sqrt(3) * radius/2); 
     float centerX = viewWidth/2; 
     float centerY = viewHeight/2; 

     hexagonBorderPath.moveTo(centerX, centerY + radius); 
     hexagonBorderPath.lineTo(centerX - triangleHeight, centerY + radius/2); 
     hexagonBorderPath.lineTo(centerX - triangleHeight, centerY - radius/2); 
     hexagonBorderPath.lineTo(centerX, centerY - radius); 
     hexagonBorderPath.lineTo(centerX + triangleHeight, centerY - radius/2); 
     hexagonBorderPath.lineTo(centerX + triangleHeight, centerY + radius/2); 
     hexagonBorderPath.moveTo(centerX, centerY + radius); 

     float radiusBorder = radius - borderWidth;  
     float triangleBorderHeight = (float) (Math.sqrt(3) * radiusBorder/2); 

     hexagonPath.moveTo(centerX, centerY + radiusBorder); 
     hexagonPath.lineTo(centerX - triangleBorderHeight, centerY + radiusBorder/2); 
     hexagonPath.lineTo(centerX - triangleBorderHeight, centerY - radiusBorder/2); 
     hexagonPath.lineTo(centerX, centerY - radiusBorder); 
     hexagonPath.lineTo(centerX + triangleBorderHeight, centerY - radiusBorder/2); 
     hexagonPath.lineTo(centerX + triangleBorderHeight, centerY + radiusBorder/2); 
     hexagonPath.moveTo(centerX, centerY + radiusBorder); 

     invalidate(); 
    } 

    private void loadBitmap() { 
     BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable(); 

     if (bitmapDrawable != null) 
      image = bitmapDrawable.getBitmap(); 
    } 

    @SuppressLint("DrawAllocation") 
    @Override 
    public void onDraw(Canvas canvas){ 
     super.onDraw(canvas); 

     loadBitmap(); 

     // init shader 
     if (image != null) { 

      canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); 

      shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
      paint.setShader(shader); 

      canvas.drawPath(hexagonBorderPath, paintBorder); 
      canvas.drawPath(hexagonPath, paint); 
     } 

    } 

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     int width = measureWidth(widthMeasureSpec); 
     int height = measureHeight(heightMeasureSpec, widthMeasureSpec); 

     viewWidth = width - (borderWidth * 2); 
     viewHeight = height - (borderWidth * 2); 

     radius = height/2 - borderWidth; 

     calculatePath(); 

     setMeasuredDimension(width, height); 
    } 

    private int measureWidth(int measureSpec) { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpec); 
     int specSize = MeasureSpec.getSize(measureSpec); 

     if (specMode == MeasureSpec.EXACTLY) { 
      result = specSize; 
     } 
     else { 
      result = viewWidth; 
     } 

     return result; 
    } 

    private int measureHeight(int measureSpecHeight, int measureSpecWidth) { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpecHeight); 
     int specSize = MeasureSpec.getSize(measureSpecHeight); 

     if (specMode == MeasureSpec.EXACTLY) { 
      result = specSize; 
     } 
     else { 
      result = viewHeight; 
     } 

     return (result + 2); 
    } 


}