Android自定义View描边圆角无效,内部圆角显示异常求助
搞定内部子View圆角不匹配的问题
嘿,我看了你的截图和代码,一眼就发现问题所在了:你给内部填充路径(fillpath)用了和描边路径一样的固定圆角半径15,但填充路径的矩形比描边的小一圈,这就导致内部圆角的弧度和外部描边对不上,出现你截图里的“内凹”问题。
下面给你几个实用的修复方案,挑适合你的来用:
方案一:手动适配填充路径的圆角半径
描边的圆角半径是15,而填充路径是向内偏移了strokeWidth + space的距离,所以填充路径的圆角半径应该减去这个偏移量,这样内外圆角的圆心才能对齐,弧度自然就匹配了。修改你的fillpath创建代码:
// 计算适配后的填充圆角半径,减去偏移量 float offset = strokeWidth + space; float fillRx = 15 - offset; float fillRy = 15 - offset; // 防止半径变成负数,做个兜底 fillRx = Math.max(fillRx, 0); fillRy = Math.max(fillRy, 0); Path fillpath = RoundedRect( strokeWidth + space, headHeight + strokeWidth + topOffset - space, mWidth - strokeWidth - space, mHeight - strokeWidth - space, fillRx, fillRy, true, true, true, true );
方案二:用画布裁剪实现自动贴合
如果你不想算来算去,直接用Canvas的裁剪功能更省心:先画好外部描边,然后用填充区域的路径裁剪画布,再画内部填充内容,这样内部内容会自动贴合裁剪后的圆角,完全不用纠结半径:
// 先绘制外部描边 canvas.drawPath(strokepath, paint); // 创建填充区域的路径(就是你原来的fillpath) Path clipPath = RoundedRect( strokeWidth + space, headHeight + strokeWidth + topOffset - space, mWidth - strokeWidth - space, mHeight - strokeWidth - space, 15, 15, true, true, true, true ); // 保存画布状态,开启裁剪 canvas.save(); canvas.clipPath(clipPath); // 直接画矩形就行,裁剪会帮我们切出圆角 canvas.drawRect( strokeWidth + space, headHeight + strokeWidth + topOffset - space, mWidth - strokeWidth - space, mHeight - strokeWidth - space, mViewPaint ); // 恢复画布原来的状态 canvas.restore();
方案三:用系统OutlineProvider(推荐,性能更好)
如果你的App最低兼容版本是Android 5.0(API 21)以上,强烈推荐用系统自带的OutlineProvider来实现圆角,不仅代码更简洁,性能也比手动画路径好:
// 在自定义View的构造方法或者onSizeChanged方法里设置 setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { // 设置整个View的圆角范围和半径 outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 15); } }); setClipToOutline(true); // 内部子View如果需要同样的圆角,要么也设置OutlineProvider,要么让它的大小刚好适配父View的内边距 // 外部描边可以通过设置带描边的ShapeDrawable作为背景来实现,更省心
另外,顺便提一句:你的RoundedRect方法里,计算widthMinusCorners和heightMinusCorners的时候,最好加个判断确保数值不为负,避免出现路径绘制异常的情况哦。
试试上面的方案,应该就能得到你想要的内外圆角完全匹配的效果啦!
内容的提问来源于stack exchange,提问作者Sagar Maiyad
相关产品推荐
相关产品推荐

