UI效果:
直角的八边形 与圆角的八边形
RoundCornerLayout 代码:
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.PorterDuffXfermode;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
public class RoundCornerLayout extends FrameLayout {
private int mLength = DimenUtils.dp2px(18);
private float mRadius = DimenUtils.dp2px(7);
private Paint mPaint = new Paint();
private Path mPath = new Path();
public RoundCornerLayout(Context context) {
this(context, null);
}
public RoundCornerLayout(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundCornerLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
fixClipPathUnsupportedOperationException(this);
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
setWillNotDraw(false);
}
@Override
public void draw(Canvas canvas) {
float a = (float) (mRadius * Math.tan(45/2));
float distLong = mLength + a + mRadius;
float distShort = mLength + a - mRadius;
RectF leftRect1 = new RectF(0, distShort, 2 * mRadius, distLong);
//圆角八边形路径(画圆弧)
mPath.arcTo(leftRect1,180,45);
RectF leftRect2 = new RectF(distShort, 0, distLong, 2 * mRadius);
mPath.arcTo(leftRect2,225,45);
RectF topRect1 = new RectF(getWidth()-distLong, 0, getWidth()-distShort, 2 * mRadius);
mPath.arcTo(topRect1,270,45);
RectF topRect2 = new RectF(getWidth()-2*mRadius, distShort, getWidth(), distLong);
mPath.arcTo(topRect2,315,45);
RectF rightRect1 = new RectF(getWidth()-2*mRadius, getHeight() - distLong, getWidth(), getHeight()-distShort);
mPath.arcTo(rightRect1,0,45);
RectF rightRect2 = new RectF(getWidth()-distLong, getHeight()-2*mRadius, getWidth()-distShort, getHeight());
mPath.arcTo(rightRect2,45,45);
RectF bottomRect1 = new RectF(distShort, getHeight()-2*mRadius, distLong, getHeight());
mPath.arcTo(bottomRect1,90,45);
RectF bottomRect2 = new RectF(0, getHeight() - distLong, 2 * mRadius, getHeight()-distShort);
mPath.arcTo(bottomRect2,135,45);
//直角八边形路径(只需要画直线)
// mPath.moveTo(mLength, 0);
// mPath.lineTo(0, mLength);
// mPath.lineTo(0, getHeight() - mLength);
// mPath.lineTo(mLength, getHeight());
// mPath.lineTo(getWidth() - mLength, getHeight());
// mPath.lineTo(getWidth(), getHeight() - mLength);
// mPath.lineTo(getWidth(), mLength);
// mPath.lineTo(getWidth() - mLength, 0);
mPath.close();
canvas.save();
//裁剪canvas,限定绘制区域
canvas.clipPath(mPath);
super.draw(canvas);
canvas.restore();
}
public static void fixClipPathUnsupportedOperationException(View view) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
}
在xml中使用方法:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.haolan.infomation.account.MainActivity"
android:gravity="center">
<com.tudou.pathtest.RoundCornerLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="圆角八边形"
android:background="#62A1F0"
android:textColor="@color/white"
android:gravity="center"/>
</com.tudou.pathtest.RoundCornerLayout>
</LinearLayout>
可以根据设计需求,更改 path 路径,绘制不同形状的 layout 布局