Fragments: DialogFragment en Android

Buenas tardes, en esta entrada vamos a ver otro tipo de Fragment, el denominado DialogFragment.


Un DialogFragment es un fragment que flota en el centro de nuestra actividad. Son útiles a la hora de necesitar que el usuario responda a algo para continuar con la ejecución. Para crear un DialogFragment, tenemos que heredar de la clase base DialogFragment.

Con esta pequeña introducción vamos a ponernos manos a la obra:

  • Creación del Proyecto

    Para crear nuestro proyecto vamos a ir a New -> File -> Android Application Project. Si no nos apareciera la opción “Android Application Project” podemos ir a “Other”, y en la lista que nos aparecerá, buscar en el apartado de Android. También podemos, introducir “Android” en la caja de texto y con ello filtrar todos los resultados. En mi caso el proyecto se llama EjemploDialogFragment, aunque podeis asignarle el nombre que deseeis.

    Cuando se nos presente la pantalla del asistente en el que damos el nombre a nuestra Activity principal, la vamos a llamar “EjemploFragment”, aunque puede ponerse algún otro. A su archivo layout le he llamado activity_ejemplo_fragment.xml.

    cuando nuestro proyecto haya sido creado, podremos continuar construyendo nuestra aplicación.

  • EjemploFragment

    Cuando nuestro proyecto haya sido creado, tendremos nuestra Activity principal con el nombre de EjemploFragment.java, y su layout se encontrará bajo la carpeta res/layout/activity_ejemplo_fragment.xml, el cual editaremos para dejarlo así:

    		<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    		    xmlns:tools="http://schemas.android.com/tools"
    		    android:layout_width="match_parent"
    		    android:layout_height="match_parent"
    		    tools:context=".EjemploFragment" >
    		
    		    <Button
    		        android:id="@+id/btnShowDialog"
    		        android:layout_width="fill_parent"
    		        android:layout_height="wrap_content"
    		        android:text="Mostrar DialogFragment" />
    		
    		</RelativeLayout>
    		

    Simplemente tenemos un Button, cuya función será ser pulsado y mostrar el DialogFragment.

    Respecto al código java de nuestra clase EjemploFragment.java, nos encontraremos algo más en su interior:

    		package sekth.droid.Fragment;
    
    		import android.os.Bundle;
    		import android.support.v4.app.FragmentActivity;
    		import android.view.View;
    		import android.view.View.OnClickListener;
    		import android.widget.Button;
    		import android.widget.Toast;
    		
    		public class EjemploFragment extends FragmentActivity {
    			private Button btnMostrarDialog;
    			
    			@Override
    			protected void onCreate(Bundle savedInstanceState) {
    				super.onCreate(savedInstanceState);
    				setContentView(R.layout.activity_ejemplo_fragment);
    				
    				btnMostrarDialog = (Button)findViewById(R.id.btnShowDialog);
    				btnMostrarDialog.setOnClickListener(new OnClickListener(){
    		
    					@Override
    					public void onClick(View arg0) {
    						// TODO Auto-generated method stub
    						Fragment1 dialogFragment = Fragment1
    								.newInstance("¿Estas seguro de querer hacer esto?");
    						dialogFragment.show(getSupportFragmentManager(), "dialog");
    					}
    					
    				});
    				
    			}
    			
    			public void doPositiveClick(){
    				Toast.makeText(this, "Ha pulsado OK", Toast.LENGTH_SHORT).show();
    			}
    			
    			public void doNegativeClick(){
    				Toast.makeText(this, "Ha pulsado Cancelar", Toast.LENGTH_SHORT).show();
    			}
    		
    		}
    		

    Lo primero que vemos es que nuestra Activity no hereda de Activity, sino de FragmentActivity. Esto es así porque en mi caso he querido que mi aplicación pueda usar Fragment aunque la API de la versión del dispositivo sea inferior a la API 11. Si por otro lado solo quisieramos desarrollar nuestra aplicación para una API superior a 11, puede heredar de Activity sin problemas.

    • onCreate

      Hemos instanciado el Button de nuestra interfaz gráfica, al cual asignaremos un OnClickListener. Al pulsar sobre el, se crea una nueva instancia de nuestro DialogFragment y se muestra, con el título que hemos especificado, y los 2 botones, el de OK y el de Cancel.

      				@Override
      				protected void onCreate(Bundle savedInstanceState) {
      					super.onCreate(savedInstanceState);
      					setContentView(R.layout.activity_ejemplo_fragment);
      					
      					btnMostrarDialog = (Button)findViewById(R.id.btnShowDialog);
      					btnMostrarDialog.setOnClickListener(new OnClickListener(){
      			
      						@Override
      						public void onClick(View arg0) {
      							// TODO Auto-generated method stub
      							Fragment1 dialogFragment = Fragment1
      									.newInstance("¿Estas seguro de querer hacer esto?");
      							dialogFragment.show(getSupportFragmentManager(), "dialog");
      						}
      						
      					});
      					
      				}
      				
    • doPositiveClick()

      En este método meteremos el código que se ejecutará si en el DialogFragment pulsamos el botón positivo.

      				public void doPositiveClick(){
      					Toast.makeText(this, "Ha pulsado OK", Toast.LENGTH_SHORT).show();
      				}
      				

      En nuestro caso vamos a hacer que se muestre un mensaje mediante la clase Toast, informando de que hemos pulsado el botón positivo.

    • doNegativeClick()

      En este método, al contrario que el anterior, introduciremos el código que se ejecutará si pulsamos el botón negativo en el DialogFragment.

      				public void doNegativeClick(){
      					Toast.makeText(this, "Ha pulsado Cancelar", Toast.LENGTH_SHORT).show();
      				}
      				

      Como vemos, solo vamos a sacar un mensaje mediante Toast, informando de que hemos pulsado la acción negativa.

  • Fragment1

    Nuestra aplicación aún no es funcional, pues no hemos creado el DialogFragment que se ejecutará al pulsar el botón.

    Para crearlo, vamos a crear una nueva clase java en nuestro package, en la ruta src/package_name/. Esta clase la llamaremos Fragment1 por ejemplo, y heredará de la superclase DialogFragment:

    		package sekth.droid.Fragment;
    
    		import android.app.AlertDialog;
    		import android.app.Dialog;
    		import android.content.DialogInterface;
    		import android.os.Bundle;
    		import android.support.v4.app.DialogFragment;
    		
    		public class Fragment1 extends DialogFragment {
    			static Fragment1 newInstance(String title){
    				Fragment1 fragment = new Fragment1();
    				Bundle args = new Bundle();
    				args.putString("title", title);
    				fragment.setArguments(args);
    				return fragment;
    			}
    		
    			@Override
    			public Dialog onCreateDialog(Bundle savedInstanceState) {
    				// TODO Auto-generated method stub
    				String title = getArguments().getString("title");
    				return new AlertDialog.Builder(getActivity())
    					.setIcon(R.drawable.ic_launcher)
    					.setTitle(title)
    					.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
    						
    						@Override
    						public void onClick(DialogInterface dialog, int which) {
    							// TODO Auto-generated method stub
    							((EjemploFragment)getActivity()).doPositiveClick();
    						}
    					})
    					.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
    						
    						@Override
    						public void onClick(DialogInterface dialog, int which) {
    							// TODO Auto-generated method stub
    							((EjemploFragment)getActivity()).doNegativeClick();
    						}
    					})
    					.create();
    			}
    		}
    		

    Nuestra clase hereda de DialogFragment. En nuestro ejemplo, vamos a crear un AlertDialog, que es una ventana de dialogo que muestra un mensaje con botones opcionales.

    • newInstance

      Hemos definido el método newInstance(). Con este método permite crear una nueva instancia del fragment, y al mismo tiempo acepta un argumento que especifica el título que mostrará el AlertDialog, el cual será guardado en un objeto Bundle.

      				static Fragment1 newInstance(String title){
      					Fragment1 fragment = new Fragment1();
      					Bundle args = new Bundle();
      					args.putString("title", title);
      					fragment.setArguments(args);
      					return fragment;
      				}
      				
    • onCreateDialog()

      Lo siguiente es definir el método onCreateDialog(), el cual es llamado después de onCreate() y después de onCreateView(). Como podemos ver nuestro AlertDialog aquí definido es muy simple, tiene 2 botones, Aceptar y Cancelar, además de un título que es el que hemos recibido como del objeto Bundle.

      				@Override
      				public Dialog onCreateDialog(Bundle savedInstanceState) {
      					// TODO Auto-generated method stub
      					String title = getArguments().getString("title");
      					return new AlertDialog.Builder(getActivity())
      						.setIcon(R.drawable.ic_launcher)
      						.setTitle(title)
      						.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
      							
      							@Override
      							public void onClick(DialogInterface dialog, int which) {
      								// TODO Auto-generated method stub
      								((EjemploFragment)getActivity()).doPositiveClick();
      							}
      						})
      						.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
      							
      							@Override
      							public void onClick(DialogInterface dialog, int which) {
      								// TODO Auto-generated method stub
      								((EjemploFragment)getActivity()).doNegativeClick();
      							}
      						})
      						.create();
      				}
      				

      A nuestro DialogFragment le hemos dado un icono, un título, el cual como ya hemos dicho hemos recibido cuando se crea una nueva instancia del Fragment1, y hemos establecido la funcionalidad que debe tener nuestros botones. Si el usuario pulsa el botón positivo, el cual es “Aceptar”, se ejecutará el método doPositiveClick() de nuestra FragmentActivity. Por el contrario, si el usuario pulsa el botón negativo, bajo el nombre “Cancelar”, vamos a encontrarnos con que se realiza una llamada al método doNegativeClick() de nuestro FragmentActivity.

Nuestra aplicación ahora mismo ya es funcional, por lo que podemos ejecutarla y ver los resultados. A continuación vemos unas capturas de pantalla de como queda finalmente:

DialogFragment:

DialogFragmentPrincipal DialogFragmentMostrado DialogFragmentAceptar DialogFragmentCancelar

También podemos ver un video con la ejecución de la aplicación en tiempo real:



Con esta entrada hemos aprendido a manejar otro tipo de Fragment especializado, el cual se encarga de mostrar Dialog, y como vemos su proceso de creación no es complicado, y podemos empezar a añadirlos a nuestros proyectos. Cabe destacar, que hay otras maneras de hacerlos, y esta es solo una de ellas.

El código del ejemplo podeis descargarlo de aquí.

Sin más, cualquier aporte o corrección es bienvenido.

Saludos!!!

  • Enmanuel

    ¿Podría abrirse el mismo dialogo desde varias activities?

    • Buenas Enmanuel,

      Si puedes hacerlo, al fin y al cabo es una de las diferentes características de los Fragment, son reutilizables, por lo que puedes usarlos en aquellos lugares que desees.

      Sin embargo la forma en la que los uso en el tutorial quizás no sea la mas apropiada, por el cast que se hace para ejecutar los métodos. Lo idóneo sería hacerlo mediante una interface como definen en el Android Developers, para ser exactos donde pone “Passing Events Back to the Dialog’s Host”, en el cuál explican como hacerlo mediante el uso de una interface, mucho ma slimpio y es mejor práctica.

      Espero que te sirva de ayuda,

      Saludos!

  • Enmanuel

    Ok, muchas gracias, me lo apunto.

  • Antonio

    Idolo!!!!!!!!
    estaba buscando este ejemplo por todos lados…
    graciassssssssssssssssssssssssssss