November 24, 2015

Custom AlertDialog example in Xamarin.Android

In Brief:
In this post i will discuss about one of the basic and most widely used component in an android development called customized alert dialog. There are several way of implementing it, here i will show custom alertDialog creation using "DialogFragment method" and "Layout inflation to AlertDialog".


In detail:
Even though both "Dialog fragment" and "Direct layout inflation" provides the same outlook,it is left to developer to choose according to the programming requirements. Let us see the implementation of both the methods in the following steps.

1.Custom AlertDialog using layout inflation in xamarin.android

Step 1.) Define layout for alert dialog.
In this example, i have taken login popup window scenario as follows.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minWidth="25px"
    android:minHeight="25px"
    android:background="#ff80d8ff">
    <TextView
        android:id="@+id/titleLogin"
        android:layout_height="32dp"
        android:layout_width="match_parent"
        android:text="@string/Login"
        android:textSize="20dp"
        android:textColor="#FFFFFF"
        android:paddingTop="4dp"
        android:background="#ff40c4ff"
        android:typeface="sans"
        android:textStyle="bold"
        android:gravity="center" />
    <TextView
        android:id="@+id/lblUsername"
        android:layout_below="@+id/titleLogin"
        android:layout_height="25dp"
        android:layout_width="170dp"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="20dp"
        android:text="@string/Username"
        android:textColor="#000000"
        android:textSize="14dp"
        android:paddingLeft="5dp"
        android:paddingTop="2dp"
        android:typeface="sans" />
    <EditText
        android:inputType="textEmailAddress"
        android:id="@+id/txtUsername"
        android:layout_below="@+id/lblUsername"
        android:layout_height="28dp"
        android:layout_width="match_parent"
        android:layout_marginLeft="20dp"
        android:background="@drawable/RoundedCorner"
        android:hint="@string/Username"
        android:textColorHint="@android:color/darker_gray"
        android:textColor="@android:color/black"
        android:paddingLeft="5dp"
        android:paddingTop="1dp"
        android:textSize="14dp"
        android:paddingBottom="1dp"
        android:typeface="sans"
        android:layout_marginRight="20dp" />
    <TextView
        android:id="@+id/lblPassword"
        android:layout_below="@+id/txtUsername"
        android:layout_height="25dp"
        android:layout_width="170dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:text="@string/Password"
        android:textColor="#000000"
        android:textSize="14dp"
        android:paddingLeft="5dp"
        android:paddingTop="2dp"
        android:typeface="sans" />
    <EditText
        android:id="@+id/txtPassword"
        android:layout_below="@+id/lblPassword"
        android:inputType="textPassword"
        android:layout_height="28dp"
        android:layout_width="match_parent"
        android:layout_marginLeft="20dp"
        android:background="@drawable/RoundedCorner"
        android:hint="@string/Password"
        android:textColorHint="@android:color/darker_gray"
        android:textColor="@android:color/black"
        android:paddingLeft="5dp"
        android:paddingTop="1dp"
        android:textSize="14dp"
        android:paddingBottom="1dp"
        android:typeface="sans"
        android:layout_marginRight="20dp" />
    <LinearLayout
        android:id="@+id/linearLayoutBtns"
        android:layout_below="@+id/txtPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp">
        <Button
            android:id="@+id/btnLoginLL"
            android:layout_width="125dp"
            android:layout_height="35dp"
            android:textSize="14dp"
            android:text="@string/Login"
            android:typeface="sans"
            android:background="#ff0986be"
            android:textColor="#ffffffff"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_marginBottom="5dp" />
        <Button
            android:id="@+id/btnClearLL"
            android:layout_width="125dp"
            android:layout_height="35dp"
            android:textSize="14dp"
            android:text="@string/Cancel"
            android:typeface="sans"
            android:background="#ff0986be"
            android:layout_marginLeft="5dp"
            android:textColor="#ffffffff"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_marginBottom="5dp" />
    </LinearLayout>
</RelativeLayout>

Step 2.) Build the alert dialog by Inflating the above created layout.
2.1)Inflate the layout to get view.
2.2)Instantiate the AlertDialog class by passing activity instance to builder constructor.
2.3)Set view to builder
2.4)Customize builder using options like SetIcon(),SetCustomTitle(),SetFeatureDrawableAlpha() etc..
2.5)Show the builder and close by using method Dismiss().


Here Dialog class is a base class for an AlerDialog class. AlertDialog class constructor Builder() is used to create builder for an alert dialog with default theme.
  void fnShowCustomAlertDialog()
  {
     //Inflate layout
     View view = LayoutInflater.Inflate ( Resource.Layout.DialogFragmentLayout ,null);
     AlertDialog builder = new AlertDialog.Builder (this).Create();
     builder.SetView (view);
     builder.SetCanceledOnTouchOutside(false);
     Button button = view.FindViewById<Button> (Resource.Id.btnClearLL);
     button.Click += delegate { 
     builder.Dismiss();
     Toast.MakeText(this ,"Alert dialog dismissed!" , ToastLength.Short).Show();
   }; 
   builder.Show ();
  }

2.Custom AlertDialog using Dialog fragment in Xamarin.Android.

To create a DialogFragment need to inherit from the class android.app.DialogFragment. This is very much similar to the any Fragment operation with all the Available Fragment life cycle methods.

Step 1). Define the Custom layout for Dialog fragment.
Same as the above layout with login window example.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minWidth="25px"
    android:minHeight="25px"
    android:background="#ff80d8ff">
    <TextView
        android:id="@+id/titleLogin"
        android:layout_height="32dp"
        android:layout_width="match_parent"
        android:text="@string/Login"
        android:textSize="20dp"
        android:textColor="#FFFFFF"
        android:paddingTop="4dp"
        android:background="#ff40c4ff"
        android:typeface="sans"
        android:textStyle="bold"
        android:gravity="center" />
    <TextView
        android:id="@+id/lblUsername"
        android:layout_below="@+id/titleLogin"
        android:layout_height="25dp"
        android:layout_width="170dp"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="20dp"
        android:text="@string/Username"
        android:textColor="#000000"
        android:textSize="14dp"
        android:paddingLeft="5dp"
        android:paddingTop="2dp"
        android:typeface="sans" />
    <EditText
        android:inputType="textEmailAddress"
        android:id="@+id/txtUsername"
        android:layout_below="@+id/lblUsername"
        android:layout_height="28dp"
        android:layout_width="match_parent"
        android:layout_marginLeft="20dp"
        android:background="@drawable/RoundedCorner"
        android:hint="@string/Username"
        android:textColorHint="@android:color/darker_gray"
        android:textColor="@android:color/black"
        android:paddingLeft="5dp"
        android:paddingTop="1dp"
        android:textSize="14dp"
        android:paddingBottom="1dp"
        android:typeface="sans"
        android:layout_marginRight="20dp" />
    <TextView
        android:id="@+id/lblPassword"
        android:layout_below="@+id/txtUsername"
        android:layout_height="25dp"
        android:layout_width="170dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:text="@string/Password"
        android:textColor="#000000"
        android:textSize="14dp"
        android:paddingLeft="5dp"
        android:paddingTop="2dp"
        android:typeface="sans" />
    <EditText
        android:id="@+id/txtPassword"
        android:layout_below="@+id/lblPassword"
        android:inputType="textPassword"
        android:layout_height="28dp"
        android:layout_width="match_parent"
        android:layout_marginLeft="20dp"
        android:background="@drawable/RoundedCorner"
        android:hint="@string/Password"
        android:textColorHint="@android:color/darker_gray"
        android:textColor="@android:color/black"
        android:paddingLeft="5dp"
        android:paddingTop="1dp"
        android:textSize="14dp"
        android:paddingBottom="1dp"
        android:typeface="sans"
        android:layout_marginRight="20dp" />
    <LinearLayout
        android:id="@+id/linearLayoutBtns"
        android:layout_below="@+id/txtPassword"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp">
        <Button
            android:id="@+id/btnLoginLL"
            android:layout_width="125dp"
            android:layout_height="35dp"
            android:textSize="14dp"
            android:text="@string/Login"
            android:typeface="sans"
            android:background="#ff0986be"
            android:textColor="#ffffffff"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_marginBottom="5dp" />
        <Button
            android:id="@+id/btnClearLL"
            android:layout_width="125dp"
            android:layout_height="35dp"
            android:textSize="14dp"
            android:text="@string/Cancel"
            android:typeface="sans"
            android:background="#ff0986be"
            android:layout_marginLeft="5dp"
            android:textColor="#ffffffff"
            android:textStyle="bold"
            android:gravity="center"
            android:layout_marginBottom="5dp" />
    </LinearLayout>
</RelativeLayout>

Step 2.) Prepare DialogFragment class.
2.a) Create class (DialogFragmentSample) by deriving from DialogFragment base class.
2.b) Override Fragment life cycle method OnCreateView() to attach dialog layout.
2.c) Alternatively you can override OnCreateDialog() method to return a Dialog instance with above(method 1)alert dialog code.
2.d) Return customized view and use Dismiss() to close popup.

using Android.App; 
using Android.OS; 
using Android.Views;
using Android.Widget;

namespace CustomAlertAndroid
{
 public class DialogFragmentSample : DialogFragment
 { 
  public static DialogFragmentSample NewInstace(Bundle bundle)
  {
   var fragment = new DialogFragmentSample ();
   fragment.Arguments = bundle;
   return fragment;
  } 
  public override View OnCreateView ( LayoutInflater inflater , ViewGroup container , Bundle savedInstanceState )
  {
        //return customview for the fragment
   View view=inflater.Inflate(Resource.Layout.DialogFragmentLayout,container,false);   
   Button button = view.FindViewById<Button> (Resource.Id.btnClearLL);
   Dialog.Window.RequestFeature ( WindowFeatures.NoTitle ); //remove title area
   Dialog.SetCanceledOnTouchOutside (false); //dismiss window on touch outside

   button.Click += delegate { 
    Dismiss();
    Toast.MakeText(Activity ,"Dialog fragment dismissed!" , ToastLength.Short).Show();
   }; 
   return view;
  }
 }
}
Step 3.): Instantiate the Fragment class from activity class to display the dialog.
   FragmentTransaction fragmentTransaction = FragmentManager.BeginTransaction ();
  //remove fragment from backstack if any exists
  Fragment fragmentPrev =FragmentManager.FindFragmentByTag("dialog");
  if ( fragmentPrev != null )
   fragmentTransaction.Remove ( fragmentPrev ); 

  fragmentTransaction.AddToBackStack ( null );
  //create and show the dialog
  DialogFragmentSample dialogFragment= DialogFragmentSample.NewInstace(null); 
  dialogFragment.Show ( fragmentTransaction , "dialog" );
Output screen:

FinalTouch:  Custom AlertDialog is useful whenever app need to display the messages like successful operation,error message or any status information with an attractive UI instead of default dialog box. 
Write back for any suggestions/errors. Thank you :)