使用方式:直接在xml中使用便可。android
<com.base.baseview.RoundLayout android:id="@+id/example_view" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:layout_gravity="center_horizontal" app:attr_round_corner="7dp">
import android.content.Context; import android.content.res.TypedArray; 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.graphics.Region; import android.util.AttributeSet; import android.view.View; import android.widget.RelativeLayout; /** * 圓角佈局 * 支持自定義屬性見<>declare-styleable name="RoundLayout"</> * <p> * 須要圓角的View做爲<>RoundLayout</>的子View便可,設置<>attr_round_corner</>圓角半徑 */ public class RoundLayout extends RelativeLayout { public float[] radii = new float[8]; // top-left, top-right, bottom-right, bottom-left public Path mClipPath; // 剪裁區域路徑 public Paint mPaint; // 畫筆 public int mStrokeColor; // 描邊顏色 public int mStrokeWidth; // 描邊半徑 public boolean mClipBackground; // 是否剪裁背景 public Region mAreaRegion; // 內容區域 public RectF mLayer; // 畫布圖層大小 private int mRoundCorner; // 圓角大小 public RoundLayout(Context context, int radius) { this(context); this.mRoundCorner = PixelUtils.dip2px(context, radius); } public RoundLayout(Context context) { this(context, null); } public RoundLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttrs(context, attrs); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mLayer.set(0, 0, w, h); refreshRegion(this); } @Override protected void dispatchDraw(Canvas canvas) { canvas.saveLayer(mLayer, null, Canvas.ALL_SAVE_FLAG); super.dispatchDraw(canvas); onClipDraw(canvas); canvas.restore(); } @Override public void draw(Canvas canvas) { refreshRegion(this); if (mClipBackground) { canvas.save(); canvas.clipPath(mClipPath); super.draw(canvas); canvas.restore(); } else { super.draw(canvas); } } public void initAttrs(Context context, AttributeSet attrs) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundLayout); mStrokeColor = ta.getColor(R.styleable.RoundLayout_attr_stroke_color, Color.WHITE); mStrokeWidth = ta.getDimensionPixelSize(R.styleable.RoundLayout_attr_stroke_width, 0); mClipBackground = ta.getBoolean(R.styleable.RoundLayout_attr_clip_background, false); if (mRoundCorner == 0) { mRoundCorner = ta.getDimensionPixelSize(R.styleable.RoundLayout_attr_round_corner, 4); } int roundCornerTopLeft = ta.getDimensionPixelSize( R.styleable.RoundLayout_attr_round_corner_top_left, mRoundCorner); int roundCornerTopRight = ta.getDimensionPixelSize( R.styleable.RoundLayout_attr_round_corner_top_right, mRoundCorner); int roundCornerBottomLeft = ta.getDimensionPixelSize( R.styleable.RoundLayout_attr_round_corner_bottom_left, mRoundCorner); int roundCornerBottomRight = ta.getDimensionPixelSize( R.styleable.RoundLayout_attr_round_corner_bottom_right, mRoundCorner); ta.recycle(); radii[0] = roundCornerTopLeft; radii[1] = roundCornerTopLeft; radii[2] = roundCornerTopRight; radii[3] = roundCornerTopRight; radii[4] = roundCornerBottomRight; radii[5] = roundCornerBottomRight; radii[6] = roundCornerBottomLeft; radii[7] = roundCornerBottomLeft; mLayer = new RectF(); mClipPath = new Path(); mAreaRegion = new Region(); mPaint = new Paint(); mPaint.setColor(Color.WHITE); mPaint.setAntiAlias(true); setLayerType(View.LAYER_TYPE_HARDWARE, null); } public void refreshRegion(View view) { int w = (int) mLayer.width(); int h = (int) mLayer.height(); RectF areas = new RectF(); areas.left = view.getPaddingLeft(); areas.top = view.getPaddingTop(); areas.right = w - view.getPaddingRight(); areas.bottom = h - view.getPaddingBottom(); mClipPath.reset(); mClipPath.addRoundRect(areas, radii, Path.Direction.CW); Region clip = new Region((int) areas.left, (int) areas.top, (int) areas.right, (int) areas.bottom); mAreaRegion.setPath(mClipPath, clip); } public void onClipDraw(Canvas canvas) { if (mStrokeWidth > 0) { // 將與描邊區域重疊的內容裁剪掉 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); mPaint.setColor(Color.WHITE); mPaint.setStrokeWidth(mStrokeWidth * 2); mPaint.setStyle(Paint.Style.STROKE); canvas.drawPath(mClipPath, mPaint); // 繪製描邊 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); mPaint.setColor(mStrokeColor); mPaint.setStyle(Paint.Style.STROKE); canvas.drawPath(mClipPath, mPaint); } mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaint.setColor(Color.WHITE); mPaint.setStyle(Paint.Style.FILL); canvas.drawPath(mClipPath, mPaint); } }
喜歡的朋友點個贊吧,真的是很是好用!canvas