Search code examples
xamarinxamarin.androidmvvmcrossandroid-alertdialog

How to change MvxDialogFragment layout


I want to change the default AlertDialog layout size.

I created class:

public class SampleDialog : MvxDialogFragment
{
    public override Dialog OnCreateDialog(Bundle savedInstanceState)
    {
        var dialog = new AlertDialog.Builder(Context);
        dialog.SetView(View.Inflate(Context,Resource.Layout.SampleDialog,null));

        return dialog.Create();
    }

    public override void OnStart()
    {
        if (Dialog == null) { return; }

        Dialog.Window.SetLayout(200,460);
        base.OnStart();
    }
}

and it's layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/text1" />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/text2" />
</LinearLayout>

And i'm creating dialog from fragment view:

var dialog = new SampleDialog
{
    ViewModel = ViewModel,
    Cancelable = true
};

dialog.Show(FragmentManager, "");

Tryed to set layout width in OnCreateDialog method,OnStart, or directly by setting LinearLayout.layout_width property, but the result is the same.

How this can be configured?


Solution

  • Inflating the layout

    When inflating the layout you can make use of either the default inflator or Mvvmcross BindingInflate which will apply any xml bindings you require.

    Default inflator:

    public override Dialog OnCreateDialog(Bundle savedInstanceState)
    {
        base.EnsureBindingContextSet(savedInstanceState);
    
        var dialog = new AlertDialog.Builder(Context);
        dialog.SetView(Activity.LayoutInflater.Inflate(Resource.Layout.SampleDialog, null));
    
        return dialog.Create();
    }
    

    Mvvmcross xml binding inflator:

    public override Dialog OnCreateDialog(Bundle savedInstanceState)
    {
        base.EnsureBindingContextSet(savedInstanceState);
    
        var dialog = new AlertDialog.Builder(Context);
        dialog.SetView(this.BindingInflate(Resource.Layout.SampleDialog, null));
    
        return dialog.Create();
    }
    

    Sizing the layout

    The Dialog.Window.SetLayout() takes in the pixel values for 200(width) and 460(height) which will vary in physical size with different device screen resolutions.

    A better approach would be to use dp and convert it to pixels:

    Add the desired size dimensions to your dimens.xml

    <resources>
        <dimen name="dialog_width">400dp</dimen>
        <dimen name="dialog_height">200dp</dimen>
    </resources>
    

    Update your SampleDialog

    public override void OnStart()
    {
        base.OnStart();
    
        var width = Resources.GetDimension(Resource.Dimension.dialog_width);
        var height = Resources.GetDimension(Resource.Dimension.dialog_height);
    
        Dialog.Window.SetLayout((int)width, (int)height);
    }