Академический Документы
Профессиональный Документы
Культура Документы
com/2015/06/como-crear-dialogos-en-android/
Se caracterizan por interrumpir una tarea del usuario, alterando el foco de la aplicación e invitándolo de forma
intrusiva a que vea información, decida ante una circunstancia crítica o especifique datos.
Por ejemplo…
Puedes usar un diálogo para recordar la importancia de borrar un elemento de la interfaz antes de continuar con
la tarea.
Para descargar el proyecto en Android Studio completo, puedes usar el siguiente botón:
Descargar Código
En los botones podremos ver acciones familiares como lo son la aceptación (Botón positivo) que determina que el
usuario está de acuerdo con la acción. La cancelación (Botón negativo) para evitar la realización de una acción, y
la neutralidad (Botón neutro) para determinar que aún no se está listo para proseguir o cancelar la acción.
Un diálogo de alerta se representa con la clase AlertDialog. En su construcción debes usar un elemento
auxiliar llamado Builder, el cual te ayudará a definir las
partes del diálogo con gran facilidad y sus eventos de
respuesta para los botones.
/**
* Crea un diálogo de alerta sencillo
* @return Nuevo diálogo
*/
public AlertDialog createSimpleDialog() {
AlertDialog.Builder builder = new
AlertDialog.Builder(getActivity());
builder.setTitle("Titulo")
.setMessage("El Mensaje para el
usuario")
.setPositiveButton("OK",
new
DialogInterface.OnClickListener() {
@Override
public void
onClick(DialogInterface dialog, int which) {
listener.onPossitiveButtonClick();
}
})
.setNegativeButton("CANCELAR",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
listener.onNegativeButtonClick();
}
});
return builder.create();
}
También es posible crear un diálogo con una lista de elementos que permita algún tipo de selección por parte del
usuario. Donde es posible crear una lista de elementos comunes, una lista de radio buttons o una lista de
checkeo múltiple.
Si quieres crear una lista simple usa el método setItems() en vez de setMessage(). Este método recibe un
arreglo de cadenas que permita definir las etiquetas de los elementos y una escucha OnClickListener para
decidir que sucede…
/**
* Crea un Diálogo con una lista de selección simple
*
* @return La instancia del diálogo
*/
public AlertDialog createSingleListDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
items[0] = "Naranja";
items[1] = "Mango";
items[2] = "Banano";
builder.setTitle("Diálogo De Lista")
.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(
getActivity(),
"Seleccionaste:" + items[which],
Toast.LENGTH_SHORT)
.show();
}
});
return builder.create();
}
Para saber que ítem fue presionado consulta el parámetro which. Este te indicará el índice seleccionado del
array.
Crear dialogo con lista de radio buttons
/**
* Crea un diálogo con una lista de radios
*
* @return Diálogo
*/
public AlertDialog createRadioListDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
items[0] = "Soltero/a";
items[1] = "Casado/a";
items[2] = "Divorciado/a";
builder.setTitle("Estado Civil")
.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(
getActivity(),
"Seleccionaste: " + items[which],
Toast.LENGTH_SHORT)
.show();
}
});
return builder.create();
}
/**
* Crea un diálogo con una lista de checkboxes
* de selección multiple
*
* @return Diálogo
*/
public AlertDialog createMultipleListDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Intereses")
.setMultiChoiceItems(items, null, new
DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean
isChecked) {
if (isChecked) {
// Guardar indice seleccionado
itemsSeleccionados.add(which);
Toast.makeText(
getActivity(),
"Checks seleccionados:(" +
itemsSeleccionados.size() + ")",
Toast.LENGTH_SHORT)
.show();
} else if (itemsSeleccionados.contains(which)) {
// Remover indice sin selección
itemsSeleccionados.remove(Integer.valueOf(which));
}
}
});
return builder.create();
}
En este caso puedes tomar la selección de varias casillas. Para contarlas usa un pequeño array para añadir
aquellos que estén marcados (esto lo sabes con el parámetro isChecked). De lo contrario retiralos del array
cuando no lo estén.
Desde el punto de vista técnico, se requiere que la definición xml sea inflada a través del método inflate() del
componente LayoutInflater. Esto lo puede hacer al obtener una instancia con getLayoutInflater().
Por ejemplo…
El siguiente layout muestra un formulario común donde se
pide el inicio de sesión de nuestro usuario o la creación
de una cuenta. Como ves, el contenido tiene distribución
vertical de los campos y botones coloridos en distintas
posiciones.
dialog_signin.xml
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:padding="@dimen/dialog_body">
<TextView
android:id="@+id/info_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:paddingBottom="@dimen/padding_between"
android:paddingTop="@dimen/padding_between"
android:text="@string/info_text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:id="@+id/crear_boton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/info_text"
android:layout_centerHorizontal="true"
android:paddingBottom="@dimen/button_padding"
android:paddingTop="@dimen/button_padding"
android:text="@string/crear_boton"
android:textColor="@android:color/white" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@+id/crear_boton"
android:layout_marginBottom="@dimen/padding_between"
android:layout_marginTop="@dimen/padding_between"
android:background="#C8C9CB" />
<EditText
android:id="@+id/nombre_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/divider"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/normal_padding"
android:background="@drawable/edit_text_border"
android:ems="10"
android:hint="@string/nombre_input"
android:inputType="textPersonName"
android:padding="@dimen/edit_text_padding"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/contrasena_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/nombre_input"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/padding_between"
android:layout_marginTop="@dimen/normal_padding"
android:background="@drawable/edit_text_border"
android:ems="10"
android:hint="@string/contrasena_input"
android:inputType="textPassword"
android:padding="@dimen/edit_text_padding"
android:textAppearance="?android:attr/textAppearanceSmall" />
<CheckBox
android:id="@+id/recordar_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/contrasena_input"
android:layout_alignStart="@+id/contrasena_input"
android:layout_below="@+id/contrasena_input"
android:checked="false"
android:text="@string/recordar_check" />
<TextView
android:id="@+id/olvidar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/contrasena_input"
android:layout_alignRight="@+id/contrasena_input"
android:layout_below="@+id/recordar_check"
android:paddingTop="@dimen/padding_between"
android:text="@string/olvidar_text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:id="@+id/entrar_boton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:paddingBottom="@dimen/button_padding"
android:paddingTop="@dimen/button_padding"
android:text="@string/entrar_boton"
android:textColor="@android:color/white" />
</RelativeLayout>
Para aplicar este contenido sobre nuestro diálogo debemos llevar a cabo los pasos anteriormente descritos…
/**
* Crea un diálogo con personalizado para comportarse
* como formulario de login
*
* @return Diálogo
*/
public AlertDialog createLoginDialogo() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(v);
signup.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Crear Cuenta...
dismiss();
}
}
);
signin.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// Loguear...
dismiss();
}
}
);
return builder.create();
}
Un proceso sencillo. Cada botón tendrá su evento correspondiente a las acciones deseadas (crear cuenta y
loguear).
Este ejemplo no ha sido ajustado para landscape. Sin embargo, es importante que optimices tus diálogos
personalizados para esta variación.
Si deseas soportar el uso de DialogFragment hasta la versión 1.6 (API 4) recuerda usar la librería de soporte
con la siguiente directiva:
import android.support.v4.app.DialogFragment;
Para implementarlo simplemente crea una clase y extiéndela de DialogFragment. Luego sobrescribe el método
onCreateDialog() para que retorne en la instancia de alguna subclase de Dialog.
Por ejemplo…
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
/**
* Fragmento con diálogo básico
*/
public class SimpleDialog extends DialogFragment {
public SimpleDialog() {
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return createSimpleDialog();
}
/**
* Crea un diálogo de alerta sencillo
* @return Nuevo diálogo
*/
public AlertDialog createSimpleDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Titulo")
.setMessage("El Mensaje para el usuario")
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
// Acciones
}
})
.setNegativeButton("CANCELAR",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
// Acciones
}
});
return builder.create();
}
}
Debes crear una nueva instancia del DialogFragment en la actividad o fragmento donde desees que se
proyecte. A continuación llamas al método show(), el cual se encarga de mostrar el diálogo contenido en el
fragmento.
show() recibe la instancia del FragmentManager y la etiqueta descriptiva del diálogo para su identificación.
Para conseguir el fragment manager simplemente usa el método getSupportFragmentManager(). Si lo vas a
mostrar en un fragmento, usa solo getFragmentManager().
Paso #1: Declara una interfaz dentro del DialogFragment. La declaración de la interfaz debe tener definido un
método por cada acción que reciba el diálogo.
Si deseas procesar en la actividad los métodos del botón positivo y el negativo, entonces creas una interfaz con
dos métodos respectivos:
public interface OnSimpleDialogListener {
void onPossitiveButtonClick();// Eventos Botón Positivo
void onNegativeButtonClick();// Eventos Botón Negativo
}
Paso #2: Declarar un atributo del tipo de la interfaz para conseguir la instancia directa de la actividad.
// Interfaz de comunicación
OnSimpleDialogListener listener;
Paso #3: Comprobar que la actividad ha implementado la interfaz podemos usar el método onAttach().
Recuerda que este recibe la instancia de la actividad contenedora del fragmento. Simplemente asignas la
actividad a la instancia de la interfaz.
Si este proceso no es posible, entonces lanzas una excepción del tipo ClassCastException.
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnSimpleDialogListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(
activity.toString() +
" no implementó OnSimpleDialogListener");
}
}
Paso #4: Invocar los métodos de la interfaz en las secciones del diálogo donde deseamos implicar a la actividad.
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
listener.onPossitiveButtonClick();
}
})
.setNegativeButton("CANCELAR",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
listener.onNegativeButtonClick();
}
});
//...
}
Paso #6: Sobrescribir dentro de la actividad los métodos de la interfaz, con las acciones que requieras.
@Override
public void onPossitiveButtonClick() {
// Acciones
}
@Override
public void onNegativeButtonClick() {
// Acciones
}
Esta convención es recomendada, ya que en la documentación oficial de Android Developers se menciona que
no se deben comunicar dos fragmentos directamente. Quizás porque las esperanzas de vida de los fragmentos
pueden variar, así que es mejor asegurar su independencia de transmisión.
Supón que tienes un fragmento sencillo con un text view y un botón. La idea es que al presionar el botón, se
despliegue el diálogo de lista simple que hemos construido con anterioridad.
Lo primero es crear un DialogFragment que tenga tres opciones. Para este ejemplo usaré el mensaje “¿Qué
fruta te gusta más?” y añadiré tres opciones: “Naranja”, “Mango” y “Banano”:
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
/**
* Fragmento con diálogo de lista simple
*/
public class SimpleListDialog extends DialogFragment {
OnSetTitleListener listener;
public SimpleListDialog() {
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return createSingleListDialog();
}
/**
* Crea un Diálogo con una lista de selección simple
*
* @return La instancia del diálogo
*/
public AlertDialog createSingleListDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
items[0] = "Naranja";
items[1] = "Mango";
items[2] = "Banano";
return builder.create();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (OnSetTitleListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(
activity.toString() +
" no implementó OnSetTitleListener");
}
}
Como ves, la escucha de comunicación onSetTitleListener provee un método llamado setTitle() para
gestionar la selección del usuario. Justo en el momento que el usuario presiona (método onClick()), se envía
hacia la actividad la cadena contenida en items[which].
if(fragment!=null){
fragment.setTitle(title);
}else{
// Reporta el error...
}
}
}
Al recibir el evento, debes llamar a la instancia del fragmento al que necesitas pasar los resultados. Para ello
llamas al administrador de fragmentos y usas el método findFragmentById() o findFragmentByTag().
El primero obtiene la instancia del fragmento con el id pasado como parámetro y el segundo obtiene el fragmento
que contiene la etiqueta especificada.
Con eso ya puedes llamar el método hipotético setTitle() del fragmento y comunicar la fruta preferida del
usuario en el text view.
DateDialog.java
import android.annotation.TargetApi;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.os.Build;
import android.os.Bundle;
import
android.support.v4.app.DialogFragment;
import java.util.Calendar;
/**
* Fragmento con un diálogo de elección de fechas
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class DateDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
// Obtener fecha actual
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
Para la construcción solo se requiere añadir la fecha por defecto con que se mostrará el diálogo. La clase
Calendar puede ayudarte a obtener la fecha actual por si deseas usarla.
Con ello puedes sobrescribir el método en tu actividad y realizar la acción que desees. En el siguiente ejemplo
despliego la fecha elegida en un Toast:
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
Toast.makeText(
this,
"Fecha: " + year + "-" + monthOfYear + "-" + dayOfMonth,
Toast.LENGTH_LONG)
.show();
TimeDialog.java
import android.annotation.TargetApi;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Build;
import android.os.Bundle;
import
android.support.v4.app.DialogFragment;
import android.text.format.DateFormat;
import java.util.Calendar;
/**
* Fragmento con un diálogo de elección de
tiempos
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class TimeDialog extends
DialogFragment {
@Override
public Dialog onCreateDialog(Bundle
savedInstanceState) {
// Iniciar con el tiempo actual
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
El TimePickerDialog se construye con el tiempo actual detectado con ayuda de la clase Calendar. Donde su
constructor recibe los siguientes parámetros:
El paso a seguir es implementar la interfaz OnTimeSetListener en tu actividad principal para sobrescribir las
acciones del método de acción onTimeSet().
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Toast.makeText(
this,
"Tiempo: " + hourOfDay + ":" + minute,
Toast.LENGTH_LONG)
.show();
}
También pueden usarse en situaciones donde el tamaño de la pantalla influye. Es decir, para tamaños pequeños
podría mostrarse el diálogo en pantalla completa y para tamaños grandes se desplegaría normalmente.
Lo curioso es que al crear un diálogo en pantalla completa, no podemos usar la clase AlertDialog junto a
Builder, debido a que el DialogFragment será embebido a través de una transacción de fragmentos como se
hace normalmente.
Esto significa que el método onCreateDialog() no será sobrescrito, por lo que debemos acudir a
onCreateView() para inflar un layout por completo.
Así que puedes deducir que las áreas de título, contenido y acción no están distribuida de la misma forma. Esta
vez los botones de confirmación y el título van en la action bar; y el contenido será ubicado en todo el espacio de
trabajo.
El siguiente ejemplo extraído de la guía de Material Design para diseño de diálogos full screen , muestra cómo se
vería este elemento:
Si lees un poco, nos indican que debemos ubicar la acción de
confirmación como action button con un verbo descriptivo
como “Guardar”, “Crear”, “Enviar”, etc. En caso de la acción
negativa, se usa el ícono de cerrar como Up Button.
fullscreen_dialog.xml
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:paddingTop="@dimen/edit_text_padding"
android:text="@string/cliente_label"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/textView"
android:entries="@array/clientes" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/spinner"
android:paddingTop="@dimen/edit_text_padding"
android:text="@string/producto_label"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner
android:id="@+id/spinner2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/textView2"
android:entries="@array/productos" />
<TextView
android:id="@+id/fecha_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/spinner2"
android:paddingTop="@dimen/edit_text_padding"
android:text="@string/fecha_label"
android:textAppearance="?android:attr/textAppearanceSmall" />
<View
android:id="@+id/centro"
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_centerInParent="true"
android:background="@null" />
<TextView
android:id="@+id/prioridad_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/fecha_text"
android:paddingTop="@dimen/edit_text_padding"
android:text="@string/prioridad_label"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner
android:id="@+id/spinner5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/prioridad_text"
android:entries="@array/prioridades" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/spinner5"
android:paddingTop="@dimen/edit_text_padding"
android:text="@string/notas_label"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/textView5"
android:hint="@string/notas_hint"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/fecha_text"
style="@android:style/Widget.DeviceDefault.Light.Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/fecha_label"
android:layout_marginRight="@dimen/normal_padding"
android:layout_toLeftOf="@+id/hora_text"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/hora_text"
style="@android:style/Widget.DeviceDefault.Light.Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/fecha_label"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
</ScrollView>
Para proseguir con ese diseño, simplemente debes crear un nuevo fragmento que extienda de DialogFragment
y sobrescribes el método onCreateView() para inflarlo.
FullScreenDialog.java
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.herprogramacion.dialogpers.R;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// Obtener instancia de la action bar
ActionBar actionBar = ((AppCompatActivity) getActivity())
.getSupportActionBar();
if (actionBar != null) {
// Habilitar el Up Button
actionBar.setDisplayHomeAsUpEnabled(true);
// Cambiar icono del Up Button
actionBar.setHomeAsUpIndicator(R.mipmap.ic_close);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fullscreen_dialog, container, false);
iniciarHora(view);// Setear hora inicial
iniciarFecha(view);// Setear fecha inicial
return view;
}
textTiempo.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
new TimeDialog().show(getFragmentManager(),
"TimePickerInFull");
}
}
);
}
textFecha.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
new DateDialog().show(getFragmentManager(),
"DatePickerInFull");
}
}
);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fullscreen_dialog, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
// procesarDescartar()
break;
case R.id.action_save:
// procesarGuardar()
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Actualiza la fecha del view {@code fecha_text}
* @param year Nuevo Año
* @param monthOfYear Nuevo Mes
* @param dayOfMonth Nuevo día
*/
public void setDateView(int year, int monthOfYear, int dayOfMonth) {
Calendar c = Calendar.getInstance();
c.set(year, monthOfYear, dayOfMonth);
SimpleDateFormat format = new SimpleDateFormat("E MMM d yyyy");
textFecha.setText(format.format(c.getTime()));
}
/**
* Actualiza la hora del view {@code hora_text}
* @param hourOfDay Nueva Hora
* @param minute Nuevos Minutos
*/
public void setTimeView(int hourOfDay, int minute) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR, hourOfDay);
c.set(Calendar.MINUTE, minute);
SimpleDateFormat format = new SimpleDateFormat("HH:mm a");
textTiempo.setText(format.format(c.getTime()));
}
}
El estilo de la fecha y el tiempo puedes modificarlo a través de la clase SimpleDateFormat, la cual provee el
método format() para transformar información con respecto a un patrón.
Otra aspecto importante es la creación de un DateDialog y un TimeDialog al momento de pulsar los text
views de fecha y tiempo. Lo que quiere decir que se espera que la actividad implemente las escuchas para la
transferencia de los datos.
Ahora debes insertarlo en la actividad donde te encuentras. Lo que requiere una transacción simple de
fragmentos.
DetailActivity.java
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.widget.DatePicker;
import android.widget.TimePicker;
import com.herprogramacion.dialogpers.R;
import com.herprogramacion.dialogpers.dialogos.FullScreenDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
if (savedInstanceState == null) {
crearFullScreenDialog();
}
}
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int
dayOfMonth) {
Los métodos onDateSet() y onTimeSet() de las interfaces de los pickers acceden directamente al dialogo
FullScreenDialog para comunicar los datos. Si observaste bien, setDateView() y setTimeView() son los
métodos encargados de recibir los datos de las interfaces de comunicación.
Por último programamos las acciones de la action bar. Crea un nuevo menú llamado fullscreen_dialog.xml y
asígnale un action button para guardar:
fullscreen_dialog.xml
El ícono de cerrar se implementó al obtener la action bar en onCreateView() para cambiar el icono del up
button con el método setHomeAsUpIndicator(). El drawable puedes encontrarlo al descargar el proyecto.
Y esto es tan sencillo como usar el método dismiss() dentro de DialogFragment. Adicionalmente puedes
realizar acciones en ese instante con el método onDismiss().
// Dentro de un DialogFragment...
@Override
public void onDismiss(DialogInterface dialog) {
// Tus acciones
}
Por otro lado el diálogo puede ser cancelado sin aplicar los cambios a través de cancel(). Para procesar su
comportamiento puedes usar onCancel(), el cual es invocado si el usuario presiona el Back Button, si es
presionado el botón negativo o si se presiona por fuera del diálogo.
// Dentro de un DialogFragment...
@Override
public void onCancel(DialogInterface dialog) {
// Tus acciones
}
Conclusiones
Asegúrate de usar diálogos cuando desees que el usuario decida ante una situación de confirmación o
cuando sea necesario el ingreso de datos necesarios para el procesamiento de una acción.
La clase DialogFragment permite la relación de los diálogos con los eventos de un fragmento. Esto
reduce la complejidad de interacciones con la actividad.
Asegúrate de seguir los patrones de diseño y las medidas establecidas por Google para mantener una
excelente experiencia de usuario en tu aplicación.
Es importante mantener el diseño de tus diálogos personalizados adaptable a diferentes tipos de pantallas
y orientaciones. Esto maximizará la experiencia de usuario en tu app.
Icono de la aplicación