Custom FragmentDialog with round corners and not 100% screen width

Dialog background: dialog_rounded_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/white" />
    <corners android:radius="12dp" />
</shape>

Dialog layout: dialog_rounded.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/dialog_rounded_bg"
    android:minWidth="260dp"
    android:orientation="vertical"
    android:padding="24dp">
    ...
</LinearLayout>

Dialog fragment: RoundedDialog.java

public class RoundedDialog extends DialogFragment {
    ...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.dialog_rounded, container, false);
        // Set transparent background and no title
        if (getDialog() != null && getDialog().getWindow() != null) {
            getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        }
        return view;
    }
    ...
}

Rounded dialog

Update: If you don't set the flag Window.FEATURE_NO_TITLE, a blue line appears on top of the dialog in devices with Android ≤ 4.4.


Well, I just found a solution, I am not really happy with it though.

I set the background (rounded_dialog.xml) for the dialog like this:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
<corners android:radius="10dp" />
<padding android:left="10dp" android:right="10dp"/>
</shape>

Then I set this to my dialog in its ´onCreateView´ method this way below. The rounded corners are not really necessary in this piece of code as the background is transparent, but the padding is important, because the dialog is still in fact as wide as the screen, but the padding makes it look like it is not.

getDialog().getWindow().setBackgroundDrawableResource(R.drawable.rounded_dialog);

And in the end I set background of the dialog´s components to another custom drawable which makes the corners round. I have a LinearLayout with RelativeLayout at the top and TextView at the bottom, so I set @null to the parent LinearLayout and set two different custom drawables to the two parts, one of which has rounded bottomCorners and the other one topCorners.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" 
android:background="@drawable/title_round"  
>

<RelativeLayout
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"        
    android:orientation="horizontal" 
    android:background="@drawable/blue_title_round_top"
    android:paddingTop="4dp"
    android:paddingBottom="4dp"
    >
<TextView 
    android:id="@+id/calendarHint"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/rounded_bottom"
    android:layout_gravity="center"
    android:gravity="center"
        />
</LinearLayout>

I believe there is a more proper solution to this as this is correct just visually, not really functionally, but enough correct for this case.


Updated 2022 answer with Kotlin and View Binding -

class InternetLostDialog : DialogFragment() {

    private lateinit var binding: DialogInternetLostBinding

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        binding = DialogInternetLostBinding.inflate(LayoutInflater.from(context))
        val builder = AlertDialog.Builder(requireActivity())
        isCancelable = false
        builder.setView(binding.root)
        binding.root.setOnClickListener {
            requireActivity().finish()
        }
        val dialog = builder.create()
        dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        return dialog
    }

}