'Custom FragmentDialog with round corners and not 100% screen width
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!
Solution 1:[1]
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;
}
...
}
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.
Solution 2:[2]
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
}
}
Solution 3:[3]
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:
- 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>
- Create
your_layout.xmlfile 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>
- Create
bg_corner_dialog.xmlfile 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>
- Finally apply
styleandlayoutto the yourDialogFragment:
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
Solution 4:[4]
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>
Solution 5:[5]
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)
Solution 6:[6]
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 is R.drawable.dialog_background
<?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>
Solution 7:[7]
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" />
It's tested for API >= 21
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Ghasem Sadeghi |
| Solution 4 | Mohamed AbdelraZek |
| Solution 5 | Muhammed Ashraf |
| Solution 6 | waheed shah |
| Solution 7 |



