Search code examples
androidandroid-dialogfragmentrounded-corners

Android round corner layout in dialogfragment


I want to make a dialog fragment with corners. The problem I have

enter image description here

As you see, if a TextView in on top, there will be some parts of it that is over the transparent part of the dialog, which is bad. This also happens with that scrolling bar from the listview. I want to "cut" that parts..or mask them like in the second photo. Is this possible?

shape

    <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#FFF" />
    <corners android:topLeftRadius="20dp" android:topRightRadius="20dp"
        android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp"/>
    <stroke android:color="#7F7F7F" android:width="1dp" />
</shape>

I'm using a linear layout for the fragment, with the above background. I call

getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

To get rid of the background color & title bar.


Solution

  • The simple (non-clipping) way

    The easiest way would be to simply add padding to your layout. Then your text won't overlap with the rounded corners.

    If you must have rounded corners without padding, there are a few other options that I know of:

    Option 1: Clip Views (API 21+)

    Support for clipping views was added to the View class in API 21. If you don't need earlier API levels, it's really easy to use this in-built clip feature:

    • Set your rounded shape drawable as your layout background.
    • According to the documentation, you then just set the clip attribute in your layout XML to android:clipToOutline="true"

    Unfortunately, there's a bug and this attribute doesn't seem to work. Luckily, we can set the clipping in Java:

    • In your activity or fragment, just do: View.setClipToOutline(true)

    I've tested it, and it works:

    View Clipping ON View Clipping OFF

    Option 2: Nine-Patch frame mask

    If you need to support rounded clipping on devices < API 21, you can use this general approach:

    • Using a FrameLayout or RelativeLayout, create a rounded corner nine-patch to "frame" the rest of your content.
    • This nine-patch image should be transparent (alpha 0%), except for the corners, which should be opaque (alpha 100%).
    • Set the nine-patch as the background of a view, and place that view as the last child in the layout (this makes it stack on top of the other views).
    • Text will then display through the transparent nine-patch, but will be masked at the corners.

    If you use this approach, just make your nine-patch corners match the color of your background.