创建自定义凸路径Android

我希望为我的框架布局设置一个自定义形状(矩形的每个角的半径不同),以便框架布局中的视图将剪切到形状的边界.

    ViewOutlineProvider provider = new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                configurePath(getWidth(), getHeight());
                outline.setConvexPath(borderPath);
            }
        }
    };

    setOutlineProvider(provider);
    setClipToOutline(true);

configurePath()看起来像这样:

private void configurePath (int width, int height) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        return;
    }

    borderPath.rewind();

    float minSize = Math.min(width, height);
    float maxRadiusWidth = 2 * Math.max(Math.max(topLeftRadius, topRightRadius),
            Math.max(bottomLeftRadius, bottomRightRadius));

    if (minSize < maxRadiusWidth) {
        borderPath.addRect(0, 0, width, height, Path.Direction.CCW);
        return;
    }

    // Top left circle
    oval.set(0, 0, 2 * topLeftRadius, 2 * topLeftRadius);
    borderPath.moveTo(0, topLeftRadius);
    borderPath.arcTo(oval, 180, -90);

    borderPath.rLineTo(width - topLeftRadius - topRightRadius, 0);

    // Top right circle
    oval.set(width - 2 * topRightRadius, 0, width, 2 * topRightRadius);
    borderPath.arcTo(oval, 90, -90);

    borderPath.rLineTo(0, height - topRightRadius - bottomRightRadius);

    // Bottom right circle
    oval.set(width - 2 * bottomRightRadius, height - 2 * bottomRightRadius, width, height);
    borderPath.arcTo(oval, 0, -90);

    borderPath.rLineTo(-width + bottomRightRadius + bottomLeftRadius, 0);

    // Bottom left circle
    oval.set(0, height - 2 * bottomLeftRadius, 2 * bottomLeftRadius, height);
    borderPath.arcTo(oval, -90, -90);

    borderPath.rLineTo(0, -height + bottomLeftRadius + topLeftRadius);
}

当我运行它时,我得到java.lang.IllegalArgumentException:path必须是凸的,我无法进入native_isConvex()并看看它是如何决定路径是否凸出.

那么什么是凸路?为什么congfigurePath()中的路径不是凸的?
 如何创建自定义凸路径?谢谢.

最佳答案 我自己想通了.路径不凸,因为我没有正确绘制路径.实现我想要的多角半径效果的正确路径应该是:

    // Top left circle
    oval.set(0, 0, 2 * topLeftRadius, 2 * topLeftRadius);
    borderPath.moveTo(0, topLeftRadius);
    borderPath.arcTo(oval, -180, 90);

    borderPath.rLineTo(width - topLeftRadius - topRightRadius, 0);

    // Top right circle
    oval.set(width - 2 * topRightRadius, 0, width, 2 * topRightRadius);
    borderPath.arcTo(oval, -90, 90);

    borderPath.rLineTo(0, height - topRightRadius - bottomRightRadius);

    // Bottom right circle
    oval.set(width - 2 * bottomRightRadius, height - 2 * bottomRightRadius, width, height);
    borderPath.arcTo(oval, 0, 90);

    borderPath.rLineTo(-width + bottomRightRadius + bottomLeftRadius, 0);

    // Bottom left circle
    oval.set(0, height - 2 * bottomLeftRadius, 2 * bottomLeftRadius, height);
    borderPath.arcTo(oval, 90, 90);

    borderPath.rLineTo(0, -height + bottomLeftRadius + topLeftRadius);

更新:虽然现在路径正确,但它仍然不是凸路径,似乎自定义路径不会被视为凸路径.

点赞