Diferencia entre revisiones de «Ventás de Diálogos»
Línea 1308: | Línea 1308: | ||
'''Código da clase fragment_u3_15_layout_dialogo'''<br/> | '''Código da clase fragment_u3_15_layout_dialogo'''<br/> | ||
− | <syntaxhighlight lang=" | + | <syntaxhighlight lang="xml" line enclose="div" highlight="" > |
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |
Revisión del 20:21 26 oct 2018
Sumario
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.
- Lembrar como xa vimos no ciclo de vida das activities que a aparición dun DialogBox implicará que a Activity pase ao estado Paused.
- 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.
- 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:
- 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
- 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
- Referencias:
Diálogos anteriores a API 13
- Nota: Opción deprecated. Utilizar DialogFragments (seguinte sección)
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- 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.
- Esta aplicación está baseada no curso de Android da Aula Mentor: http://www.mentor.mec.es/
- 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.
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).
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'.
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- 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.
- Todos os diálogos anteriores menos o último fanse facendo uso da clase AlertDialog.Builder.
- 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.support.v7.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
- 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
- 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':
- 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.
- Os botóns se poden identificar polas constantes definidas na clase DialogInterface
- 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.
Diálogo Lista de Selección
- 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)
- 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 e como segundo parámetro implementamos a interface DialogInterface.OnClickListener().
Diálogo cunha selección múltiple (checkboxes)
- 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>
- Neste tipo de diálogo varía a Interface que xestiona o Click sobre cada un dos elementos da lista e pasa a ser a [,%20android.content.DialogInterface.OnMultiChoiceClickListener) Interface DialogInterface.OnMultiChoiceClickListener].
- 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 [,%20boolean[],%20android.content.DialogInterface.OnMultiChoiceClickListener) 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.
- Os DialogFragment foron engadidos na versión API 22.
- 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'.
- 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 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent" >
6
7 <EditText
8 android:id="@+id/editTexto"
9 android:layout_height="wrap_content"
10 android:layout_width="match_parent"
11 android:inputType="text"
12 android:gravity="fill_horizontal"
13 />
14 <Button
15 android:id="@+id/buttonPecharDialogo"
16 android:layout_width="wrap_content"
17 android:layout_height="wrap_content"
18 android:layout_below="@+id/editTexto"
19 android:layout_centerInParent="true"
20 android:text="Pechar" />
21
22 </RelativeLayout>
Agora deberemos crear unha clase que vai representar o DialogFragment e que vai cargar o layout anterior. Esta clase será a que instanciemos dende a nosa Activity.
O código Java do DialogFragment
Código da clase UD3_15_DialogoFragmento
Obxectivo: Clase que representa ó DialogFragment
1 import android.os.Bundle;
2 import android.support.v4.app.DialogFragment;
3 import android.view.LayoutInflater;
4 import android.view.View;
5 import android.view.View.OnClickListener;
6 import android.view.ViewGroup;
7 import android.widget.Button;
8 import android.widget.EditText;
9
10 public class UD3_15_DialogoFragmento extends DialogFragment{
11
12 public String valorTexto;
13
14 @Override
15 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
16
17 final View rootView = inflater.inflate(R.layout.fragment_u3_15_layout_dialogo, container, false);
18 getDialog().setTitle(getTag()); // O Tag se envía dende a activiy có método show.
19
20 Button btn = (Button) rootView.findViewById(R.id.buttonPecharDialogo);
21 btn.setOnClickListener(new OnClickListener() {
22
23 @Override
24 public void onClick(View v) {
25 // TODO Auto-generated method stub
26 EditText edit = (EditText)rootView.findViewById(R.id.editTexto);
27 valorTexto = edit.getText().toString();
28 ((U3_15_Dialogos)UD3_15_DialogoFragmento.this.getActivity()).pecharDialogo();
29 dismiss();
30 }
31 });
32
33 // Do something else
34 return rootView;
35 }
36 }
Analicemos o código.
- Liña 2: Estamos a utilizar a librería de compatibilidade con versións anteriores de Android.
- Liña 10: A nosa clase deriva de DialogFragment.
- Liña 15: Ó derivar de DialogFragment sobreescribimos o método onCreateView que ten que devolver o View que conforma o diálogo.
- No noso caso deberemos 'inflar' o layout deseñado anteriormente.
- O obxecto da clase LayoutInflater permite pasar dun deseño gráfico (o layout) e un obxecto manexable por programación. Isto o fai chamando ó método inflate e o garda no obxecto rootView.
- Liña 21: Có paso anterior, podemos acceder ós compoñentes gráficos que se atopan no layout por programación. No noso caso accedemos ó botón pechar e xestionamos o evento de click.
- Liñas 25-31: O que facemos nestas liñas é acceder ó contido da caixa de texto do diálogo, o gardamos nunha propiedade da clase.
- Liña 28: Esta liña vos dará un erro ata que usedes o código que ven a continuación. Esta liña chama a un método definido na activity que lanzou o DialogFragment.
- Liña 29: Pechamos o diálogo.
O XML da Activity
Definimos o layout da nosa activity:
Código da clase activity_u3_15__dialogos.xml
Obxectivo: Layout da nosa activity.
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 android:layout_width="fill_parent"
3 android:layout_height="fill_parent"
4 android:orientation="vertical" >
5
6 <TextView
7 android:layout_width="match_parent"
8 android:layout_height="wrap_content"
9 android:text="Ventás de diálogo" />
10
11
12 <Button
13 android:id="@+id/btn_dialogo"
14 android:layout_width="match_parent"
15 android:layout_height="wrap_content"
16 android:onClick="onBotonClick"
17 android:text="Ventá de diálogo con fragment" >
18 </Button>
19
20 </LinearLayout>
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 U3_15_Dialogos
Obxectivo: Amosar un diálogo baseado en Fragment.
1 import android.os.Bundle;
2 import android.support.v4.app.FragmentActivity;
3 import android.support.v4.app.FragmentManager;
4 import android.view.View;
5 import android.widget.Toast;
6
7 public class U3_15_Dialogos extends FragmentActivity {
8
9 private UD3_15_DialogoFragmento dialogoFragmento;
10
11 @Override
12 protected void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14 setContentView(R.layout.activity_u3_15__dialogos);
15 dialogoFragmento = new UD3_15_DialogoFragmento();
16 }
17
18 public void pecharDialogo(){
19 Toast.makeText(this, dialogoFragmento.valorTexto, Toast.LENGTH_LONG).show();
20 }
21
22 public void onBotonClick(View view) {
23 FragmentManager fm = getSupportFragmentManager();
24
25 switch (view.getId()) {
26 case R.id.btn_dialogo:
27 dialogoFragmento.show(fm, "EXEMPLO DE DIALOGO!!!!");
28 break;
29
30 }
31 }
32 }
Analicemos o código.
- Liñas 2,3,7: Por compatibilidade con versións anteriores de Android escollemos a opción de utilizar un FragmentActivity.
- Liña 9,15: Definimos e instaciamos o diálogo.
- Liñas 18-20: Este é o método que chama a clase do Diálogo cando prememos o botón pechar.
- Liña 23: Necesitamos un FragmentManager para amosar o diálogo.
- Liña 27: Amosamos o diálogo.
Unha variación
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 UD3_15_DialogoFragmento
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 UD3_15_DialogoFragmento 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).
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).