创建一个的正确方法ViewGroup
剪辑它的孩子是在dispatchDraw(Canvas)
method.
这是一个关于如何剪辑 a 的任何子项的示例ViewGroup
带圆圈:
private Path path = new Path();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// compute the path
float halfWidth = w / 2f;
float halfHeight = h / 2f;
float centerX = halfWidth;
float centerY = halfHeight;
path.reset();
path.addCircle(centerX, centerY, Math.min(halfWidth, halfHeight), Path.Direction.CW);
path.close();
}
@Override
protected void dispatchDraw(Canvas canvas) {
int save = canvas.save();
canvas.clipPath(circlePath);
super.dispatchDraw(canvas);
canvas.restoreToCount(save);
}
the dispatchDraw
方法是用于剪辑子项的方法。无需setWillNotDraw(false)
如果你的布局只是剪辑它的子元素。
这张图片是用上面的代码获得的,我只是扩展了FacebookProfilePictureView
(这是一个FrameLayout
包括一个正方形ImageView
与 Facebook 个人资料图片):
因此,要实现圆形边框,您可以执行以下操作:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// compute the path
path.reset();
rect.set(0, 0, w, h);
path.addRoundRect(rect, radius, radius, Path.Direction.CW);
path.close();
}
@Override
protected void dispatchDraw(Canvas canvas) {
int save = canvas.save();
canvas.clipPath(path);
super.dispatchDraw(canvas);
canvas.restoreToCount(save);
}
您实际上可以创建任何复杂的路径:)
请记住,您可以使用“Op”操作多次调用clipPath,以按照您喜欢的方式交叉多个剪辑。
注意:我在中创建了路径onSizeChanged
因为这样做是在onDraw
对性能不利。
注意2:剪切路径是在没有抗锯齿的情况下完成的:/所以如果你想要平滑的边框,你需要以其他方式来完成。我现在不知道有任何方法可以使剪辑使用抗锯齿功能。
更新(大纲)
由于 Android Lollipop (API 21),标高和阴影可以应用于视图。一个新概念叫做Outline https://developer.android.com/reference/android/graphics/Outline.html已被介绍。这是一条告诉框架要使用的视图形状的路径计算阴影 https://developer.android.com/training/material/shadows-clipping.html#Shadows和其他事情(比如连锁反应).
默认Outline
视图的大小是视图大小的矩形,但可以轻松制作为椭圆形/圆形或圆角矩形。定义一个自定义Outline
你必须使用该方法setOutlineProvider() https://developer.android.com/reference/android/view/View.html#setOutlineProvider(android.view.ViewOutlineProvider)在视图上,如果它是自定义视图,您可能需要在构造函数中使用您的自定义设置它ViewOutlineProvider
定义为自定义视图的内部类。您可以定义自己的Outline
提供商使用Path
您的选择,只要它是凸路径 https://en.wikipedia.org/wiki/Convex_hull(数学概念意味着没有凹槽和孔的闭合路径,例如星形和齿轮形状都不是凸形的)。
您还可以使用该方法setClipToOutline(true) https://developer.android.com/reference/android/view/View.html#setClipToOutline(boolean)使轮廓也剪辑(我think这也适用于抗锯齿,有人可以在评论中确认/反驳吗?),但这仅支持非Path
大纲。
祝你好运