创建自定义凸路径Android

时间:2017-04-19 21:31:08

标签: android

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

<div style="width: 200px; background-color: #bf8f42; opacity: 0.8; margin: auto; margin-top: 50px; padding: 10px;">View Flash Perks

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 must be convex,看看它是如何决定路径是否凸出。

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

2 个答案:

答案 0 :(得分:1)

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

    // 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);

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

答案 1 :(得分:0)

很高兴您使用它,但有内置工具。
最简单的是可绘制的xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:bottomLeftRadius="8dp"
        android:topLeftRadius="8dp"
        android:topRightRadius="8dp"
        android:bottomRightRadius="0dp" />

    <solid android:color="#fff" />

</shape>

以编程方式,您可以使用RoundRectShape类。这也是从xml上面膨胀的东西 在curstructor中,您传递外角半径,线宽和内角半径。您还可以查看源代码以了解它们如何创建路径(提示:path.addRoundRect())。