尝试这个视图。您可能需要根据您的具体需求进行调整,但它会在视图的顶部绘制一个带有边框的六边形蒙版。背景资源低于掩码。

结果:

代码:

HexagonMaskView.java

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Path;

import android.graphics.Region;

import android.util.AttributeSet;

import android.view.View;

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();

}

}

更新29.07.2016

一个更好的方式,只剪辑源图像,而不画整个视图的背景。切换到ImageView作为基类,以受益于scaleType。我也做了一些代码重构。

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.graphics.PorterDuff;

import android.graphics.Region;

import android.util.AttributeSet;

import android.widget.ImageView;

public class HexagonMaskView extends ImageView {

private Path hexagonPath;

private Path hexagonBorderPath;

private Paint mBorderPaint;

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() {

this.hexagonPath = new Path();

this.hexagonBorderPath = new Path();

this.mBorderPaint = new Paint();

this.mBorderPaint.setColor(Color.WHITE);

this.mBorderPaint.setStrokeCap(Paint.Cap.ROUND);

this.mBorderPaint.setStrokeWidth(50f);

this.mBorderPaint.setStyle(Paint.Style.STROKE);

}

public void setRadius(float radius) {

calculatePath(radius);

}

public void setBorderColor(int color) {

this.mBorderPaint.setColor(color);

invalidate();

}

private void calculatePath(float radius) {

float halfRadius = radius / 2f;

float triangleHeight = (float) (Math.sqrt(3.0) * halfRadius);

float centerX = getMeasuredWidth() / 2f;

float centerY = getMeasuredHeight() / 2f;

this.hexagonPath.reset();

this.hexagonPath.moveTo(centerX, centerY + radius);

this.hexagonPath.lineTo(centerX - triangleHeight, centerY + halfRadius);

this.hexagonPath.lineTo(centerX - triangleHeight, centerY - halfRadius);

this.hexagonPath.lineTo(centerX, centerY - radius);

this.hexagonPath.lineTo(centerX + triangleHeight, centerY - halfRadius);

this.hexagonPath.lineTo(centerX + triangleHeight, centerY + halfRadius);

this.hexagonPath.close();

float radiusBorder = radius - 5f;

float halfRadiusBorder = radiusBorder / 2f;

float triangleBorderHeight = (float) (Math.sqrt(3.0) * halfRadiusBorder);

this.hexagonBorderPath.reset();

this.hexagonBorderPath.moveTo(centerX, centerY + radiusBorder);

this.hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY + halfRadiusBorder);

this.hexagonBorderPath.lineTo(centerX - triangleBorderHeight, centerY - halfRadiusBorder);

this.hexagonBorderPath.lineTo(centerX, centerY - radiusBorder);

this.hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY - halfRadiusBorder);

this.hexagonBorderPath.lineTo(centerX + triangleBorderHeight, centerY + halfRadiusBorder);

this.hexagonBorderPath.close();

invalidate();

}

@Override

public void onDraw(Canvas c) {

c.drawPath(hexagonBorderPath, mBorderPaint);

c.clipPath(hexagonPath, Region.Op.INTERSECT);

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

super.onDraw(c);

}

@Override

public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = MeasureSpec.getSize(heightMeasureSpec);

setMeasuredDimension(width, height);

calculatePath(Math.min(width / 2f, height / 2f) - 10f);

}

}

示例布局:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

android:background="@android:color/holo_green_dark">

android:id="@+id/image"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:src="@drawable/bear"

android:background="@android:color/holo_green_light"/>

FXPot.png

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐