android – How to remove border from Dialog?-ThrowExceptions

Exception or error:

I have an activity which is shown in a dialog:

In order to remove border and rounded corners, i tried this:

<resources>
  <style name="ActivityDialog" parent="@android:style/Theme.Dialog">
  <item name="android:windowBackground">@null</item> 
    <item name="android:windowFrame">@null</item>
</style>

The border is gone, but sadly also the margin around the dialog.

How to solve:

The border, round corners and margin are all defined by android:windowBackground. (Parameter android:windowFrame is already set to @null in Theme.Dialog style, therefore setting it to @null again has no effect.)

In order to remove the border and round corners you have to change the android:windowBackground appropriately. The Theme.Dialog style sets it to @android:drawable/panel_background. Which is a 9-patch drawable that looks like this (this one is the hdpi version):

enter image description here

As you can see the 9-patch png defines the margin, border and round corners of the dialog theme. To remove the border and round corners you have to create an appropriate drawable. If you want to keep the shadow gradient you have to create set of new 9-patch drawables (one drawable for each dpi). If you don’t need the shadow gradient you can create a shape drawable.

The required style is then:

<style name="ActivityDialog" parent="@android:style/Theme.Dialog">      
   <item name="android:windowBackground">@drawable/my_custom_dialog_background</item>            
</style>

###

Without creating a custom background drawable and adding a special style just add one line to your code:

dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

###

I played around a bit with other possibilities but using a 9 patch with fixed margins and found out that the layer-list drawable is allowing to define offsets, hence margins around its enclosed drawables, so this worked for me:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:drawable="@drawable/my_custom_background"
        android:top="5dp" android:bottom="5dp" android:left="5dp" android:right="5dp">
    </item>

</layer-list>

and then you can use this as the “android:windowBackground”:

<style name="ActivityDialog" parent="@android:style/Theme.Dialog">      
   <item name="android:windowBackground">@drawable/my_custom_layer_background</item>            
</style>

###

Another option

Resources\Values\styles.xml

<style name="MessageDialog" parent="android:Theme.Holo.Light.Dialog">
   <item name="android:windowBackground">@android:color/transparent</item>
</style>

where

AlertDialog.Builder builder = new AlertDialog.Builder(Activity, Resource.Style.MessageDialog);            

These statements are excerpted from the following snippet:

public class MessageAlertDialog : DialogFragment, IDialogInterfaceOnClickListener
{
    private const string DIALOG_TITLE = "dialogTitle";
    private const string MESSAGE_TEXT = "messageText";
    private const string MESSAGE_RESOURCE_ID = "messageResourceId";

    private string _dialogTitle;
    private string _messageText;
    private int _messageResourceId;

    public EventHandler OkClickEventHandler { get; set; }

    public static MessageAlertDialog NewInstance(string messageText)
    {
        MessageAlertDialog dialogFragment = new MessageAlertDialog();

        Bundle args = new Bundle();
        args.PutString(MESSAGE_TEXT, messageText);

        dialogFragment.Arguments = args;

        return dialogFragment;
    }

    public static MessageAlertDialog NewInstance(string dialogTitle, string messageText)
    {
        MessageAlertDialog dialogFragment = new MessageAlertDialog();

        Bundle args = new Bundle();
        args.PutString(DIALOG_TITLE, dialogTitle);
        args.PutString(MESSAGE_TEXT, messageText);

        dialogFragment.Arguments = args;

        return dialogFragment;
    }

    public static MessageAlertDialog NewInstance(int messageResourceId)
    {
        MessageAlertDialog dialogFragment = new MessageAlertDialog();

        Bundle args = new Bundle();
        args.PutInt(MESSAGE_RESOURCE_ID, messageResourceId);

        dialogFragment.Arguments = args;

        return dialogFragment;
    }        

    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        _dialogTitle = Arguments.GetString(DIALOG_TITLE);
        _messageText = Arguments.GetString(MESSAGE_TEXT);
        _messageResourceId = Arguments.GetInt(MESSAGE_RESOURCE_ID);
    } 

    public override Dialog OnCreateDialog(Bundle savedInstanceState)
    {
        base.OnCreateDialog(savedInstanceState);

        AlertDialog.Builder builder = new AlertDialog.Builder(Activity, Resource.Style.MessageDialog);            

        if (_dialogTitle != null)
        {
            builder.SetTitle(_dialogTitle);
        }

        if (_messageText != null)
        {
            builder.SetMessage(_messageText);
        }
        else
        {
            View messageView = GetMessageView();
            if (messageView != null)
            {
                builder.SetView(messageView);
            }
        }

        builder.SetPositiveButton("OK", this);
               //.SetCancelable(false);            

        this.Cancelable = false;
        AlertDialog dialog = builder.Create();
        dialog.SetCanceledOnTouchOutside(false);
        //dialog.Window.SetBackgroundDrawableResource(Android.Resource.Color.Transparent);

        return dialog;            
    } 

    private View GetMessageView()
    {
        if (_messageResourceId != 0)
        {
            View messageView = Activity.LayoutInflater.Inflate(_messageResourceId, null);

            return messageView;
        }

        return null;
    }

    void IDialogInterfaceOnClickListener.OnClick(IDialogInterface di, int i)
    {
        OkClickEventHandler?.Invoke(this, null);
    }
}

Usage

public static void ShowMessageAlertDialog(FragmentManager fragmentManager, string dialogTitle, string messageText, EventHandler okClickEventHandler)
{
    MessageAlertDialog msgAlertDialog = MessageAlertDialog.NewInstance(dialogTitle, messageText);
    msgAlertDialog.OkClickEventHandler += okClickEventHandler;

    msgAlertDialog.Show(fragmentManager, "message_alert_dialog");
}

###

Another solution to this issue is to use android.support.v7.app.AlerDialog instead of android.app.AlertDialog. It’s the most easiest and time effective solution. Design you custom view in the layout and then use it with your support package’s AlertDialogBuilderclass and it will work like charm.

Leave a Reply

Your email address will not be published. Required fields are marked *