Android Canvas 圆角处理
16lz
2021-01-23
目录表
- android 自定义view必备api
- android 可拖动圆环刻度条
- android 仿滴滴大头针跳动波纹效果
- android 仿网易云鲸云音效
- Android 仿滴滴首页嵌套滑动效果
- path 的圆角处理
在开发过程中,圆角背景和圆角图片应该都算是标配了,如下面效果:顶部一个自定义的进度背景 view,下面挨着路口放大图 ImageView。
实现一
由于都是代码动态设置的,所以就不考虑 xml 了。设置背景首先想到的是 GradientDrawable,我们可以通过其 setCornerRadii 方法来指定 4 个圆角的弧度。float[] 的长度是 8 ,2 个一组,很灵活。最后通过 setBackgroundDrawable(Drawable background) 直接设置即可。
private GradientDrawable getBackground(boolean isNightMode) { int color; if (isNightMode) { color = Color.parseColor("#000000"); } else { color = Color.parseColor("#3C3F46"); } float radius = NaviUtil.dp2px(getContext(), 8); GradientDrawable drawable = new GradientDrawable(); drawable.setShape(GradientDrawable.RECTANGLE); drawable.setCornerRadii(new float[]{ radius, radius, radius, radius ,0, 0, 0, 0}); drawable.setColor(color); return drawable; }
实现二
可以将整个 view 通过裁剪画布的方式,在 onDraw方法中进行绘制。主要方法即 path.addRoundRect(…) ,代码见下:
private void drawClipPathOnCanval(Canvas canvas) { if(mClipPath == null){ mClipPath = new Path(); if(mClipRectF == null) mClipRectF = new RectF(0, 0 , CommentUtils.dip2px(mContext, 150) , CommentUtils.dip2px(mContext, 150)); // path为圆形矩形。裁剪圆形,弧等都同理 /* * RectF:矩形轮廓 * rx:圆角矩形的圆角的x半径 * ry:圆角矩形的圆角的y半径 * direction:cw:顺时针、CCW:逆时针 */ mClipPath.addRoundRect(mClipRectF , CommentUtils.dip2px(mContext, 15) , CommentUtils.dip2px(mContext, 15) , Path.Direction.CW); } canvas.clipPath(mClipPath); }
方法 addRoundRect(RectF, rx, ry, direction) 同时绘制 4 个角弧度是非常方便的,但如果只需绘制左上和左下两个弧角呢?所幸其还有带 float[] 参数的同载方法,可以灵活设置每个角的弧度,使用方法估计一看就明:
addRoundRect(RectF rect, float[] radii, Direction dir)
在对 canvas 进行裁剪前,我们需要锁定下画布,裁剪绘制完成之后,再恢复画布。在 onDraw方法见下:
// 锁定当前画布 canvas.save(); // 裁剪画布 drawClipPathOnCanval(canvas); // 正常绘制逻辑:这里包括绘制进度条等 // 恢复画布 canvas.restore();
实现三
如果对于进度值的精度要求不高,完全可能通过多边形 + 圆弧的方式来实现两个角的圆弧矩形。例如上图中的绿色进度实现,方法可以如下:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float currW = getWidth() * mProgress; if (currW < mRadus * 0.25) { return; } else if (currW <= mRadus) { currW = mRadus; } else if (currW > getWidth() - mRadus) { // 绘制右上角弧度 canvas.drawArc(getRect(getWidth() - 2 * mRadus, 0 , getWidth(), 2 * mRadus) , -90, 90 , true, mPbBgPaint); canvas.drawRect(getRect(getWidth() - mRadus, mRadus , getWidth(), mPbheight), mPbBgPaint); currW = getWidth() - mRadus; } // 绘制左上角弧度 canvas.drawArc(getRect(0, 0, mRadus * 2, mRadus * 2) , 180, 90 , true, mPbBgPaint); // 绘制多边形 mMorePath.moveTo(0, mPbheight); mMorePath.lineTo(0, mRadus); mMorePath.lineTo(mRadus, mRadus); mMorePath.lineTo(mRadus, 0); mMorePath.lineTo(currW, 0); mMorePath.lineTo(currW, mPbheight); mMorePath.close(); canvas.drawPath(mMorePath, mPbBgPaint); }
实现四
对于图片 Bitmap 的裁剪,我们也可以通过 path 来生成一个两个弧角的 Bitmap,方法见下:
public Bitmap getRoundedCornerBitmap(Bitmap bitmap, float[] rids) { try { Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444); Canvas canvas = new Canvas(output); final Paint paint = new Paint(); final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); final RectF rectF = new RectF(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight())); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); paint.setColor(Color.BLACK); Path path = new Path(); // float[] rids 可灵活设置每个角的弧度 path.addRoundRect(rectF , rids , Path.Direction.CW); canvas.drawPath(path, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); final Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); canvas.drawBitmap(bitmap, src, rect, paint); return output; } catch (OutOfMemoryError outOfMemoryError){ outOfMemoryError.printStackTrace(); return bitmap; }catch (Exception e) { TLog.e(TAG, TLog.USR, e); return bitmap; } }
更多相关文章
- android canvas画图 切割画布(clipRect)
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩
- Android 自定义View清除画布Canvas
- android 在画布上画图片
- Android绘制一条边为弧形的矩形
- Android shape实现订单卡片制作(shape画半圆及矩形圆角、渐变、虚
- drawRoundRect方法:绘制圆角矩形