web-dev-qa-db-ja.com

Android XMLの丸いクリップコーナー

LinearLayoutを次の描画可能な背景で設定しました。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <corners Android:radius="10dp" />
    <solid Android:color="#CCFFFFFF"/>
</shape>

私が抱えている問題は、LinearLayout内にあります。その親の下部にある別のLinearLayout要素があります。丸みを帯びた角がないため、その角は親の左下と右下の角を超えて伸びています。

Child LinearLayoutの描画可能な背景は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:Android="http://schemas.Android.com/apk/res/Android" 
    Android:src="@drawable/pedometer_stats_background" 
    Android:tileMode="repeat"   
/>

問題は次のようになります。 http://kttns.org/hn2zm デバイスでは、クリップされていないことがより明確になります。

クリッピングを達成するための最良の方法は何ですか?

27
Emily Laguna

あなたの説明はこのように聞こえますか:

<LinearLayout Android:shape="rounded">
   <LinearLayout Android:background="@drawable/pedometer_stats_background">
   </LinearLayout>
</LinearLayout>

また、内側のレイアウトは丸められていないため、丸みを帯びたコーナーの外側に押し出されています。ビットマップの角を丸くする必要があります。繰り返しビットマップがある場合は、9パッチのドローアブルの定義を確認する必要があります。角を丸め、拡大できるグラフィックの部分を定義します。

http://developer.Android.com/guide/topics/resources/drawable-resource.html#Shape

ドローアブルの形状にビットマップを追加し、それを描画している任意の形状のスキンとして適用できればいいのですが。また、ビットマップを描画するShapeサブクラスを作成できることをご存知であれば、残念ながら、それはAndroidには含まれていません。

7
chubbsondubs

2018年更新

過去7年間で多くの変化がありました。

最近、このタイプのレイアウトを処理する最良の方法は、角の丸いサポートと他の多くの新しいUI機能のサポートが組み込まれているCardViewを使用することです。

cardCornerRadiusプロパティを適用して、角を丸めるように設定します。

<Android.support.v7.widget.CardView
    .......
    app:cardCornerRadius="16dp">

</Android.support.v7.widget.CardView>

オリジナル

背景が灰色のiPhoneスタイルの丸みのあるレイアウトが必要でした。 (ため息-常にiPhoneをコピーする)

レイアウトをマスクする方法を見つけることができずにイライラしました。ここでの答えのほとんどは、背景画像を使用することですが、これは私が必要とするものではありません。


編集FrameLayoutを使用してAndroid:foregroundドローアブルを設定することを提案した以前の回答。これにより、ビューに奇妙なパディングが導入されました。より簡単なRelativeLayoutテクニックを使用するように回答を更新しました。


コツは、RelativeLayoutを使用することです。その中にレイアウトを配置します。レイアウトの下に別のImageViewを追加し、そのbackgroundを適切なマスキングイメージフレームに設定します。これにより、他のレイアウトの上に描画されます。

私の場合、灰色の背景で、丸みを帯びた透明な長方形が切り取られた9Patchファイルを作成しました。

frame

これにより、基本的なレイアウトに最適なマスクが作成されます。

XMLコードは次のとおりです-これは通常のレイアウトXMLファイルです。

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_height="wrap_content" Android:layout_width="fill_parent">

    <!-- this can be any layout that you want to mask -->
    <LinearLayout Android:id="@+id/mainLayout"
        Android:layout_height="wrap_content"
        Android:layout_width="fill_parent" Android:orientation="vertical"
        Android:background="@Android:color/white">

        <TextView Android:layout_height="wrap_content"
            Android:layout_width="wrap_content" Android:layout_gravity="center"
            Android:text="Random text..." />

    </LinearLayout>

    <!-- FRAME TO MASK UNDERLYING VIEW -->
    <ImageView Android:layout_height="fill_parent" 
        Android:layout_width="fill_parent" 
        Android:background="@drawable/grey_frame"
        Android:layout_alignTop="@+id/mainLayout"
        Android:layout_alignBottom="@+id/mainLayout" />

</RelativeLayout>

下にあるImageViewに注目してください。メインのレイアウトに上と下が揃っており、マスキング画像が設定されています。

  • Android:background="@drawable/grey_frame"

これは私の9Patchファイルを参照し、フォアグラウンドで描画されることにより、下にあるレイアウトをマスクします。

これは、標準レイアウトの灰色の丸い角を示す例です。

maskedLayout

hth

31

APIレベル21(Lollipop)が追加されました View.setClipToOutline 。 Androidに関するドキュメント シャドウとクリッピングビューの定義 から:

ビューをドローアブルの形状にクリップするには、ビューの背景としてドローアブルを設定し、... View.setClipToOutline()メソッドを呼び出します。

親ビューの背景をコーナー半径のあるGradientDrawableに設定することでこれをテストし、子ビューは親の同じ丸い角に一致するように正しくトリミングされます。

7
Elizabeth Amato