2017-04-19 8 views
2

フレームレイアウト内のビューがシェイプの境界にクリップするように、カスタムシェイプ(四角形の各隅に異なる半径)をフレームレイアウトに設定します。カスタムコンベアパスを作成する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 must be convexを持って、私はnative_isConvex()に入るとパスが凸状である場合、それはどのように決定するか見ることができませんでした。

したがって、凸のパスとは何ですか? congfigurePath()のパスが凸ではないのはなぜですか? カスタム凸曲線を作成するにはどうすればよいですか?ありがとうございました。

+0

同じ問題に直面しています。今のところ、 'lineTo'メソッドだけを使うとき、' isConvex'は 'true'を返すことができます。 'quadTo'または' arcTo'を使うと、 'isConvex'は' false'を返します。おそらく、これはいくつかのヒントになる可能性があります... – pxsx

+0

@pxsxYeah、 'arcTo'は私が問題の原因と思ったものです。しかし、私はビューグループのカスタムシェイプを作成する予定だったので、それを使用する必要があります。とにかく、clipPathを使ってカスタムシェイプの問題を解決しました。 –

答えて

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

更新日:パスが正しいですが、それは、まだ凸パスではありませんカスタマイズされたパスが凸パスとして扱われることはありませんように思えます。

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よりも膨らんでしまうものです。
カーストラスタでは、外側の角の半径、線の太さ、内側の角の半径を渡します。ソースを見て、パスの作成方法を確認することもできます(ヒント:path.addRoundRect())。

+1

'addRoundRect(RectF rect、float [] radius、Direction dir)'について教えていただきありがとうございます。しかし、アウトラインのソースコードによると、 'public boolean canClip(){ return mMode!= MODE_CONVEX_PATH; } 'アウトラインはカスタムシェイプのクリッピングをサポートしていません –

関連する問題