Custom FragmentDialog with round corners and not 100% screen width
Asked Answered
O

9

69

I am creating a custom fragment dialog with round corners and with layout that would not fill the screen width (I would prefer if it just wrapped its content).

this is my rounded_dialog.xml in drawable folder, which is called by my Custom ThemeWithCorners as a background for the dialog. I also tried to set it as background to the linear layout which creates its content but nothing works.

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" 
>
<solid android:color="@android:color/white"/>
<corners android:radius="20dp"
/>
</shape>

and this is how i call the dialog:

final String FTAG = "TAG_FRAGMENT_DIALOG_CALENDAR";
    dialog = (CalendarDialog) fm.findFragmentByTag(FTAG);
    ft = fm.beginTransaction();
    if (dialog != null)
    {
        ft.remove(dialog);
    }
    dialog = CalendarDialog.newInstance(this);      
    dialog.setCancelable(true);

    ft.add(dialog, FTAG);
    ft.show(dialog);
    ft.commit();

In onCreate method of the dialog I set the style and theme:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_TITLE, R.style.ThemeWithCorners);      
}

This is the onCreateView method:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
getDialog().setCanceledOnTouchOutside(true);
v = (MyCalendar)inflater.inflate(R.layout.calendar_dialog, container, true)
    return v;
}

I also tried to add this to onCreateDialog method as other answers on SO suggested but did not work either:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
    Dialog d =  super.onCreateDialog(savedInstanceState);
    LayoutParams lp=d.getWindow().getAttributes();
    d.getWindow().setBackgroundDrawable(new ColorDrawable(0));
    lp.width=-2;lp.height=-2;lp.gravity=Gravity.CENTER;
    lp.dimAmount=0;            
    lp.flags=LayoutParams.FLAG_LAYOUT_NO_LIMITS | LayoutParams.FLAG_NOT_TOUCH_MODAL;

    return d;
}

So to sum it up, I want round corners, not 100% width of the screen, it preferably should wrap its content. Please, please, I need some help, I am really desperate about this, I´v ebeen trying it for days!

Outclass answered 14/3, 2013 at 22:18 Comment(0)
O
59

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.

Outclass answered 15/3, 2013 at 0:23 Comment(0)
W
146

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.

Woolsack answered 4/7, 2017 at 18:23 Comment(3)
What font have you used in the dialog?Audette
It's a custom font (Maison Neue).Woolsack
This solution also worked with ConstraintLayout instead of a LinearLayout.Calamint
O
59

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.

Outclass answered 15/3, 2013 at 0:23 Comment(0)
D
9

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
    }

}
Dragonroot answered 23/8, 2020 at 8:32 Comment(0)
R
4

Another way:
Use setStyle() in onCreate() method to apply a style to your DialogFragment.
Then, you can use android:background same as always in the root view of your_layout.xml file.


Steps:

  1. style.xml file (in res folder) :
<style name="DialogTheme_transparent" parent="Theme.AppCompat.Dialog">
    <item name="android:windowBackground">@android:color/transparent</item>
    <!--You can set other style items also, such as animations and etc-->
</style>
  1. Create your_layout.xml file in the layout folder:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="8dp"
    android:background="@drawable/bg_corner_dialog">
    ...
</LinearLayout>
  1. Create bg_corner_dialog.xml file in the drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    android:dither="true">
    <solid android:color="#ffffff"/>
    <corners android:radius="16dp"/>
</shape>
  1. Finally apply style and layout to the your DialogFragment:
public class CustomDialogFragment extends DialogFragment {
    ...

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, R.style.DialogTheme_transparent);
        ...
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.your_layout, container, false);
        ButterKnife.bind(this, v);
        //init UI Elements...
        return v;
    }

}

I hope this helps you.
Best wishes

Russel answered 10/10, 2019 at 19:47 Comment(0)
T
3

There is a quick fix for DialogFragment. For example, in the method onCreateDialog() add style in AlertDialog.Builder(context, style):

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    View view = LayoutInflater.from(getActivity()).inflate(R.layout.custom_dialog_lauout, null);
    return new AlertDialog.Builder(getActivity(), R.style.custom_alert_dialog)
            .setView(view)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int i) {
                    // do something
                }
            })
            .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            })
            .create();
}

In styles folder custom_alert_dialog

<style name="custom_alert_dialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:windowBackground">@drawable/corner_background</item>
</style>

In drawable folder corner_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:radius="8dp" />

enter image description here

It's tested for API >= 21

Thralldom answered 7/2, 2022 at 18:4 Comment(0)
I
2

An updated solution that works for me using Kotlin.

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

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

then calculating the screen width programmatically then subtract the Margin value from it, using this code snippet.

val displayMetrics = DisplayMetrics()
        requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
        val width = displayMetrics.widthPixels

then inside onStart callback I applied that width minus Margin. here is the full code.

@AndroidEntryPoint
class CancelDialogFragment : DialogFragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        if (dialog != null && dialog?.window != null) {
            dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
            dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE);
        }
        return inflater.inflate(R.layout.fragment_cancel_dialog, container, false)
    }

    override fun onStart() {
        super.onStart()
        val displayMetrics = DisplayMetrics()
        requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)

        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels

        dialog?.window?.setLayout(width-64, ViewGroup.LayoutParams.WRAP_CONTENT)
    }


}

XML Layout fragment_cancel_dialog

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingVertical="32dp"
    android:padding="8dp"
    android:layout_marginHorizontal="8dp"
    android:background="@drawable/rounded_dialog"
    tools:context=".ui.orders.CancelDialogFragment">


    <TextView
        android:id="@+id/textView9"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Reason of cancellation"
        android:textSize="16sp"
        app:layout_constraintStart_toStartOf="@+id/firstNameTIL"
        app:layout_constraintTop_toTopOf="parent" />


    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/firstNameTIL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="24dp"
        android:layout_marginTop="16dp"
        app:hintAnimationEnabled="false"
        app:hintEnabled="false"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView9">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/firstNameET"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/edit_text_bg"
            android:drawablePadding="12dp"
            android:inputType="textPersonName"
            android:paddingHorizontal="16dp"
            android:paddingVertical="16dp"
            android:textAlignment="viewStart"
            android:textColor="@color/textColor"
            android:textColorHint="@color/black" />
    </com.google.android.material.textfield.TextInputLayout>


    <Button
        android:id="@+id/signUpButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="32dp"
        android:background="@drawable/button_bg"
        android:paddingHorizontal="56dp"
        android:text="@string/confirmStr"
        android:textAllCaps="false"
        android:inputType="text"
        android:textColor="@color/black"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/firstNameTIL" />


</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

Inconformity answered 14/5, 2021 at 21:13 Comment(0)
I
1

For Any One who wants to Use the AlertDialogBuilder and transparent the background and set the Drawable in XML file.

<style name="DialogStyle" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">

<item name="android:background">@drawable/dialog_background</item>
<item name="android:windowBackground">@android:color/transparent</item>

Set this Theme on Builder like below

private val builder: AlertDialog.Builder = AlertDialog.Builder(context,R.style.DialogStyle)
    .setView(dialogView)

where R.drawable.dialog_background is:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape android:shape="rectangle" android:padding="10dp">
            <solid
                android:color="@color/dialog_bg_color"/>
            <corners
                android:radius="30dp" />
        </shape>
    </item>
</layer-list>
Institute answered 29/12, 2021 at 10:44 Comment(0)
A
0

I think to make rounded corners, its much easier if u make cardview as the root of your layout and add below code in onCreateView(): alertDialog.getWindow().setBackgroundDrawableResource(android.R.color.transpare‌​nt)

Adriell answered 17/6, 2020 at 9:7 Comment(1)
it doesnt work for me, has no effect on dialog displayedAegean
R
0

This is an old question and it misses the simplest way of achieving rounded edges in a DialogFragment component. You can achieve this with one liner:

override fun getTheme() = R.style.RoundedCornersDialog
Revivalism answered 8/7, 2022 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.