原理
类似于圆形图片,都是将图片事在指定的模子中。
首先计算出五角形外围五个点的坐标,通过直线连接,这样便可将五角形的区域给定住。再通过设置了BitmapShader的Paint将该路径画出即可。微信中发图片时图片会显示出一个尖角,也可以通过该种思路完成。
代码
public class DemoView extends View {
private Paint paint;
private Bitmap bitmap;
public DemoView(Context context) {
this(context, null);
}
public DemoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DemoView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
paint = new Paint();
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.fengjing);
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//将可能非正方形变成正方形
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
switch (MeasureSpec.getMode(widthMeasureSpec)){
case MeasureSpec.AT_MOST:
widthSize = Math.min(widthSize,bitmap.getWidth());
break;
case MeasureSpec.UNSPECIFIED:
widthSize = bitmap.getWidth();
break;
}
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
switch (MeasureSpec.getMode(heightMeasureSpec)){
case MeasureSpec.AT_MOST:
heightSize = Math.min(heightSize,bitmap.getHeight());
break;
case MeasureSpec.UNSPECIFIED:
heightSize = bitmap.getHeight();
break;
}
int size = Math.min(widthSize, heightSize);
setMeasuredDimension(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setTextSize(100);
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Matrix matrix = new Matrix();
matrix.preScale(getWidth() * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight());
paint.setAntiAlias(true);
// matrix.preTranslate(bitmap.getWidth() /2,bitmap.getHeight() /2);
shader.setLocalMatrix(matrix);
paint.setShader(shader);
paint.setStyle(Paint.Style.FILL);
Path path = new Path();
PointF topPoint = getTopPoint();
path.moveTo(topPoint.x, topPoint.y);
PointF lb = getLB();
path.lineTo(lb.x,lb.y);
PointF rt = getRT();
path.lineTo(rt.x,rt.y);
PointF lt = getLT();
path.lineTo(lt.x,lt.y);
PointF rb = getRB();
path.lineTo(rb.x,rb.y);
path.close();
canvas.drawPath(path,paint);
}
private float getLength() {//计算五角形边的长度
return (float) (getWidth() * sin(36));
}
private PointF getTopPoint() {
PointF pointF = new PointF();
pointF.set(getWidth() / 2, 0);
return pointF;
}
//left-top
private PointF getLT() {
PointF pointF = new PointF();
pointF.set((getWidth() - getWidth() * (float) sin(72)) / 2, getWidth() * (float) sin(36) * (float) sin(36));
return pointF;
}
//right-top
private PointF getRT() {
PointF pointF = new PointF();
pointF.set((getWidth() + getWidth() * (float) sin(72)) / 2, getWidth() * (float) sin(36) * (float) sin(36));
return pointF;
}
//right-bottom
private PointF getRB() {
PointF lt = getRT();
PointF pointF = new PointF();
pointF.set(lt.x - getLength() * (float)sin(18),lt.y + getLength() * (float)cos(18));
return pointF;
}
//left-bottom
private PointF getLB() {
PointF lt = getLT();
PointF pointF = new PointF();
pointF.set(lt.x+getLength() * (float)sin(18),lt.y + getLength() * (float)cos(18));
return pointF;
}
private double sin(double angle) {
return Math.sin(Math.toRadians(angle));
}
private double cos(double angle) {
return Math.cos(Math.toRadians(angle));
}
}
注释
主要是通过BitmapShader完成的绘制。任何形状的图形,只要先勾勒出区域,然后按BitmapShader方式进行绘制,都可以绘制到指定的形状。