Ventás de Diálogos

De MediaWiki
Saltar a: navegación, buscar

Introdución

  • Un diálogo é unha ventá pequena que lle pregunta ao usuario para tomar unha decisión, para informalo, ou para que o usuario introduza información.
  • Non cubre toda a pantalla
  • É usado para que o usuario tome algún tipo de acción antes de seguir coa aplicación.


00 dialogs w title.png

  • Hai catro tipos de ventás de diálogo:
    • AlertDialog: pode conter de cero a tres botóns, unha lista, RadioButtons, CheckBoxes, etc.
    • ProgressDialog: amosa unha barra de progreso. Herda de da clase AlertDialog. Verase na Unidade 5.
    • DatePickerDialog: este diálogo é para seleccionar unha fecha.
    • TimePickerDialog: este diálogo permite seleccionar unha hora.


  • O ProgressDialog está deprecated dende a API 26, isto quere dicir que nun futuro deixará de poder utilizarse dita clase.
PDM Dialogos 5.JPG
Como alternativas podemos empregar:
Veremos na UNIDADE 7: Threads e AsyncTask un exemplo de uso deste tipo de Dialog.
  • No caso de que teñades na vosa práctica que escoller un campo data ou un campo hora, deberedes facer uso do Dialogs comentados anteriormente.



  • Neste unidade imos centrarnos nos AlertDialog
    • Un diálogo baseado na clase AlertDialog ten 3 rexións:

00 dialogs regions.png


  • 1.-Título: é opcional.
  • 2.-Área de contido:pode amosar unha mensaxe, lista, un layout personalizado, etc.
  • 3.-Botóns de acción: Non debe haber máis de tres botóns.
  • Hai tres tipos de botóns:
    • Positivo: usarase para aceptar ou continuar unha acción.
    • Negativo: usarase cando se desexe cancelar unha acción.
    • Neutral: usarase cando non se sabe que facer coa acción.



  • Anteriormente a API 13, para amosar un diálogo chamábase ao método showDialog() indicando un parámetro enteiro, único na actividade.
Actualmente el uso dese método está deprecated.
Como alternativa se pode facer uso dos DialogFragment que fai engadido na versión API 22
PDM Dialogos 6.JPG
Esta forma de crear un diálogo tamén está deprecated dende a versión API 28, Android P
Polo tanto Android recomenda facer uso da biblioteca de compatibilidade com.android.support:support-v4:27.0.0 tanto para dar soporte a dispositivos anteriores a API 22 como os dispositivos posteriores a API 28.
Nota: Deberedes cambiar o número 27.0.0 pola versión compileSdkVersion do arquivo build.gradle.
Lembra que xa vimos como engadir unha biblioteca de compatibilidade nesta wiki




Dialogs anteriores a API 13

Nota: Opción deprecated. Utilizar DialogFragments (seguinte sección)
Se non o temos creado antes, crearemos un novo paquete de nome: Dialogs como un subpaquete do teu paquete principal.



  • Dentro do paquete Dialogs crear unha nova 'Empty Activity' de nome: UD03_01_Dialogs de tipo Launcher e sen compatibilidade.
Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.




  • As seguintes imaxes amosan o funcionamento da aplicación.
  • Todos os elementos dos diálogos teñen asociado un Toast como acción, aínda que só se amose na última imaxe da seguinte secuencia.



O XML do Layout

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    xmlns:app="http://schemas.android.com/apk/res-auto"
  4.    xmlns:tools="http://schemas.android.com/tools"
  5.    android:layout_width="match_parent"
  6.    android:layout_height="match_parent"
  7.    tools:context=".Dialogs.UD03_01_Dialogs">
  8.  
  9.     <TextView
  10.        android:id="@+id/tvTexto_UD03_01_Dialogs"
  11.        android:layout_width="wrap_content"
  12.        android:layout_height="wrap_content"
  13.        android:layout_marginStart="8dp"
  14.        android:layout_marginTop="8dp"
  15.        android:text="Preme nos botóns (ten scroll). Ventás de diálogo."
  16.        android:textSize="18sp"
  17.        app:layout_constraintStart_toStartOf="parent"
  18.        app:layout_constraintTop_toTopOf="parent" />
  19.  
  20.     <ScrollView
  21.        android:layout_width="0dp"
  22.        android:layout_height="240dp"
  23.        android:layout_marginStart="8dp"
  24.        android:layout_marginTop="28dp"
  25.        android:layout_marginEnd="8dp"
  26.        app:layout_constraintEnd_toEndOf="parent"
  27.        app:layout_constraintHorizontal_bias="1.0"
  28.        app:layout_constraintStart_toStartOf="parent"
  29.        app:layout_constraintTop_toBottomOf="@+id/tvTexto_UD03_01_Dialogs">
  30.  
  31.         <LinearLayout
  32.            android:id="@+id/linearLayout"
  33.            android:layout_width="match_parent"
  34.            android:layout_height="wrap_content"
  35.            android:orientation="vertical">
  36.  
  37.             <Button
  38.                android:id="@+id/btnDlgMensaxe_UD03_01_Dialogs"
  39.                android:layout_width="match_parent"
  40.                android:layout_height="wrap_content"
  41.                android:text="Ventá de diálogo con mensaxe" />
  42.  
  43.             <Button
  44.                android:id="@+id/btnDlgBotons_UD03_01_Dialogs"
  45.                android:layout_width="match_parent"
  46.                android:layout_height="wrap_content"
  47.                android:layout_marginTop="5dp"
  48.                android:text="Ventá de diálogo con 3 botóns" />
  49.  
  50.             <Button
  51.                android:id="@+id/btnDlgLista_UD03_01_Dialogs"
  52.                android:layout_width="match_parent"
  53.                android:layout_height="wrap_content"
  54.                android:layout_marginTop="5dp"
  55.                android:text="V.de diálogo con lista de selección " />
  56.  
  57.             <Button
  58.                android:id="@+id/btnDlgUnicaSel_UD03_01_Dialogs"
  59.                android:layout_width="match_parent"
  60.                android:layout_height="wrap_content"
  61.                android:layout_marginTop="5dp"
  62.                android:text="V.de diálogo cunha única selección " />
  63.  
  64.             <Button
  65.                android:id="@+id/btnDlgMulSelec_UD03_01_Dialogs"
  66.                android:layout_width="match_parent"
  67.                android:layout_height="wrap_content"
  68.                android:layout_marginTop="5dp"
  69.                android:text="V.de diálogo  con selección múltiple" />
  70.  
  71.             <Button
  72.                android:id="@+id/btnDlgEntrada_UD03_01_Dialogs"
  73.                android:layout_width="match_parent"
  74.                android:layout_height="wrap_content"
  75.                android:layout_marginTop="5dp"
  76.                android:text="V.de diálogo con entrada de texto" />
  77.         </LinearLayout>
  78.     </ScrollView>
  79.  
  80. </android.support.constraint.ConstraintLayout>
  81. </ScrollView>
  82.  
  83. </LinearLayout>



Definición de recursos tipo array en XML

  • Aproveitamos o ficheiro /res/values/strings.xml e definimos dous recursos de tipo Array, para a lista de selección e para a selección múltiple.


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <resources>
  4.     <string name="app_name">Aprendiendo</string>
  5.  
  6.  
  7.     <string-array name="array_elem_seleccion1_ud03_01_dialogs">
  8.         <item>Opción un</item>
  9.         <item>Opción dous</item>
  10.         <item>Opción tres</item>
  11.         <item>Opción catro</item>
  12.     </string-array>
  13.  
  14.     <string-array name="array_elem_seleccion2_ud03_01_dialogs">
  15.         <item>Coche</item>
  16.         <item>Moto</item>
  17.         <item>Bici</item>
  18.         <item>Metro</item>
  19.         <item>Tren</item>
  20.         <item>Autobús</item>
  21.         <item>Andando</item>
  22.     </string-array>
  23.  
  24.  
  25. </resources>



Definición do recurso de tipo Layout usado polo diálogo con entrada de texto (o último)

Explicado posteriormente.

  • Ficheiro /res/layout/dlg_entrada_texto_ud03_01_dialogs.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    xmlns:app="http://schemas.android.com/apk/res-auto"
  4.    xmlns:tools="http://schemas.android.com/tools"
  5.    android:layout_width="match_parent"
  6.    android:layout_height="match_parent"
  7.    android:theme="@android:style/Theme.Holo.Dialog">
  8.  
  9.     <EditText
  10.        android:id="@+id/etPass_Dlg_UD03_01_Dialogs"
  11.        android:layout_width="0dp"
  12.        android:layout_height="wrap_content"
  13.        android:layout_marginEnd="8dp"
  14.        android:inputType="textPassword"
  15.        android:contentDescription="Introduce o password"
  16.        android:textColor="@android:color/holo_blue_dark"
  17.        app:layout_constraintEnd_toEndOf="parent"
  18.        app:layout_constraintStart_toStartOf="@+id/guideline"
  19.        app:layout_constraintTop_toBottomOf="@+id/etNome_Dlg_UD03_01_Dialogs" />
  20.  
  21.     <TextView
  22.        android:id="@+id/tvNome_Dlg_UD03_01_Dialogs2"
  23.        android:layout_width="wrap_content"
  24.        android:layout_height="wrap_content"
  25.        android:layout_marginStart="8dp"
  26.        android:layout_marginTop="20dp"
  27.        android:text="Contrasinal:"
  28.        android:textSize="18sp"
  29.        app:layout_constraintStart_toStartOf="parent"
  30.        app:layout_constraintTop_toBottomOf="@+id/tvPass_Dlg_UD03_01_Dialogs" />
  31.  
  32.     <TextView
  33.        android:id="@+id/tvPass_Dlg_UD03_01_Dialogs"
  34.        android:layout_width="wrap_content"
  35.        android:layout_height="wrap_content"
  36.        android:layout_marginStart="8dp"
  37.        android:layout_marginTop="8dp"
  38.        android:text="Nome:"
  39.        android:textSize="18sp"
  40.        app:layout_constraintStart_toStartOf="parent"
  41.        app:layout_constraintTop_toTopOf="parent" />
  42.  
  43.     <android.support.constraint.Guideline
  44.        android:id="@+id/guideline"
  45.        android:layout_width="wrap_content"
  46.        android:layout_height="wrap_content"
  47.        android:orientation="vertical"
  48.        app:layout_constraintGuide_begin="103dp" />
  49.  
  50.     <EditText
  51.        android:id="@+id/etNome_Dlg_UD03_01_Dialogs"
  52.        android:layout_width="0dp"
  53.        android:layout_height="wrap_content"
  54.        android:layout_marginEnd="8dp"
  55.        android:focusedByDefault="true"
  56.        android:contentDescription="Introduce o nome"
  57.        android:textColor="@android:color/holo_blue_dark"
  58.        app:layout_constraintEnd_toEndOf="parent"
  59.        app:layout_constraintStart_toStartOf="@+id/guideline"
  60.        app:layout_constraintTop_toTopOf="parent" />
  61. </android.support.constraint.ConstraintLayout>



Código Java

  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.Dialogs;
  2.  
  3. import android.app.Activity;
  4. import android.app.AlertDialog;
  5. import android.app.Dialog;
  6. import android.content.Context;
  7. import android.content.DialogInterface;
  8. import android.content.res.Resources;
  9. import android.os.Bundle;
  10. import android.view.LayoutInflater;
  11. import android.view.View;
  12. import android.widget.TextView;
  13. import android.widget.Toast;
  14.  
  15. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  16.  
  17. public class UD03_01_Dialogs extends Activity implements View.OnClickListener {
  18.     private static final int DIALOGO_MENSAXE = 1;
  19.     private static final int DIALOGO_TRES_BOTONS = 2;
  20.     private static final int DIALOGO_LISTA = 3;
  21.     private static final int DIALOGO_RADIO_BUTTON = 4;
  22.     private static final int DIALOGO_CHECK_BOX = 5;
  23.     private static final int DIALOGO_ENTRADA_TEXTO = 6;
  24.  
  25.     // Atributo para crear as ventás de diálogo
  26.     private AlertDialog.Builder venta;
  27.  
  28.     protected Dialog onCreateDialog(int id) {
  29.         switch (id) {
  30.  
  31.             case DIALOGO_MENSAXE:
  32.                 venta = new AlertDialog.Builder(this);
  33.                 venta.setTitle("Atención");
  34.                 venta.setMessage("Nova amensaxe. Preme o botón 'Back' para volver á pantalla principal");
  35.                 venta.setIcon(android.R.drawable.ic_dialog_email);
  36.                 return venta.create();
  37.  
  38.  
  39.  
  40.             case DIALOGO_TRES_BOTONS:
  41.                 venta = new AlertDialog.Builder(this);
  42.                 venta.setIcon(android.R.drawable.ic_dialog_info);
  43.                 venta.setTitle("Enquisa");
  44.                 venta.setMessage("Compras sempre en grandes superficies?");
  45.                 venta.setCancelable(false);
  46.                 venta.setPositiveButton("Si", new DialogInterface.OnClickListener() {
  47.                     public void onClick(DialogInterface dialog, int boton) {
  48.                         /* Sentencias se o usuario preme Si */
  49.                         Toast.makeText(getApplicationContext(), "Premeches 'Si'", 1).show();
  50.                     }
  51.                 });
  52.                 venta.setNegativeButton("Non", new DialogInterface.OnClickListener() {
  53.                     public void onClick(DialogInterface dialog, int boton) {
  54.                         /* Sentencias se o usuario preme Non */
  55.                         Toast.makeText(getApplicationContext(), "Premeches'Non'", 1).show();
  56.                     }
  57.                 });
  58.                 venta.setNeutralButton("Ás veces", new DialogInterface.OnClickListener() {
  59.                     public void onClick(DialogInterface dialog, int boton) {
  60.                         /* Sentencias se o usuario preme Ás veces */
  61.                         Toast.makeText(getApplicationContext(), "Premeches 'Ás veces'", 1).show();
  62.                     }
  63.                 });
  64.                 return venta.create();
  65.  
  66.  
  67.  
  68.             case DIALOGO_LISTA:
  69.                 venta = new AlertDialog.Builder(this);
  70.                 venta.setIcon(android.R.drawable.ic_dialog_alert);
  71.                 venta.setTitle("Escolle unha opción");
  72.                 venta.setItems(R.array.array_elem_seleccion1_ud03_01_dialogs, new DialogInterface.OnClickListener() {
  73.                     public void onClick(DialogInterface dialog, int posicion) {
  74.                         // O usuario selecciona unha das opcións do listado
  75.                         String[] opcions = getResources().getStringArray(R.array.array_elem_seleccion1_ud03_01_dialogs);
  76.                         Toast.makeText(getApplicationContext(), "Seleccionaches: '" + opcions[posicion] + "'", Toast.LENGTH_LONG).show();
  77.                     }
  78.                 });
  79.                 return venta.create();
  80.  
  81.  
  82.  
  83.             case DIALOGO_RADIO_BUTTON:
  84.                 venta = new AlertDialog.Builder(this);
  85.                 venta.setIcon(android.R.drawable.ic_dialog_info);
  86.                 venta.setTitle("Selecciona un smartpohone");
  87.                 // Non incluír mensaxe dentro de este tipo de diálogo!!!
  88.                 final CharSequence[] smartphones = { "iPhone", "Blackberry", "Android" };
  89.                 venta.setSingleChoiceItems(smartphones, 0, new DialogInterface.OnClickListener() {
  90.                     public void onClick(DialogInterface dialog, int opcion) {
  91.                         // Evento que ocorre cando o usuario selecciona una opción
  92.                         Toast.makeText(getApplicationContext(), "Seleccionaches: " + smartphones[opcion], Toast.LENGTH_SHORT).show();
  93.                     }
  94.                 });
  95.                 venta.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  96.                     public void onClick(DialogInterface dialog, int boton) {
  97.                         Toast.makeText(getApplicationContext(), "Premeches 'Aceptar'", 1).show();
  98.                     }
  99.                 });
  100.                 venta.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  101.                     public void onClick(DialogInterface dialog, int boton) {
  102.                         Toast.makeText(getApplicationContext(), "Premeches 'Cancelar'", 1).show();
  103.                     }
  104.                 });
  105.                 return venta.create();
  106.  
  107.  
  108.  
  109.             case DIALOGO_CHECK_BOX:
  110.                 venta = new AlertDialog.Builder(this);
  111.                 venta.setIcon(android.R.drawable.ic_dialog_info);
  112.                 venta.setTitle("Selecciona modos de transporte");
  113.                 Resources res = getResources();
  114.                 final String[] matriz = res.getStringArray(R.array.array_elem_seleccion2_ud03_01_dialogs);
  115.                 // Non incluír mensaxe dentro de este tipo de diálogo!!!
  116.                 venta.setMultiChoiceItems(matriz, new boolean[] { false, true, false, true, false, false, false }, new DialogInterface.OnMultiChoiceClickListener() {
  117.                     public void onClick(DialogInterface dialog, int opcion, boolean isChecked) {
  118.                         // Evento que ocorre cando o usuario selecciona unha opción
  119.                         if (isChecked)
  120.                             Toast.makeText(getApplicationContext(), "Seleccionaches " + matriz[opcion], Toast.LENGTH_SHORT).show();
  121.                         else
  122.                             Toast.makeText(getApplicationContext(), "Deseleccionaches " + matriz[opcion], Toast.LENGTH_SHORT).show();
  123.                     }
  124.                 });
  125.                 venta.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  126.                     public void onClick(DialogInterface dialog, int boton) {
  127.                         Toast.makeText(getApplicationContext(), "Premeches 'Aceptar'", Toast.LENGTH_LONG).show();
  128.                     }
  129.                 });
  130.                 venta.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  131.                     public void onClick(DialogInterface dialog, int boton) {
  132.                         Toast.makeText(getApplicationContext(), "Premeches 'Cancelar'", Toast.LENGTH_LONG).show();
  133.                     }
  134.                 });
  135.                 return venta.create();
  136.  
  137.  
  138.  
  139.             case DIALOGO_ENTRADA_TEXTO:
  140.                 // Primeiro preparamos o interior da ventá de diálogo inflando o seu
  141.                 // fichero XML
  142.                 String infService = Context.LAYOUT_INFLATER_SERVICE;
  143.                 LayoutInflater li = (LayoutInflater) getApplicationContext().getSystemService(infService);
  144.                 // Inflamos o compoñente composto definido no XML
  145.                 View inflador = li.inflate(R.layout.dlg_entrada_texto_ud03_01_dialogs, null);
  146.                 // Buscamos os compoñentes dentro do Diálogo
  147.                 final TextView etNome = (TextView) inflador.findViewById(R.id.etNome_Dlg_UD03_01_Dialogs);
  148.                 final TextView etContrasinal = (TextView) inflador.findViewById(R.id.etPass_Dlg_UD03_01_Dialogs);
  149.  
  150.                 venta = new AlertDialog.Builder(this);
  151.                 venta.setTitle("Indica usuario e contrasinal");
  152.                 // Asignamos o contido dentro do diálogo (o que inflamos antes)
  153.                 venta.setView(inflador);
  154.                 // Non se pode incluír unha mensaxe dentro deste tipo de diálogo!!!
  155.                 venta.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  156.                     public void onClick(DialogInterface dialog, int boton) {
  157.                         Toast.makeText(getApplicationContext(), "Escribiches nome: '" + etNome.getText().toString() + "'. Contrasinal: '" + etContrasinal.getText().toString() + "' e premeches 'Aceptar'",
  158.                                 Toast.LENGTH_LONG).show();
  159.                     }
  160.                 });
  161.                 venta.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  162.                     public void onClick(DialogInterface dialog, int boton) {
  163.                         Toast.makeText(getApplicationContext(), "Premeches en 'Cancelar'", Toast.LENGTH_LONG).show();
  164.                     }
  165.                 });
  166.                 return venta.create();
  167.  
  168.         }
  169.         return null;
  170.     }
  171.  
  172.  
  173.     private void xestioarEventos(){
  174.  
  175.         findViewById(R.id.btnDlgBotons_UD03_01_Dialogs).setOnClickListener(this);
  176.         findViewById(R.id.btnDlgEntrada_UD03_01_Dialogs).setOnClickListener(this);
  177.         findViewById(R.id.btnDlgLista_UD03_01_Dialogs).setOnClickListener(this);
  178.         findViewById(R.id.btnDlgMensaxe_UD03_01_Dialogs).setOnClickListener(this);
  179.         findViewById(R.id.btnDlgMulSelec_UD03_01_Dialogs).setOnClickListener(this);
  180.         findViewById(R.id.btnDlgUnicaSel_UD03_01_Dialogs).setOnClickListener(this);
  181.     }
  182.  
  183.  
  184.     @Override
  185.     protected void onCreate(Bundle savedInstanceState) {
  186.         super.onCreate(savedInstanceState);
  187.         setContentView(R.layout.activity_ud03_01__dialogs);
  188.  
  189.         xestioarEventos();
  190.     }
  191.  
  192.     // A interface está implementada na Activity
  193.     @Override
  194.     public void onClick(View v) {
  195.         switch (v.getId()) {
  196.             case R.id.btnDlgMensaxe_UD03_01_Dialogs:
  197.                 showDialog(DIALOGO_MENSAXE);
  198.                 break;
  199.  
  200.             case R.id.btnDlgBotons_UD03_01_Dialogs:
  201.                 showDialog(DIALOGO_TRES_BOTONS);
  202.  
  203.                 break;
  204.  
  205.             case R.id.btnDlgLista_UD03_01_Dialogs:
  206.                 showDialog(DIALOGO_LISTA);
  207.  
  208.                 break;
  209.  
  210.             case R.id.btnDlgUnicaSel_UD03_01_Dialogs:
  211.                 showDialog(DIALOGO_RADIO_BUTTON);
  212.  
  213.                 break;
  214.  
  215.             case R.id.btnDlgMulSelec_UD03_01_Dialogs:
  216.                 showDialog(DIALOGO_CHECK_BOX);
  217.  
  218.                 break;
  219.  
  220.             case R.id.btnDlgEntrada_UD03_01_Dialogs:
  221.                 showDialog(DIALOGO_ENTRADA_TEXTO);
  222.  
  223.                 break;
  224.  
  225.             default:
  226.                 break;
  227.         }
  228.  
  229.     }
  230. }
  • Liñas 17: Para a xestión dos eventos de click sobre os botóns implementamos a interface a nivel de Activity.
  • Liñas 18-23: Creamos constantes enteiras para cada tipo de dialogo que queremos crear.
  • Liñas 26: Esta propiedade vai servir para 'crear' os diferentes tipos de Dialogs.
  • Liñas 28-170: En función do código que lle chega (o código ven enviado dende as liñas 195-223) creamos os diferentes tipos de Dialogs.
  • Liñas 189: Rexistramos os eventos de click en cada botón.
  • Liñas 195-223: En función do botón premido mandamos crear un tipo de diálogo diferente enviando un código que o identifica (inventado por nos)


  • Métodos máis comúns para todos os tipos de diálogos:
    • setTitle(): establece o título da ventá de diálogo.
    • setMessage(): pon a mensaxe na área de contido da ventá de diálogo.
    • setIcon():establece a propiedade Icon cunha das imaxes predefinidas.


  • No caso dos cadros de diálogo que teñan botóns:
    • Indicamos para cada tipo de botón o Texto que debe ver o usuario
    • Indicamos a acción a realizar se se preme. Neste caso chámase ao Listener de DialogInterface asociado ao evento Click.


  • No método onBotonClick(View view) achamos que botón foi o que se pulsou e en función diso chamamos ao método showDialog() pasándolle a constante enteira asociada ao diálogo que queremos crear.
  • No método onCreateDialog() temos asociado un diálogo para cada unha das constantes enteiras. O método recibe o enteiro e crear o diálogo asociado a ese número enteiro.
  • Para cada novo diálogo crease un obxecto venta co construtor AlertDialog.Builder()

Ventás de diálogo personalizadas

  • O último diálogo (Liñas 139-172) ten asociado un Layout XML. Ficheiro /res/layout/dlg_entrada_texto_ud03_01_dialogs.xml (xa posto anteriormente).
  • Para visualizalo, no canto de utilizar setMessage() usamos o método setView() (liña 154 do código da activity) para amosar na área de contido do diálogo o XML inflado;
  • Ese ficheiro XML hai que instancialo nas súas correspondentes Vistas.
  • Ese proceso coñecese co nome de Inflar e é necesario facelo para poder visualizar o recurso xml.
  • Podemos ver como é dito proceso no código:
  1.      case DIALOGO_ENTRADA_TEXTO:
  2.          // Primeiro preparamos o interior da ventá de diálogo inflando o seu
  3.          // fichero XML
  4.          String infService = Context.LAYOUT_INFLATER_SERVICE;
  5.          LayoutInflater li = (LayoutInflater) getApplicationContext().getSystemService(infService);
  6.          // Inflamos o compoñente composto definido no XML
  7.          View inflador = li.inflate(R.layout.dlg_entrada_texto_ud03_01_dialogs, null);
  8.          ............
  9.          venta.setView(inflador);

Neste caso estamos a facer un 'inflate' explícito, pero aínda que non vos dades conta, tamén se fai un 'inflate' cando chamamos o método setContentView dentro do onCreate da activity. Lembrar que o que pasamos como dato nesa chamada é o layout que vai visualizar a activity. Isto se coñece como 'inflate' implícito e o fai o S.O. automaticamente.

  • Para nos (aínda que non sexa exactamente iso) o 'inflado' serve para pasar dun recurso de texto xml a un obxecto (View) onde se atopan todos os elementos gráficos que están definidos no arquivo xml. É importante sinalar que cando queiramos acceder a un compoñente do diálogo (por exemplo, no xogo das preguntas, cando engadimos unha pregunta nova aparece un diálogo deste tipo. Ao dar de alta a pregunta leva consigo acceder as caixas de texto) o temos que facer a través do view que obtemos do 'inflado'. Se isto o facemos dende dentro dunha clase anónima, teremos que definir o View como final.
    No exemplo, o que se define como final é o campo de texto (liñas 148 e 149), pero poderíamos definir como final o View da forma:


  1.                 case DIALOGO_ENTRADA_TEXTO:
  2.                         // Primeiro preparamos o interior da ventá de diálogo inflando o seu
  3.                         // fichero XML
  4.                         String infService = Context.LAYOUT_INFLATER_SERVICE;
  5.                         LayoutInflater li = (LayoutInflater) getApplicationContext().getSystemService(infService);
  6.                         // Inflamos o compoñente composto definido no XML
  7.                         final View inflador = li.inflate(R.layout.dialogo_entrada_texto, null);
  8.  
  9.                         venta = new AlertDialog.Builder(this);
  10.                         venta.setTitle("Indica usuario e contrasinal");
  11.                         // Asignamos o contido dentro do diálogo (o que inflamos antes)
  12.                         venta.setView(inflador);
  13.                         // Non se pode incluír unha mensaxe dentro deste tipo de diálogo!!!
  14.                         venta.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  15.                                 public void onClick(DialogInterface dialog, int boton) {
  16.                                         // Buscamos os compoñentes dentro do Diálogo
  17.                                         TextView etNome = (TextView) inflador.findViewById(R.id.etNome_Dlg_UD03_01_Dialogs);
  18.                                         TextView etContrasinal = (TextView) inflador.findViewById(R.id.etPass_Dlg_UD03_01_Dialogs);
  19.                                        
  20.                                         Toast.makeText(getApplicationContext(), "Escribiches nome: '" + etNome.getText().toString() + "'. Contrasinal: '" + etContrasinal.getText().toString() + "' e premeches 'Aceptar'",
  21.                                                         1).show();
  22.                                 }
  23.                         });
  • No inflate o segundo parámetro:
View inflador = li.inflate(R.layout.dialogo_entrada_texto, null);)

normalmente ponse null, pero podemos poñer un view que queiramos que sexa 'pai' do view que se xera a partires do arquivo de recursos xml.




Dialogs posteriores a API 13.DialogFragment (opción actual)

A partires da API 13 (Android 3.2) a forma de 'construír' os diálogos modificouse.

Se se usa a forma anteriormente explicada funcionará pero marcará no Compilador a liña como deprecated.

Android 2014 U3 15 Dialogos 1.JPG

Imos ver neste punto como poderíamos facer para construír os diálogos doutra forma.

Para explicalo teremos que falar antes dos DialogFragment e por extensión dos Fragment.

Información adicional:

Un fragment representa un 'trozo' da interface dun usuario. A idea dos fragment xurdiu polas dificultades que tiñan as aplicacións a adaptarse a tamaños grandes de pantalla (como as tablet´s).

Android 2014 U3 15 Dialogos 2.JPG
Imaxe obtida de [1]

Imaxinade que tedes unha aplicación que amosa unha lista de usuarios e que ó premer sobre un deles apareceran os seus datos completos.

Isto feito nun móbil cunha pantalla de 4 polgadas levaría consigo a creación de dúas activities, xa que na mesma non cabe toda a información (necesitaríamos usar scroll, bastante incómodo).

Esta mesma aplicación levada a unha tablet de 10 polgadas non tería problema en visualizar todo na mesma pantalla.

Os fragment vannos permitir dividir os elementos gráficos en 'anacos' que imos poder usar de forma independente nas activities. Así, no caso anterior podemos crear dous fragment, un coa lista e outro có detalle de cada usuario.

Agora dependendo do tamaño da pantalla podo facer que na pantalla pequena se amose un só fragment (a lista) é que o premer sobre un elemento da mesma apareza o outro fragment (o detalle).
Se o tamaño é grande (tablet) podo facer que aparezan os dous fragment na mesma activity.

O código que xestiona a pulsación dun elemento da lista e amosar os datos estará definido nun só sitio, o que modificamos é o sitio onde se visualiza o fragment en función do tamaño da pantalla.

Tendo claro o concepto de Fragment isto lévanos ao seguinte concepto: DialogFragment.



Creando os Dialogs

  • Imos facer a mesma práctica que no 'Caso pràctico 1' pero adaptándoa para non utilizar formas de chamar/crear a Dialogs 'deprecated'.
Se non o temos creado antes, crearemos un novo paquete de nome: Dialogs como un subpaquete do teu paquete principal.



  • Dentro do paquete Dialogs crear unha nova 'Empty Activity' de nome: UD03_02_Dialogs de tipo Launcher e sen compatibilidade.
Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.



  • Podemos facer uso de diferentes tipos de Dialogs:
  • Dialog cunha mensaxe
  • Dialog cunha mensaxe e un, dous botóns ou tres botóns.
  • Dialog cunha lista de selección na que aparece unha lista de opcións e escollemos unha.
  • Dialog cunha lista de selección na que aparece unha lista de opcións e escollemos unha pero graficamente diferenciase da anterior en que empregamos radiobuttons.
  • Dialog cunha lista de selección na que aparece unha lista de opcións e podemos escoller moitas (aparecen checkboxes)
  • Dialog definido por nos, no que teremos un layout e todos os controis que queiramos poñer.


O proceso de uso será o seguinte:
  • Crear un obxecto da clase anterior imos definir que botóns, texto,...vai ter (dentro das posibilidades que nos permita).
  • Chamar ao método create() da clase AlertDialog.Builder o cal devolverá un obxecto da clase AlertDialog.
  • Chamar ao método show() da clase AlertDialog.Builder o cal amosa o diálogo creado.





O layout da activity

  • O layout é o mesmo que no caso práctico 1 polo que o cargaremos dende o método onCreate()
Nota: Teredes que crear o layout da activity UD03_01_Dialogs, que ten de nome:activity_ud03_01__dialogs, pero so o layout, non tedes por que facer a práctica enteira.
  1.     @Override
  2.     protected void onCreate(Bundle savedInstanceState) {
  3.         super.onCreate(savedInstanceState);
  4.         setContentView(R.layout.activity_ud03_01__dialogs);     // Poñemos o mesmo layout que na activity UD03_01_Dialogs
  5.  
  6.     }



O código da Activity

  • Primeiro imos rexistrar os eventos de click dos diferentes botóns, implementando a interface OnClickListener a nivel de Activity:
  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.Dialogs;
  2.  
  3. import android.app.Activity;
  4. import android.content.DialogInterface;
  5. import android.os.Bundle;
  6. import android.app.AlertDialog;
  7. import android.view.View;
  8. import android.widget.Toast;
  9.  
  10. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  11.  
  12. public class UD03_02_Dialogs extends Activity implements View.OnClickListener {
  13.  
  14.     private void xestioarEventos(){
  15.  
  16.         findViewById(R.id.btnDlgBotons_UD03_01_Dialogs).setOnClickListener(this);
  17.         findViewById(R.id.btnDlgEntrada_UD03_01_Dialogs).setOnClickListener(this);
  18.         findViewById(R.id.btnDlgLista_UD03_01_Dialogs).setOnClickListener(this);
  19.         findViewById(R.id.btnDlgMensaxe_UD03_01_Dialogs).setOnClickListener(this);
  20.         findViewById(R.id.btnDlgMulSelec_UD03_01_Dialogs).setOnClickListener(this);
  21.         findViewById(R.id.btnDlgUnicaSel_UD03_01_Dialogs).setOnClickListener(this);
  22.     }
  23.  
  24.     @Override
  25.     protected void onCreate(Bundle savedInstanceState) {
  26.         super.onCreate(savedInstanceState);
  27.         setContentView(R.layout.activity_ud03_01__dialogs);     // Poñemos o mesmo layout que na activity UD03_01_Dialogs
  28.  
  29.         xestioarEventos();
  30.     }
  31.  
  32.     @Override
  33.     public void onClick(View v) {
  34.  
  35.         switch (v.getId()) {
  36.             case R.id.btnDlgMensaxe_UD03_01_Dialogs:
  37.  
  38.                 break;
  39.  
  40.             case R.id.btnDlgBotons_UD03_01_Dialogs:
  41.  
  42.                 break;
  43.  
  44.             case R.id.btnDlgLista_UD03_01_Dialogs:
  45.  
  46.                 break;
  47.  
  48.             case R.id.btnDlgUnicaSel_UD03_01_Dialogs:
  49.  
  50.                 break;
  51.  
  52.             case R.id.btnDlgMulSelec_UD03_01_Dialogs:
  53.  
  54.                 break;
  55.  
  56.             case R.id.btnDlgEntrada_UD03_01_Dialogs:
  57.  
  58.                 break;
  59.  
  60.             default:
  61.                 break;
  62.         }
  63.  
  64.  
  65.     }
  66. }



Diálogo con mensaxe
PDM Dialogos 12.jpg
  • Teremos que engadir o seguinte código ao método onClick():
  1.     @Override
  2.     public void onClick(View v) {
  3.         AlertDialog.Builder builder=null;   // Nos eventos de botón sempre imos 'construir' un Dialog
  4.  
  5.         switch (v.getId()) {
  6.             case R.id.btnDlgMensaxe_UD03_01_Dialogs:
  7.                 builder = new AlertDialog.Builder(this);
  8.                 builder.setTitle("Atención");
  9.                 builder.setMessage("Nova amensaxe. Preme o botón 'Back' para volver á pantalla principal");
  10.                 builder.setIcon(android.R.drawable.ic_dialog_email);
  11.                 builder.create();   // Devolve un Dialog, pero non o necesitamos polo de agora.
  12.                 builder.show();
  13.  
  14.                 break;
  • Liña 3: Para non ter que definir un obxecto da clase AlertDialog.Builder en cada caso do swith o definimos fora.
  • Liña 7: Instanciamos o obxecto.
  • Liña 8-10: Establecemos un título, a mensaxe e unha icona. Non son obrigatorios poñelos pero si aconsellable.
  • Liña 11: Chamamos ao método create() para que cre o Dialog.
  • Liña 12: Chamamos ao método show() para que amose o Dialog.


  • O código anterior tamén poderíamos escribilo así:
  1.                 builder = new AlertDialog.Builder(this)
  2.                     .setTitle("Atención")
  3.                     .setMessage("Nova amensaxe. Preme o botón 'Back' para volver á pantalla principal")
  4.                     .setIcon(android.R.drawable.ic_dialog_email);
  5.                 builder.create();   // Devolve un Dialog, pero non o necesitamos polo de agora.
  6.                 builder.show();
Fixarse que a liña do new non leva punto e coma, nen as seguintes ata a de setIcon.



Diálogo con botóns
PDM Dialogos 14.jpg


  • Como dixemos anteriormente podemos engadir ata 3 botóns e darlle a funcionalidade que queiramos. Normalmente teremos as opcións Aceptar/Cancelar.
A diferenza de xestionar o Click dos botóns vistos ata o de agora e que a interface que rexistra o evento é DialogInterface.OnClickListener.
A xestión de ditos botóns se fai con interface anónimas no mesmo sitio onde creamos o Dialog ou ven podemos facer como nos botóns e implementar a interface DialogInterface.OnClickListener a nivel de Activiry.
Ao igual que no resto de opcións non é obrigatorio poñer os tres botóns como no seguinte exemplo.


  • Engadimos o seguinte código ao método OnClick():
  1.             case R.id.btnDlgBotons_UD03_01_Dialogs:
  2.                         builder = new AlertDialog.Builder(this)
  3.                         .setTitle("Caixa de diálogo").setIcon(R.drawable.ic_launcher)
  4.                         .setMessage("QUE TE PARACE ESTE DIALOGO ?")
  5.  
  6.                         .setPositiveButton("Ben", new DialogInterface.OnClickListener() {
  7.                             @Override
  8.                             public void onClick(DialogInterface dialog, int which) {
  9.                                 Toast.makeText(getApplicationContext(), "PULSADA OPCION BOA",Toast.LENGTH_LONG).show();
  10.                             }
  11.                         })
  12.  
  13.                         .setNegativeButton("MAL", new DialogInterface.OnClickListener() {
  14.                             @Override
  15.                             public void onClick(DialogInterface dialog, int which) {
  16.  
  17.                                 Toast.makeText(getApplicationContext(),"PULSADA OPCION MALA", Toast.LENGTH_LONG).show();
  18.                             }
  19.                         })
  20.  
  21.                         .setNeutralButton("NON SEI", new DialogInterface.OnClickListener() {
  22.                             @Override
  23.                             public void onClick(DialogInterface dialog, int which) {
  24.  
  25.                                 Toast.makeText(getApplicationContext(),"PULSADA OPCION NON SEI", Toast.LENGTH_LONG).show();
  26.                             }
  27.                         });
  28.  
  29.                 builder.create();
  30.                 builder.show();
  31.  
  32.                 break;


  • Como vemos o evento de click é moi parecido ao feito cos botóns.
Neste caso estamos implementando Interface Anónimas. Neste caso lembrar que 'this' fai referencia ao Dialog, non a Activity polo que se necesitades ter unha referencia ao Context podemos utilizar o método getApplicationContext().
Se necesitades acceder a algo da Activity dentro da interface, podemos facer como no caso dos botóns. Declarar a obxecto como final fora da forma:
  1.             case R.id.btnDlgBotons_UD03_01_Dialogs:
  2.                 final Button btnOpcion = findViewById(R.id.btnDlgBotons_UD03_01_Dialogs);
  3.  
  4.                 builder = new AlertDialog.Builder(this)
  5.                 .setTitle("Caixa de diálogo").setIcon(R.drawable.ic_launcher)
  6.                 .setMessage("QUE TE PARACE ESTE DIALOGO ?")
  7.  
  8.                 .setPositiveButton("Ben", new DialogInterface.OnClickListener() {
  9.                     @Override
  10.                     public void onClick(DialogInterface dialog, int which) {
  11.                         Toast.makeText(getApplicationContext(), "PULSADA OPCION BOA",Toast.LENGTH_LONG).show();
  12.                         btnOpcion.setText(btnOpcion.getText().toString().concat("-OK"));
  13.                     }
  14.                 })
  15.                 .setNegativeButton("MAL", new DialogInterface.OnClickListener() {
  16.                     @Override
  17.                     public void onClick(DialogInterface dialog, int which) {
  18.                         //
  19.  
  20.                         Toast.makeText(getApplicationContext(),"PULSADA OPCION MALA", Toast.LENGTH_LONG).show();
  21.                     }
  22.                 })
  23.                 .setNeutralButton("NON SEI", new DialogInterface.OnClickListener() {
  24.                     @Override
  25.                     public void onClick(DialogInterface dialog, int which) {
  26.  
  27.                         Toast.makeText(getApplicationContext(),"PULSADA OPCION NON SEI", Toast.LENGTH_LONG).show();
  28.                     }
  29.                 });
  30.  
  31.                 builder.create();
  32.                 builder.show();
  33.  
  34.                 break;
  • Nesta imaxe podemos ver como o texto do botón se modifica cando se preme no botón 'Ben':
PDM Dialogos 24.jpg


  • No caso de implementar a Interface a nivel da Activity como xa vimos nesta Wiki, ao método onClick chegará como información o Diálog e o botón que foi premido.
  • No caso dos Dialog, se temos varios que van a mesma interface, teremos que telos definidos a nivel global, dentro da Activity da forma:
  1. public class UD03_02_Dialogs extends Activity implements View.OnClickListener, DialogInterface.OnClickListener {
  2.  
  3.     private Dialog dialog1,dialog2;
  4.  
  5.     ....
  6.     @Override
  7.     public void onClick(DialogInterface dialog, int which) {
  8.         if (dialog==dialog1){
  9.             if (which==DialogInterface.BUTTON_POSITIVE){
  10.  
  11.             }
  12.         }        
  13.     }
  14.  
  15.  
  16.     @Override
  17.     public void onClick(View v) {
  18.         AlertDialog.Builder builder=null;   // Nos eventos de botón sempre imos 'construir' un Dialog
  19.  
  20.         switch (v.getId()) {
  21.  
  22.             case R.id.btnDlgBotons_UD03_01_Dialogs:
  23.                 final Button btnOpcion = findViewById(R.id.btnDlgBotons_UD03_01_Dialogs);
  24.  
  25.                 builder = new AlertDialog.Builder(this)
  26.                 .setTitle("Caixa de diálogo").setIcon(R.drawable.ic_launcher)
  27.                 .setMessage("QUE TE PARACE ESTE DIALOGO ?")
  28.  
  29.                 .setPositiveButton("Ben", new DialogInterface.OnClickListener(this);
  30.  
  31.                 .setNegativeButton("MAL", new DialogInterface.OnClickListener(this);
  32.  
  33.                 dialog1 = builder.create();
  34.                 builder.show();
  35.  
  36.                 break;
Liña 1: Implementamos a interface DialogInterface.OnClickListener
Liña 3: Definimos os Dialog que imos a usar a nivel global para poder referencialos.
Liñas 6-13: Aquí xestionamos o evento OnClick de todos os botóns de todos os diálogos que rexistren o evento contra a interface da Activity.
Liña 33: Na liña 33 asociamos o diálogo creado para poder ter unha referencia ao mesmo fora do método.



  • Indicar que se queremos pechar o diálogo cando prememos uns dos botóns, o podemos facer chamando ao método dismiss do diálogo. A referencia ao diálogo a temos no método que implementa a interface de xestión de eventos do mesmo:
  1.         builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  2.             @Override
  3.             public void onClick(DialogInterface dialog, int which) {
  4.                 dialog.dismiss();
  5.             }
  6.         });




Diálogo Lista de Selección
PDM Dialogos 16.jpg


  • Neste tipo de diálogo van saír unha serie de opcións.
Neste exemplo imos obter esas opcións dun String-Array definido en /res/values, pero poderíamos empregar calquera fonte de datos, que gardaríamos nun array e o pasaríamos como parámetro.
Se xa fixeches a práctica 1 xa o tedes definido e non fai falla facelo.
  • Aproveitamos o ficheiro /res/values/strings.xml e definimos un recurso de tipo Array, para a lista de selección e para a selección múltiple.


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <resources>
  4.     <string name="app_name">Aprendiendo</string>
  5.  
  6.  
  7.     <string-array name="array_elem_seleccion1_ud03_01_dialogs">
  8.         <item>Opción un</item>
  9.         <item>Opción dous</item>
  10.         <item>Opción tres</item>
  11.         <item>Opción catro</item>
  12.     </string-array>
  13.  
  14.  
  15. </resources>



  • O código da Activity no método onClick(View v) quedaría así:
  1.             case R.id.btnDlgLista_UD03_01_Dialogs:
  2.                 builder = new AlertDialog.Builder(this);
  3.                 builder.setIcon(android.R.drawable.ic_dialog_alert)
  4.                     .setTitle("Escolle unha opción")
  5.                     .setItems(R.array.array_elem_seleccion1_ud03_01_dialogs, new DialogInterface.OnClickListener() {
  6.                     public void onClick(DialogInterface dialog, int posicion) {
  7.                         // O usuario selecciona unha das opcións do listado
  8.                         String[] opcions = getResources().getStringArray(R.array.array_elem_seleccion1_ud03_01_dialogs);
  9.                         Toast.makeText(getApplicationContext(), "Seleccionaches: '" + opcions[posicion] + "'", Toast.LENGTH_LONG).show();
  10.                     }
  11.                 });
  12.                 builder.create();
  13.                 builder.show();
  14.  
  15.                 break;
  • Liña 5: Se fai uso do método setItems da clase AlertDialog.Builder (o cal está sobrecargado, podedes comprobalo no enlace). Na opción escollida espera recibir dous parámetros. No primeiro o id da clase R que fai referencia a un 'array-adapter' e o segundo un obxecto que implemente a interface DialogInterface.OnClickListener. No exemplo estamos a empregar unha interface anónima.
Ao evento onClick() chegará a posición do elemento seleccionado. Como temos unha referencia ao array con todos os datos, podemos saber cal foi a opción escollida.




Diálogo cunha única selección (radiobuttons)
PDM Dialogos 17.jpg


  • Neste tipo de diálogo van saír unha serie de opcións pero cunha aparencia de radiobuttons para que marquemos unha soa opción e despois premamos un botón de conformación de selección.



  • O código da Activity no método onClick(View v) quedaría así:
  1.             case R.id.btnDlgUnicaSel_UD03_01_Dialogs:
  2.                 builder = new AlertDialog.Builder(this)
  3.                     .setIcon(android.R.drawable.ic_dialog_info)
  4.                     .setTitle("Selecciona un smartpohone");
  5.                 // Non incluír mensaxe dentro de este tipo de diálogo!!!
  6.                 final CharSequence[] smartphones = { "iPhone", "Blackberry", "Android" };
  7.                
  8.                 builder.setSingleChoiceItems(smartphones, 0, new DialogInterface.OnClickListener() {
  9.                     public void onClick(DialogInterface dialog, int opcion) {
  10.                         // Evento que ocorre cando o usuario selecciona una opción
  11.                         Toast.makeText(getApplicationContext(), "Seleccionaches: " + smartphones[opcion], Toast.LENGTH_SHORT).show();
  12.                     }
  13.                 });
  14.                
  15.                 builder.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  16.                     public void onClick(DialogInterface dialog, int boton) {
  17.                         Toast.makeText(getApplicationContext(), "Premeches 'Aceptar'", Toast.LENGTH_LONG).show();
  18.                     }
  19.                 });
  20.                
  21.                 builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  22.                     public void onClick(DialogInterface dialog, int boton) {
  23.                         Toast.makeText(getApplicationContext(), "Premeches 'Cancelar'", Toast.LENGTH_LONG).show();
  24.                     }
  25.                 });
  26.                
  27.                 builder.create();
  28.                 builder.show();
  29.  
  30.  
  31.             break;
  • Liña 6: Definimos as opcións nun array CharSequence[].Poderíamos empregar igual que no caso anterior un array-string definido en /res/ pero poño este exemplo de uso para que vexades diferentes opcións.
  • Liña 8: Facendo uso do método setSingleChoiceItems() o cal está sobrecargado, enviamos o array cos datos, como segundo parámetro o elemento seleccionado da lista por defecto e como terceiro parámetro implementamos a interface DialogInterface.OnClickListener().



Diálogo cunha selección múltiple (checkboxes)
PDM Dialogos 19.jpg


  • Neste tipo de diálogo van saír unha serie de opcións pero cunha aparencia de radiobuttons para que marquemos unha soa opción e despois premamos un botón de conformación de selección.
Neste exemplo imos obter esas opcións dun String-Array definido en /res/values, pero poderíamos empregar calquera fonte de datos, que gardaríamos nun array e o pasaríamos como parámetro.
Se xa fixeches a práctica 1 xa o tedes definido e non fai falla facelo.
  • Aproveitamos o ficheiro /res/values/strings.xml e definimos un recurso de tipo Array, para a lista de selección e para a selección múltiple.


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <resources>
  4.  
  5.     <string-array name="array_elem_seleccion2_ud03_01_dialogs">
  6.         <item>Coche</item>
  7.         <item>Moto</item>
  8.         <item>Bici</item>
  9.         <item>Metro</item>
  10.         <item>Tren</item>
  11.         <item>Autobús</item>
  12.         <item>Andando</item>
  13.     </string-array>
  14.  
  15.  
  16. </resources>




  • O código da Activity no método onClick(View v) quedaría así:
  1.             case R.id.btnDlgMulSelec_UD03_01_Dialogs:
  2.  
  3.                 builder = new AlertDialog.Builder(this)
  4.                     .setIcon(android.R.drawable.ic_dialog_info)
  5.                     .setTitle("Selecciona modos de transporte");
  6.  
  7.                 Resources res = getResources();
  8.                 final String[] matriz = res.getStringArray(R.array.array_elem_seleccion2_ud03_01_dialogs);
  9.  
  10.                 // Non incluír mensaxe dentro de este tipo de diálogo!!!
  11.                 builder.setMultiChoiceItems(matriz, new boolean[] { false, true, false, true, false, false, false }, new DialogInterface.OnMultiChoiceClickListener() {
  12.                     public void onClick(DialogInterface dialog, int opcion, boolean isChecked) {
  13.                         // Evento que ocorre cando o usuario selecciona unha opción
  14.                         if (isChecked)
  15.                             Toast.makeText(getApplicationContext(), "Seleccionaches " + matriz[opcion], Toast.LENGTH_SHORT).show();
  16.                         else
  17.                             Toast.makeText(getApplicationContext(), "Deseleccionaches " + matriz[opcion], Toast.LENGTH_SHORT).show();
  18.                     }
  19.                 });
  20.  
  21.                 builder.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  22.                     public void onClick(DialogInterface dialog, int boton) {
  23.                         Toast.makeText(getApplicationContext(), "Premeches 'Aceptar'", Toast.LENGTH_LONG).show();
  24.  
  25.                     }
  26.                 });
  27.                 builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  28.                     public void onClick(DialogInterface dialog, int boton) {
  29.                         Toast.makeText(getApplicationContext(), "Premeches 'Cancelar'", Toast.LENGTH_LONG).show();
  30.                     }
  31.                 });
  32.  
  33.                 builder.create();
  34.                 builder.show();
  35.  
  36.             break;
  • Liña 7-8: Recuperamos o string-array de /res/. O declaramos final xa que imos referencial dentro da interface anónima.
  • Liña 11: Empregamos o método setMultiChoiceItems() o cal está sobrecargado. Neste caso, enviamos un array de strings como primeiro parámetro, como segundo parámetro leva un array de booleans indicando cales dos elementos da lista están chequeados ou non, e como terceiro parámetro implementamos a interface DialogInterface.OnMultiChoiceClickListener().
Se no segundo parámetro enviamos null, todos os elementos da lista estarán deseleccionados.

Dialog personalizado: DialogFragment

  • Un DialogFragment é un Fragment que amosa unha ventá de diálogo e situase por enriba da nosa Activity.
A vantaxe que ten con respecto aos díalogos 'predefinidos' é que podemos ter calquera deseño que queiramos xa que vai estar asociado a un Layout propio.
PDM Dialogos 21.jpg



PDM Dialogos 6.JPG


Esta forma de crear un diálogo tamén está deprecated dende a versión API 28, Android P
Android recomenda facer uso da biblioteca de compatibilidade com.android.support:support-v4:27.0.0 tanto para dar soporte a dispositivos anteriores a API 22 como con dispositivos posteriores a API 28.
Nota: Deberedes cambiar o número 27.0.0 pola versión compileSdkVersion do arquivo build.gradle.
Lembra que xa vimos como engadir unha biblioteca de compatibilidade nesta wiki


  • Ao facer uso da biblioteca de compatibilidade, cando cremos un DialogFragment teremos que importar a clase correcta, xa que teremos dúas opcións, a que ven coa biblioteca de compatibilidade e a 'orixinal'.
PDM Dialogos 10.jpg


Polo tanto na nosa activity terá que está importada a que provén da biblioteca de compatibilidade.
  1. import android.support.v4.app.DialogFragment;


  • Ao empregar esta biblioteca Android Studio non deixará empregar unha Activity e teremos que facer uso da clase AppCompactActivity.
  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.Dialogs;
  2.  
  3. import android.app.AlertDialog;
  4. import android.app.Dialog;
  5. import android.content.DialogInterface;
  6. import android.content.res.Resources;
  7. import android.os.Bundle;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.view.View;
  10. import android.widget.Button;
  11. import android.widget.Toast;
  12.  
  13. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  14.  
  15. public class UD03_02_Dialogs extends AppCompatActivity implements View.OnClickListener {


  • Ao cambiar a activity o Theme por defecto non poderá ser empregado.
Como xa vimos nesta Wiki o theme por defecto a nivel do proxecto se atopa no arquivo styles.xml de /res/values/ e ten:
  1. <resources>
  2.     <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
  3.         <!-- Customize your theme here. -->
  4.     </style>
  5. </resources>
Agora, para que se vexa correctamente,debería ter isto:
  1. <resources>
  2.     <style name="AppTheme" parent="android:Theme.AppCompat.Light.DarkActionBar">
  3.         <!-- Customize your theme here. -->
  4.     </style>
  5. </resources>
Fixádevos que deriva de Theme.AppCompact.
Pero se o facemos a este nivel, afectará a todas as activities. Se tedes todos as activities derivando de AppCompatActivity non tedes problema, pero se non é o caso, deberedes de asinar o theme anterior pero o nivel desa Activity concreta.
Unha forma de facelo é modificando o arquivo AndroidManifiest.xml para esa Activity (outra forma sería no layout desa activity):
  1.         <activity android:name=".Dialogs.UD03_02_Dialogs" android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
  2.            android:label="UD03_02_Dialogs">




  • Un DialogFragment vai ter un layout asociado que vai compoñer o seu contido.
Definimos polo tanto o contido do noso diálogo.


O XML do DialogFragment

Código da clase fragment_u3_15_layout_dialogo

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    xmlns:app="http://schemas.android.com/apk/res-auto"
  4.    xmlns:tools="http://schemas.android.com/tools"
  5.    android:layout_width="match_parent"
  6.    android:layout_height="match_parent">
  7.  
  8.     <EditText
  9.        android:id="@+id/etPass_Dlg_UD03_02_Dialogs"
  10.        android:layout_width="0dp"
  11.        android:layout_height="wrap_content"
  12.        android:layout_marginEnd="8dp"
  13.        android:layout_marginStart="8dp"
  14.        android:contentDescription="Introduce o password"
  15.        android:inputType="textPassword"
  16.        android:textColor="@android:color/holo_blue_dark"
  17.        app:layout_constraintBottom_toBottomOf="@+id/tvNome_Dlg_UD03_02_Dialogs"
  18.        app:layout_constraintEnd_toEndOf="parent"
  19.        app:layout_constraintHorizontal_bias="0.0"
  20.        app:layout_constraintStart_toStartOf="@+id/guideline" />
  21.  
  22.     <TextView
  23.        android:id="@+id/tvNome_Dlg_UD03_02_Dialogs"
  24.        android:layout_width="wrap_content"
  25.        android:layout_height="0dp"
  26.        android:layout_marginStart="16dp"
  27.        android:layout_marginTop="28dp"
  28.        android:text="Contrasinal:"
  29.        android:textSize="18sp"
  30.        app:layout_constraintStart_toStartOf="parent"
  31.        app:layout_constraintTop_toBottomOf="@+id/tvPass_Dlg_UD03_02_Dialogs" />
  32.  
  33.     <TextView
  34.        android:id="@+id/tvPass_Dlg_UD03_02_Dialogs"
  35.        android:layout_width="wrap_content"
  36.        android:layout_height="wrap_content"
  37.        android:layout_marginStart="16dp"
  38.        android:layout_marginTop="16dp"
  39.        android:text="Nome:"
  40.        android:textSize="18sp"
  41.        app:layout_constraintStart_toStartOf="parent"
  42.        app:layout_constraintTop_toTopOf="parent" />
  43.  
  44.     <android.support.constraint.Guideline
  45.        android:id="@+id/guideline"
  46.        android:layout_width="wrap_content"
  47.        android:layout_height="wrap_content"
  48.        android:orientation="vertical"
  49.        app:layout_constraintGuide_begin="111dp" />
  50.  
  51.     <EditText
  52.        android:id="@+id/etNome_Dlg_UD03_02_Dialogs"
  53.        android:layout_width="0dp"
  54.        android:layout_height="wrap_content"
  55.        android:layout_marginEnd="8dp"
  56.        android:layout_marginStart="8dp"
  57.        android:contentDescription="Introduce o nome"
  58.        android:focusedByDefault="true"
  59.        android:textColor="@android:color/holo_blue_dark"
  60.        app:layout_constraintBottom_toBottomOf="@+id/tvPass_Dlg_UD03_02_Dialogs"
  61.        app:layout_constraintEnd_toEndOf="parent"
  62.        app:layout_constraintHorizontal_bias="0.0"
  63.        app:layout_constraintStart_toStartOf="@+id/guideline" />
  64.  
  65.     <Button
  66.        android:id="@+id/btnPechar_Frg_UD03_02_Dialogs"
  67.        android:layout_width="304dp"
  68.        android:layout_height="wrap_content"
  69.        android:layout_marginBottom="8dp"
  70.        android:layout_marginEnd="8dp"
  71.        android:layout_marginStart="8dp"
  72.        android:layout_marginTop="8dp"
  73.        android:text="Pecha o Diálogo"
  74.        app:layout_constraintBottom_toBottomOf="parent"
  75.        app:layout_constraintEnd_toEndOf="parent"
  76.        app:layout_constraintStart_toStartOf="parent"
  77.        app:layout_constraintTop_toBottomOf="@+id/etPass_Dlg_UD03_02_Dialogs" />
  78. </android.support.constraint.ConstraintLayout>

Agora deberemos crear unha clase que vai representar o DialogFragment e que vai cargar o layout anterior. Esta clase será a que instanciaremos dende a nosa Activity.

O código Java do DialogFragment

  • Debemos ter en conta que este Dialog vai pedir unha información ao usuario (usuario-password)
Debemos implementar algunha forma de recuperar dita información por parte da Activity principal que chama a este Dialog.
Unha forma de facelo será crear no DialogFragment unha clase con campos que garden a información.
Dentro do DialogFragment crearemos un obxecto (neste caso public, pero poderíamos crear un método public getDato() e facer private ao obxecto) o cal imos poder acceder dende a Activity principal.


  • Se por algún motivo necesitamos acceder a métodos ou o contexto da Activity que chamou a este diálogo, podemos facer uso do método getActivity(), da forma:
  • Button btn = getActivity().findViewById(R.id.identificador); // Soamente podemos acceder a Views da Activity, non podemos referenciar as views do DialogFragment.
  • getActivity().getApplicationContext()


  • Se por algún motivo queremos acceder aos elementos gráficos (views) que se atopan dentro do layout do DialogFragment, dentro do código do mesmo, deberemos facer uso do método 'inflate' para obter unha referencia por programación e facer uso do método 'findVuewById()' do view que representa o layout:
  1. public class ExemploDialogo extends DialogFragment {
  2.  
  3.     private View rootView;
  4.  
  5.     @Override
  6.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  7.  
  8.         rootView = inflater.inflate(R.layout.fragment_ud03_02_layout_dialogo, container, false);
  9.  
  10.         Button btn = (Button) rootView.findViewById(R.id.btnEnDialogo);   // Exemplo de referencia a un view dentro do layout do DialogFragment
  11.  
  12.        
  13.         return rootView;
  14.     }
  15. }
Como vemos, no caso do DialogFragment, o método onCreateView() deberá devolver o view que representa o layout do DialogFragment.
Desta forma poderíamos, por exemplo, sacar unha foto dentro dun DialogFragment poñendo o método onActivityResult() dentro do seu código para obter a foto sacada e cambiar o ImageView.



Nota: Ao poñer o código que ven a continuación vos dará un erro na liña 41. Isto é debido a que dita liña chama a un método da Activity principal que aínda non está creado. Está posto despois.

Código da clase UD3_15_DialogoFragmento
Obxectivo: Clase que representa ó DialogFragment

  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.Dialogs;
  2.  
  3. import android.os.Bundle;
  4. import android.support.v4.app.DialogFragment;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.widget.Button;
  9. import android.widget.EditText;
  10.  
  11. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  12.  
  13. class DatosDialogFragment{
  14.     public String nome;
  15.     public String password;
  16. }
  17.  
  18. public class UD03_02_Dlg_Fragments extends DialogFragment {
  19.     public DatosDialogFragment datosDialogFragment;
  20.  
  21.  
  22.     @Override
  23.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  24.  
  25.         datosDialogFragment = new DatosDialogFragment();
  26.  
  27.         final View rootView = inflater.inflate(R.layout.fragment_ud03_02_layout_dialogo, container, false);
  28.         getDialog().setTitle(getTag());         // O Tag se envía dende a activiy có método show.
  29.  
  30.         Button btn = (Button) rootView.findViewById(R.id.btnPechar_Frg_UD03_02_Dialogs);
  31.         btn.setOnClickListener(new View.OnClickListener() {
  32.  
  33.             @Override
  34.             public void onClick(View v) {
  35.                 // TODO Auto-generated method stub
  36.                 EditText editNome = rootView.findViewById(R.id.etNome_Dlg_UD03_02_Dialogs);
  37.                 EditText editPassword = rootView.findViewById(R.id.etPass_Dlg_UD03_02_Dialogs);
  38.                 datosDialogFragment.nome = editNome.getText().toString();
  39.                 datosDialogFragment.password = editPassword.getText().toString();
  40.  
  41.                 ((UD03_02_Dialogs)UD03_02_Dlg_Fragments.this.getActivity()).pecharDialogo();  // Poderíamos chamar a algún método da Activity que abriu o Dialog se queremos
  42.                 dismiss();
  43.             }
  44.         });
  45.  
  46.         // Do something else
  47.         return rootView;
  48.     }
  49.  
  50.     /*
  51.     Se queremos darlle un tamaño específico ao layout do Dialog, podemos indicalo aquí, pero tendo en conta que sería un tamaño fixo e por tanto non se adaptaría a diferentes tamaños (por exemplo cando rotamos)
  52.     @Override
  53.     public void onResume(){
  54.         super.onResume();
  55.  
  56.         int width = getResources().getDimensionPixelSize(R.dimen.dimen_width_fragment_03_02_dialogs);  // As medidas no arquivo de recursos tería o valor: XXXdp
  57.         int height = getResources().getDimensionPixelSize(R.dimen.dimen_height_fragment_03_02_dialogs);
  58.         getDialog().getWindow().setLayout(width, height);
  59.     }
  60.     */
  61. }

Analicemos o código.

  • Liña 4: Estamos a utilizar a librería de compatibilidade con versións anteriores de Android.
  • Liña 18: A nosa clase deriva de DialogFragment.
  • Liña 13-16: Esta é a clase que vai gardar os datos introducidos polo usuario no DialogFragment
  • Liña 23-48: O DialogFragment ten que devolver o View que conforma todo o diálogo. Sobreescribimos o método onCreateView() para facelo.
  • Liña 25: Instacimos o obxecto que vai gardar os datos introducidos no Dialog.
  • Liña 27,28: Veremos na activity principal, que cando instanciamos o DialogFragment, podemos pasarlle unha cadea de texto. Para recuperar esa cadea debemos facer uso do método getTag(). Non é obrigatorio pasala.
  • Liña 18: Buscamos dentro do layout do DialogFragment os botóns que queiramos xestionar. Neste caso soamente hai un.
  • Liña 36-39: Ao facer Click sobre o botón, buscamos os datos introducidos e os gardamos na propiedade 'datosDialogFragment' que será a cal accedamos dende a Activity principal.
  • Liña 41: Cando o DialogFragment se peche, necesitamos informar dalgunha maneira a Activity principal. Chamaremos por tanto a un método dela (é unha forma de facelo).
  • Liña 42: Pechamos o diálogo.



O código Java da Activity

Agora implantaremos a activity que vai facer uso do DialogFragment.

Aquí teremos dúas opcións:

  • Derivar a clase de Activity. Deberemos facer uso do método getFragmentManager().
  • Derivar a clase de FragmentActivity. Esta clase é unha subclase de Activity e está posta por compatibilidade coas versións anteriores.
No caso de utilizar esta clase deberemos facer uso do método getSupportFragmentManager. No noso exemplo imos facer uso deste método.

Código da clase UD03_02_Dialogs
Obxectivo: Amosar un diálogo baseado en Fragment.

  1. package es.cursoandroid.cifprodolfoucha.aprendiendo.Dialogs;
  2.  
  3. import android.app.AlertDialog;
  4. import android.content.DialogInterface;
  5. import android.content.res.Resources;
  6. import android.os.Bundle;
  7. import android.support.v4.app.FragmentManager;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.text.Html;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Button;
  13. import android.widget.Toast;
  14.  
  15. import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
  16.  
  17. public class UD03_02_Dialogs extends AppCompatActivity implements View.OnClickListener {
  18.  
  19.     private UD03_02_Dlg_Fragments dialogoFragmento;
  20.  
  21.     private void xestioarEventos(){
  22.  
  23.         findViewById(R.id.btnDlgBotons_UD03_01_Dialogs).setOnClickListener(this);
  24.         findViewById(R.id.btnDlgEntrada_UD03_01_Dialogs).setOnClickListener(this);
  25.         findViewById(R.id.btnDlgLista_UD03_01_Dialogs).setOnClickListener(this);
  26.         findViewById(R.id.btnDlgMensaxe_UD03_01_Dialogs).setOnClickListener(this);
  27.         findViewById(R.id.btnDlgMulSelec_UD03_01_Dialogs).setOnClickListener(this);
  28.         findViewById(R.id.btnDlgUnicaSel_UD03_01_Dialogs).setOnClickListener(this);
  29.     }
  30.  
  31.     @Override
  32.     protected void onCreate(Bundle savedInstanceState) {
  33.         super.onCreate(savedInstanceState);
  34.         setContentView(R.layout.activity_ud03_01__dialogs);     // Poñemos o mesmo layout que na activity UD03_01_Dialogs
  35.  
  36.         xestioarEventos();
  37.         dialogoFragmento = new UD03_02_Dlg_Fragments();     // Deixamos instanciado o DialogFragment. Poderíamos facelo no intre que o creamos.
  38.  
  39.     }
  40.  
  41.     @Override
  42.     public void onClick(View v) {
  43.         AlertDialog.Builder builder=null;   // Nos eventos de botón sempre imos 'construir' un Dialog
  44.  
  45.         switch (v.getId()) {
  46.             case R.id.btnDlgMensaxe_UD03_01_Dialogs:
  47.                 builder = new AlertDialog.Builder(this)
  48.                     .setTitle("Atención")
  49.                     .setMessage("Nova amensaxe. Preme o botón 'Back' para volver á pantalla principal")
  50.                     .setIcon(android.R.drawable.ic_dialog_email);
  51.                 builder.create();   // Devolve un Dialog, pero non o necesitamos polo de agora.
  52.                 builder.show();
  53.  
  54.                 break;
  55.  
  56.             case R.id.btnDlgBotons_UD03_01_Dialogs:
  57.                 final Button btnOpcion = findViewById(R.id.btnDlgBotons_UD03_01_Dialogs);
  58.  
  59.                 builder = new AlertDialog.Builder(this)
  60.                 .setTitle("Caixa de diálogo").setIcon(R.drawable.ic_launcher)
  61.                 .setMessage("QUE TE PARACE ESTE DIALOGO ?")
  62.  
  63.                 .setPositiveButton("Ben", new DialogInterface.OnClickListener() {
  64.                     @Override
  65.                     public void onClick(DialogInterface dialog, int which) {
  66.                         Toast.makeText(getApplicationContext(), "PULSADA OPCION BOA",Toast.LENGTH_LONG).show();
  67.                         btnOpcion.setText(btnOpcion.getText().toString().concat("-OK"));
  68.                     }
  69.                 })
  70.                 .setNegativeButton("MAL", new DialogInterface.OnClickListener() {
  71.                     @Override
  72.                     public void onClick(DialogInterface dialog, int which) {
  73.  
  74.                             Toast.makeText(getApplicationContext(),"PULSADA OPCION MALA", Toast.LENGTH_LONG).show();
  75.  
  76.                     }
  77.                 })
  78.                 .setNeutralButton("NON SEI", new DialogInterface.OnClickListener() {
  79.                     @Override
  80.                     public void onClick(DialogInterface dialog, int which) {
  81.  
  82.                         Toast.makeText(getApplicationContext(),"PULSADA OPCION NON SEI", Toast.LENGTH_LONG).show();
  83.                     }
  84.                 });
  85.  
  86.                 builder.create();
  87.                 builder.show();
  88.  
  89.                 break;
  90.  
  91.             case R.id.btnDlgLista_UD03_01_Dialogs:
  92.                 builder = new AlertDialog.Builder(this);
  93.                 builder.setIcon(android.R.drawable.ic_dialog_alert)
  94.                     .setTitle("Escolle unha opción")
  95.                     .setItems(R.array.array_elem_seleccion1_ud03_01_dialogs, new DialogInterface.OnClickListener() {
  96.                     public void onClick(DialogInterface dialog, int posicion) {
  97.                         // O usuario selecciona unha das opcións do listado
  98.                         String[] opcions = getResources().getStringArray(R.array.array_elem_seleccion1_ud03_01_dialogs);
  99.                         Toast.makeText(getApplicationContext(), "Seleccionaches: '" + opcions[posicion] + "'", Toast.LENGTH_LONG).show();
  100.                     }
  101.                 });
  102.                 builder.create();
  103.                 builder.show();
  104.  
  105.                 break;
  106.  
  107.             case R.id.btnDlgUnicaSel_UD03_01_Dialogs:
  108.                 builder = new AlertDialog.Builder(this)
  109.                     .setIcon(android.R.drawable.ic_dialog_info)
  110.                     .setTitle("Selecciona un smartpohone");
  111.                 // Non incluír mensaxe dentro de este tipo de diálogo!!!
  112.                 final CharSequence[] smartphones = { "iPhone", "Blackberry", "Android" };
  113.  
  114.                 builder.setSingleChoiceItems(smartphones, 0, new DialogInterface.OnClickListener() {
  115.                     public void onClick(DialogInterface dialog, int opcion) {
  116.                         // Evento que ocorre cando o usuario selecciona una opción
  117.                         Toast.makeText(getApplicationContext(), "Seleccionaches: " + smartphones[opcion], Toast.LENGTH_SHORT).show();
  118.                     }
  119.                 });
  120.  
  121.                 builder.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  122.                     public void onClick(DialogInterface dialog, int boton) {
  123.                         Toast.makeText(getApplicationContext(), "Premeches 'Aceptar'", Toast.LENGTH_LONG).show();
  124.                     }
  125.                 });
  126.  
  127.                 builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  128.                     public void onClick(DialogInterface dialog, int boton) {
  129.                         Toast.makeText(getApplicationContext(), "Premeches 'Cancelar'",  Toast.LENGTH_LONG).show();
  130.                     }
  131.                 });
  132.  
  133.                 builder.create();
  134.                 builder.show();
  135.  
  136.  
  137.             break;
  138.  
  139.             case R.id.btnDlgMulSelec_UD03_01_Dialogs:
  140.  
  141.                 builder = new AlertDialog.Builder(this)
  142.                     .setIcon(android.R.drawable.ic_dialog_info)
  143.                     .setTitle("Selecciona modos de transporte");
  144.  
  145.                 Resources res = getResources();
  146.                 final String[] matriz = res.getStringArray(R.array.array_elem_seleccion2_ud03_01_dialogs);
  147.  
  148.                 // Non incluír mensaxe dentro de este tipo de diálogo!!!
  149.                 builder.setMultiChoiceItems(matriz, new boolean[] { false, true, false, true, false, false, false }, new DialogInterface.OnMultiChoiceClickListener() {
  150.                     public void onClick(DialogInterface dialog, int opcion, boolean isChecked) {
  151.                         // Evento que ocorre cando o usuario selecciona unha opción
  152.                         if (isChecked)
  153.                             Toast.makeText(getApplicationContext(), "Seleccionaches " + matriz[opcion], Toast.LENGTH_SHORT).show();
  154.                         else
  155.                             Toast.makeText(getApplicationContext(), "Deseleccionaches " + matriz[opcion], Toast.LENGTH_SHORT).show();
  156.                     }
  157.                 });
  158.  
  159.                 builder.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
  160.                     public void onClick(DialogInterface dialog, int boton) {
  161.                         Toast.makeText(getApplicationContext(), "Premeches 'Aceptar'", Toast.LENGTH_LONG).show();
  162.  
  163.                     }
  164.                 });
  165.                 builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
  166.                     public void onClick(DialogInterface dialog, int boton) {
  167.                         Toast.makeText(getApplicationContext(), "Premeches 'Cancelar'", Toast.LENGTH_LONG).show();
  168.                     }
  169.                 });
  170.  
  171.                 builder.create();
  172.                 builder.show();
  173.  
  174.             break;
  175.  
  176.             case R.id.btnDlgEntrada_UD03_01_Dialogs:
  177.                 FragmentManager fm = getSupportFragmentManager();
  178.                 dialogoFragmento.show(fm, "EXEMPLO DE DIALOGO!!!!");        // Enviamos no segundo parámetro información que vai recibir o DialogFragment có método getTag().
  179.                 break;
  180.  
  181.             default:
  182.                 break;
  183.         }
  184.  
  185.  
  186.     }
  187.  
  188.     protected void pecharDialogo(){
  189.         // O DialogFragment tamén pode chamar a métodos da activity que o invocou
  190.         Toast.makeText(this, Html.fromHtml("NOME:"+ dialogoFragmento.datosDialogFragment.nome + "<br/>PASSWORD:"+dialogoFragmento.datosDialogFragment.password), Toast.LENGTH_LONG).show();
  191.     }
  192.  
  193. }

Analicemos o código.

  • Liñas 7,8,17: Por compatibilidade con versións anteriores de Android escollemos a opción de utilizar un FragmentActivity (v4) e unha AppCompacActivity(v7).
  • Liñas 19,37: Definimos e instaciamos o diálogo.
  • Liñas 177-178: Necesitamos un obxecto da clase FragmentManager para poder amosar o DialogFragment. Chamamos ao método show() no que no segundo parámetro podemos pasarlle unha cadea de texto ao DialogFragment que recollerá có método getTag().
  • Liñas 188-192: Este é o método que se chamará dende o DialogFragment para indicar que se pechou o diálogo. Podemos recoller os datos introducidos no mesmo accedendo á propiedade dialogoFragmento.datosDialogFragment.


Devolvendo información dunha forma máis elegante

  • No caso anterior vimos que para obter a información introducida no DialogFragment dende a Activity principal definimos unha propiedade public (public DatosDialogFragment datosDialogFragment;).
Podemos facelo dunha forma máis adecuada empregando interfaces. Podedes 'repasar' o uso das interfaces nesta entrada da Wiki.


  • Creamos unha nova clase DialogFragment de nome UD03_03_Dlg_Fragments cambiando as liñas
  • Onde aparece UD03_02_Dialogs por UD03_03_Dialogs:
  • Onde aparece UD03_02_Dlg_Fragments por UD03_03_Dlg_Fragments:


  • Creamos unha nova clase Activity de nome UD03_03_Dialogs co mesmo código que no caso anterior cambiando as liñas:
  • Onde aparece UD03_02_Dialogs por UD03_03_Dialogs:
  • Onde aparece UD03_02_Dlg_Fragments por UD03_03_Dlg_Fragments:



  • A idea é a seguinte:
  • 1º PASO: Definimos unha interface cos métodos que queiramos que sexan accesibles tanto dende a Activity como dende o DialogFragment. No caso que nos ocupa, teremos un único método que levará como parámetro un obxecto da clase Bundle, que nos vai servir para gardar a información do DialogFragment.
A definición da Interface podemos facela onde queiramos, xa que ao ser publica, poderemos acceder a ela dende calquera lugar do proxecto.
Eu vou definila na propia clase DialogFrament. Ademais vou definir un obxecto de dita clase (a Interface) que vai ser o que me vai servir de 'ponte' entre a activity principal e o DialogFragment.
  1. public class UD03_03_Dlg_Fragments extends DialogFragment {
  2.  
  3.     private OnCompleteListener mOnCompleteListener;
  4.     /**
  5.      * Interface que permite a la Activity padre recibir la información del diálogo
  6.      */
  7.     public interface OnCompleteListener {
  8.         void onComplete (Bundle bundle);
  9.     }
  10.  
  11.     ............


  • 2º PASO: Agora implementamos dita interface no Activity que vai chamar ao DialogFragment. Ao implementala teremos que implementar o su método (neste caso onComplete) o cal levará o obxecto da clase Bundle cos datos.
Polo tanto, cando dende o DialogFragment se chame a este método cos datos, a Activity principal os recibirá neste parámetro.
Deberemos gardar dito dato nunha propiedade 'local' para poder facer uso del noutros métodos
  1. public class UD03_03_Dialogs extends AppCompatActivity implements View.OnClickListener,UD03_03_Dlg_Fragments.OnCompleteListener {
  2.  
  3.     private UD03_03_Dlg_Fragments dialogoFragmento=null;
  4.     private Bundle datosDialogFragment=null;
  5.  
  6.     .....
  7.  
  8.     @Override
  9.     public void onComplete(Bundle bundle) {
  10.         this.datosDialogFragment = bundle;
  11.     }
Desta forma, cando se chame a este método a Acitivity principal xa terá os datos do DialogFrament na propiedade 'datosDialogFragment'.
  • 3º PASO: Debemos ter clara a seguinte idea: Cando se chama ao DialogFragment a activity principal é un obxecto da clase UD03_03_Dialogs e ao ter a interface UD03_03_Dlg_Fragments.OnCompleteListener implementada, en certa forma, tamén é un obxecto de dita clase. Quere isto dicir que podemos converter a Activity Principal nun obxecto da interface.
  1.     @Override
  2.     public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
  3.  
  4.  
  5.         final View rootView = inflater.inflate(R.layout.fragment_ud03_02_layout_dialogo, container, false);
  6.         getDialog().setTitle(getTag());         // O Tag se envía dende a activiy có método show.
  7.  
  8.         Button btn = (Button) rootView.findViewById(R.id.btnPechar_Frg_UD03_02_Dialogs);
  9.         btn.setOnClickListener(new View.OnClickListener() {
  10.  
  11.             @Override
  12.             public void onClick(View v) {
  13.                 // TODO Auto-generated method stub
  14.                 EditText editNome = rootView.findViewById(R.id.etNome_Dlg_UD03_02_Dialogs);
  15.                 EditText editPassword = rootView.findViewById(R.id.etPass_Dlg_UD03_02_Dialogs);
  16.  
  17.                 Bundle datos = new Bundle();
  18.                 datos.putString("NOME",editNome.getText().toString());
  19.                 datos.putString("PASSWORD",editPassword.getText().toString());
  20.  
  21.                 mOnCompleteListener = (OnCompleteListener) getActivity();
  22.                 mOnCompleteListener.onComplete(datos);
  23.  
  24.                 ((UD03_03_Dialogs)UD03_03_Dlg_Fragments.this.getActivity()).pecharDialogo();  // Poderíamos chamar a algún método da Activity que abriu o Dialog se queremos
  25.                 dismiss();
  26.             }
  27.         });
  • Liñas 21-22: Son estas liñas as que permiten 'enviar' os datos a activity principal. De todas formas necesitamos 'informar' a activity principal que xa se pechou a DialogFragment polo que chamamos ao método 'pecharDialog()' como no caso anterior.


  • 4º PASO: Agora dende a Activity principal, cando se chame ao método 'pecharDialog()' xa ten os datos na propiedade 'datosDialogFragment'.
  1.     protected void pecharDialogo(){
  2.         // O DialogFragment tamén pode chamar a métodos da activity que o invocou
  3.         Toast.makeText(this, Html.fromHtml("NOME:"+ datosDialogFragment.getString("NOME") + "<br/>PASSWORD:"+datosDialogFragment.getString("PASSWORD")), Toast.LENGTH_LONG).show();
  4.     }



Unha variación. Devolvendo un AlertDialog.Builder

Esta é unha primeira aproximación os DialogFragment. Comentar que en vez de sobreescribir o método onCreateView do DialogFragment podemos sobreescribir o método onCreateDialog e devolver un diálogo construído por nos (coma un DatePickerDialog, AlertDialog.builder,....) Por exemplo:

Código da clase UD03_02_B_Dlg_Fragments
Obxectivo: Modificamos o código para amosar outra forma de crear un diálogo. Debemos comentar o código do método onCreateView.

  1. import android.app.AlertDialog;
  2. import android.app.Dialog;
  3. import android.content.DialogInterface;
  4. import android.content.DialogInterface.OnClickListener;
  5. import android.os.Bundle;
  6. import android.support.v4.app.DialogFragment;
  7. import android.widget.Toast;
  8.  
  9. public class UD03_02_B_Dlg_Fragments extends DialogFragment{
  10.  
  11.        
  12.         @Override
  13.     public Dialog onCreateDialog(Bundle savedInstanceState) {
  14.                 AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
  15.                 .setTitle("Caixa de diálogo").setIcon(R.drawable.ic_launcher)
  16.                 .setMessage("QUE TE PARACE ESTE DIALOGO ?")
  17.                 .setPositiveButton("Ben", new OnClickListener() {
  18.                 @Override
  19.                 public void onClick(DialogInterface dialog, int which) {
  20.                         Toast.makeText(getActivity(), "PULSADA OPCION BOA",Toast.LENGTH_LONG).show();
  21.                 }
  22.                 }).setNegativeButton("MAL", new OnClickListener() {
  23.                 @Override
  24.                 public void onClick(DialogInterface dialog, int which) {
  25.                 //
  26.  
  27.                         Toast.makeText(getActivity(),"PULSADA OPCION MALA", Toast.LENGTH_LONG).show();
  28.                 }
  29.                 });
  30.                 return builder.create();
  31.                
  32.                
  33.         }
  34.        
  35. }

Nota: Fixarse que estamos a importar a interface onClickListener do DialogInterface (liña 4).


Android 2014 U3 15 Dialogos 5.JPG





-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).