Diferencia entre revisiones de «Usuario:ManuelRomero/Android/PrimerosContactos/EjemploCajasDialogo»
De WikiEducator
(→La clase diálogo) |
(→Ficheros con lo visto hasta ahora) |
||
(37 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 1: | Línea 1: | ||
+ | {{TEP}} | ||
{{:Usuario:ManuelRomero/Android/PrimerosContactos/nav}} | {{:Usuario:ManuelRomero/Android/PrimerosContactos/nav}} | ||
<br/> | <br/> | ||
− | =Preparar la | + | =Preparar la apalicación= |
+ | *Vamos a realizar una app, en la que vamos a usar la forma recomendada para abrir la ventanas de diálogo | ||
+ | *Para realizar este tipo de acciones tenemos dos opciones. Una de ellas ya está ''depreciate'' y se recomienda usar ''fragment'' | ||
+ | *En este caso lo vamos a hacer con ''fragment'', concretamente heredando de la clase DialogFragment. Al final de este tema pondré el código de como hacerlo de la otra manera que en principio es más sencilla, pero menos flexible. | ||
<!-- | <!-- | ||
Aquí hago el programa de dos cajas de diálogo para que muestren las cosas | Aquí hago el programa de dos cajas de diálogo para que muestren las cosas | ||
Línea 10: | Línea 14: | ||
Implementamos primero con un botón | Implementamos primero con un botón | ||
--> | --> | ||
+ | Nuestra aplicación va a constar de dos clases | ||
+ | # la activity que va a ser nuestra pantalla con los botones | ||
+ | # La ventana diálogo que en función del botón que presionemos visualizará una ventana de diálogo u otra | ||
+ | [[Archivo:ejDialogoClases.png]] | ||
+ | |||
==La clase VentanaDialogo solo un botón == | ==La clase VentanaDialogo solo un botón == | ||
<!-- | <!-- | ||
Línea 16: | Línea 25: | ||
Clase AlerteDialog Vs Builder Vs AlertDialog.Builder | Clase AlerteDialog Vs Builder Vs AlertDialog.Builder | ||
Versión 1 (solo funciona un botón | Versión 1 (solo funciona un botón | ||
− | método getActivity() de | + | método getActivity() de DialogFragmaentç |
clase FragmentManager y método getFragmentmanager(() de la clase Activity | clase FragmentManager y método getFragmentmanager(() de la clase Activity | ||
Implementamos los diferentes botones | Implementamos los diferentes botones | ||
--> | --> | ||
− | + | *La clase VentanaDialogo va a ser un Fragment especializado '''''DialogFrament''''' | |
− | + | *Como todo ''Fragment'' a la hora de ser ejecutado dependera de una ''Activity'' que inicia su ciclo de vida | |
− | + | *Los métodos callback que se ejecutan cuando se inicia el ''DialogFragment'' son '''''onCreateDialog()''''' y '''''onCreateView()''''' | |
− | + | [[Archivo:ClaseFragment1.png]] | |
− | métodos | + | *Si vamos a usar una clase ya existen (AlerteDialog, ...), se escribe el código en ''onCreateDialog()'', sin embargo si fuéramos a realizar una caja de diálogo personalizada donde tuviéramos que definirnos un layout, podríamos sobreescribir el callback ''onCreteView()''. |
− | + | *Escribamos el código para visualizar una caja de diálogo ya establecida ''AlertDialog()'' | |
− | + | <Source lang=java> | |
− | + | public Dialog onCreateDialog(Bundle instancia) { | |
− | + | /*Creamos un objeto de la clase AlertDialog (nuestra caja de dialogo prediseñada*/ | |
− | + | AlertDialog msj = new AlertDialog.Builder(getActivity()); | |
− | + | ||
− | - | + | /*Le damos propiedades según nuetra conveniencia, la personalizamos*/ |
+ | msj.setTitle(titulo) | ||
+ | .setMessage(mensaje) | ||
+ | .setPositiveButton("OK",new DialogInterface.OnClickListener() { | ||
+ | @Override | ||
+ | public void onClick(DialogInterface dialog, int which) { | ||
+ | // TODO Auto-generated method stub | ||
+ | ((Dialogo)getActivity()).opcionSI(tipo); | ||
+ | } | ||
+ | }); | ||
+ | /*Voy debugando en el LogCat */ | ||
+ | Log.i("Depurando","Alert Dialog configurado "); | ||
+ | |||
+ | /*Retorno mi caja de diálogo*/ | ||
+ | return msj.create(); | ||
+ | } | ||
+ | </Source> | ||
+ | *En el cuerpo creamos un objeto de la clase '''AlertDialog''', que explicamos en la siguiente sección, pero como vemos en la imagen es una clase que extiende de '''Dialog''' | ||
+ | [[Archivo:ClaseAlertDialog.png]] | ||
+ | *Este médoto devuelve un objeto de la clase Dialog que nos retorna el método create de nuestro '''AlertDialog''' creado con '''AlertDialog.Builder''' | ||
− | + | ; Veamos el código de ''setPositiveButton(...)'' | |
− | + | <source lang=java> | |
− | + | setPositiveButton(CharSequence texto, DialogInterface.OnClickListener listener) | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | <source lang= | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
</source> | </source> | ||
− | + | ;Los paŕametros | |
− | + | # ''texto'' es un '''CharSequence''' que establecerça el texto del botón | |
− | *Para | + | # ''lisener'' es un objeto listener que escuchará el objeto evento generado, cuando hagamos un click en el botón. |
− | *El | + | *Este ''listener'' es una implementación de la interfaz '''''DialogInterface''''' |
− | # | + | *Para crear una instancia de la implementación de la interfaz lo hacemos invocando al método ''OnClickListnener()'' |
− | # | + | *Como implementamos la interfaz debemos sobreescribier su método ''onClick()'' |
− | + | *El método onClick()recibe dos parámetros: | |
+ | #''El objeto '''Dialog''' '' que ha generado el evento. | ||
+ | #''un entero'' que identifica el botón que ha generado el evento (útil si puedo tener varios botones como en el caso de un ratio o un check, que veremos posteriormente). | ||
+ | ;El cuerpo del bucle'' | ||
<source lang=java> | <source lang=java> | ||
− | + | ((Dialogo)getActivity()).opcionSI(tipo); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
</source> | </source> | ||
− | * | + | *Lo que hacemos es invocar al método ''opcionSI()'' que está en la clase Dialogo (la otra de nuestro ejemplo). |
− | + | *Como estamos en un ''Fragment'', éste para entrar en ejecución depende de una ''Activity'' que la ha invocado, siempre podemos acceder a dicha Activity con el método '''getActivity()''' de la clase ''Fragment'' correspondiente. | |
− | + | *No olvidemos que un ''DialogFragment'' es un ''Fragment''. | |
− | + | *Siempre Hemos de hacer un ''cast'' al tipo concreto de ''Activity'' que vamos a obtener con el método '''getActivity()''' en este caso nuestro ''Dialogo'' | |
− | + | ===AlertDialog=== | |
− | + | *Es una clase que hereda de '''''Dialog''''' y tiene ya un layout establecido la cual se adapta visualmente en fución de que asignemos valores a propidades de la clase | |
*Una vez creado el objeto le damos las propiedades que necesarias | *Una vez creado el objeto le damos las propiedades que necesarias | ||
*Los métodos que asignas propiedades son muy intuitivos, y permiten asignar | *Los métodos que asignas propiedades son muy intuitivos, y permiten asignar | ||
Línea 77: | Línea 90: | ||
#Un mensaje de texto | #Un mensaje de texto | ||
#Uno, dos o tres botones | #Uno, dos o tres botones | ||
− | #Una lista de items seleccionables | + | #Una lista de items seleccionables, opcionalmente con casilla de verificación (puedo seleccionar varios-checkButtons) u opciones excluyentes (radio buttons). |
#El método setCancelable(boolean) convierte la ventana de dialogo en modal respecto al botón de retroceso | #El método setCancelable(boolean) convierte la ventana de dialogo en modal respecto al botón de retroceso | ||
+ | *Observar que para dar las diferentes propiedades puedo hacerlo seguido | ||
+ | objeto.propiedad1() | ||
+ | .propiedad2() | ||
+ | .... | ||
+ | .propiedadn(); | ||
+ | *De igual forma que hemos visto los métodos anteriores tenemos disponibles otras opciones | ||
+ | <source lang=java> | ||
+ | AlertDialog.Buider.setNegativeButton(CharSequence titulo, DialogInterface.OnClickListener(..)); | ||
+ | AlertDialog.Buider.setNeutralButton.(CharSequence titulo, DialogInterface.OnClickListener(..)); | ||
− | + | </source> | |
+ | <!-- | ||
+ | Implementamos los diferents botones | ||
+ | --> | ||
+ | |||
+ | ==Añadiendo mas botones== | ||
+ | *Vamos a preparar nuestra aplicación para visualcizar diferentes cajas de diálogo. | ||
+ | *Queremos tener en la clase '''Dialogo''' (Recordemos que es nuestra '''Activity'''), una interfaz con tantos botones como cajas de diálogo diferentes queremos que nos visualice nuestra app. | ||
+ | En concreto vamos a hacer una app que nos visualice hasta 9 cajas de diálogo diferentes según vamos a ir viendo. | ||
+ | <br/> | ||
+ | [[Archivo:DialogoBotones.png|200px]] | ||
+ | <br/> | ||
+ | ;La dinámica de nuestra aplicación va a ser la siguiente: | ||
+ | #Al arrancar la app se visualizará la interfaz de la ''Activity'' '''Dialogo''' (imagen anterior). | ||
+ | #Presionaremos un botón. | ||
+ | #Creamos un objeto de la clase VentanaDialogo | ||
+ | #En función del botón presionado se preparará la caja de diálogo con una u otra información. | ||
+ | #Se visualizará la caja de diálogo donde podremos botones y/o opciones para seleccionar. | ||
+ | #Una vez tomada una opción de la ventana de diálogo haremos algo que visualice la opción tomada, o simplemente visualizaremos el diálogo como en el caso de ''barra de progreso'' | ||
+ | *La siguiente imagen intenta ilustrar con un sencillo diagrama de transición la relación entre las clases | ||
+ | [[Archivo:PasandoValores.png]] | ||
+ | A continuación vamos a ver como abordamos cada una de las cuestiones anteriores | ||
+ | ===Pasando información entre las clases=== | ||
+ | *Primero vemos cómo asociar los valores a la clase | ||
+ | *A continuación como leer los valores desde la clase | ||
+ | ;Poniendo los valores | ||
+ | *El primero paso es crear un objeto de la clase VentanaDialogo y de alguna forma le hemos de pasar información para que sepa ese objeto qué botón de los 10 que tenemos lo ha creado. | ||
+ | *Para ello podríamos usar un constructor, pero en android cuando una activity u otro tipo de app javase carga en la pila de ejecución tiene un ciclo de vida. Esto hace que el método callback ''onCreate()'' u otro que sepamos que se ejecuta cuando se crea el objeto de la clase realice todo lo que queremos que ocurra cuando se instancia un objeto de la clase. Por este mot aivo no se suelen usar constructores en android, aunque sí que se podría. Pero no sería el primer método que se ejecutaría al instanciar el objeto de la clase. | ||
+ | *Para pasar parámetros entre clases en android podemos usar un método estático en la clase a la que queremos pasar parámetros | ||
+ | *En nuestro caso en la clase VentanaDialogo. | ||
+ | **Será un método estático para que lo pueda invocar antes de crear el objeto | ||
+ | **Este mismo método me generará un objeto de la clase y me lo retornará | ||
+ | **Dentro de él crearemos un objeto de la clase Bundle (ver sección siguiente), y le pasamos los parámetros | ||
+ | <source lang='java'> | ||
+ | public static VentanaDialogo inicializaVentana(int tipo, String titulo, String mensaje){ | ||
+ | Log.i("inicializaVentana","haciendo poco"); | ||
+ | VentanaDialogo v = new VentanaDialogo(); | ||
+ | Bundle parametros = new Bundle(); | ||
+ | Log.i("Depurando","en el estatico de inicializaVentana"); | ||
+ | parametros.putInt("tipo",tipo); | ||
+ | parametros.putString("titulo",titulo); | ||
+ | parametros.putString("mensaje",mensaje); | ||
+ | v.setArguments(parametros); | ||
+ | return v; | ||
+ | } | ||
+ | </source> | ||
+ | *En nuestro caso queremos pasar dos valores | ||
+ | *'''''tipo''''' es entero que representará el botón que hemos presionado usaremos la lista expuesta a continuación | ||
+ | *'''''título''''' es un String que va a ser el título de la caja de diálogo (todas las cajas de diálogo tendrán un título | ||
<source lang=java> | <source lang=java> | ||
− | + | final int ALERTAOK = 1; | |
− | + | final int ALERTASINO = 2; | |
− | + | final int ALERTASINOCANCEL = 3; | |
− | + | final int ALERTARATIO = 4; | |
− | + | final int ALERTACHECK= 5; | |
− | + | final int BARRAPROGRESO1 = 6; | |
− | + | final int BARRAPROGRESO2 = 7; | |
− | + | final int DIALOGOHORA = 8; | |
− | + | final int DIALOGOFECHA = 9; | |
− | + | </source> | |
− | + | *Ahora queda poner los valores, lo debe de hacer la clase Dialogo cuando declara un objeto de la clase VentanaDialogo, veámoslo en el código | |
− | + | <source lang=java> | |
− | + | public void clickOk (View v){ | |
− | + | VentanaDialogo mensaje=VentanaDialogo.inicializaVentana(ALERTAOK,"INFORMACION","Acepta esta opción"); | |
− | + | ..... | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
+ | </source> | ||
+ | ;Leyendo los valores | ||
+ | *Ahora en la clase VentanaDialogo debemos leer estos valores | ||
+ | *Ello lo haremos dentro del método de Callback que se ejecuta cuando el objeto entra en ejecución en este caso en '''''onCreateDialog(...)''''' | ||
+ | *Para ello usamos el método '''''Bundle getArgument()''''' de la clase Fragment que retorna los argumentos que se pasan a un Fragement cuando este ha sido instanciado con ellos. Nos retorna un Bundle | ||
+ | *Posteriormente usaremos los métodos getxxx(etiqueta, valor), complementarios a los setxxx(etiquet, valor) usados para pasar los valores | ||
+ | *como se puede ver en el código se puede hacer en una línea. | ||
+ | <source lang=java> | ||
+ | String titulo = getArguments().getString("titulo"); | ||
+ | int tipo = getArguments().getInt("tipo"); | ||
+ | </source> | ||
+ | *De esta forma ya tenemos el tipo de botón que ha presionado la acción, ahora discretizamos con un switch | ||
+ | <source lang=java> | ||
+ | @Override | ||
+ | public Dialog onCreateDialog(Bundle instancia) { | ||
+ | ..... | ||
+ | String titulo = getArguments().getString("titulo"); | ||
+ | int tipo = getArguments().getInt("tipo"); | ||
+ | .... | ||
+ | switch (tipo){ | ||
+ | case ALERTAOK://Ventana tipo OK | ||
+ | Log.i("Depurando","En on CreateDialog CAso 1 "); | ||
+ | alertaOk(); | ||
+ | ..... | ||
+ | case ALERTASINO://Ventana tipo SI NO | ||
+ | alertaSiNo(); | ||
+ | ..... | ||
+ | case ALERTASINOCANCEL://Ventana de tipo Si NO CANCEL | ||
+ | alertaSiNoCancel(); | ||
+ | ..... | ||
+ | case ALERTARATIO://Ventana de tipo opciones Ratio | ||
+ | Log.i("VentanaDialogo","en el switch caso 4"); | ||
+ | alertaOpcionesRatio(); | ||
+ | ..... | ||
+ | case ALERTACHECK://Ventana de tipo Opciones Check | ||
+ | alertaOpcionesCheck(); | ||
+ | ..... | ||
+ | case BARRAPROGRESO1: | ||
+ | Log.i("OnCreateDialog","Dentro de opcion 6 antes de ir al progress"); | ||
+ | progress1(); | ||
+ | ..... | ||
+ | case BARRAPROGRESO2: | ||
+ | progress2(); | ||
+ | ..... | ||
+ | case DIALOGOHORA: | ||
+ | alertaHora(); | ||
+ | ..... | ||
+ | case DIALOGOFECHA: | ||
+ | alertaFecha(); | ||
+ | ..... | ||
+ | } | ||
+ | ..... | ||
+ | } | ||
+ | </source> | ||
− | private void | + | ====Clase Bundle==== |
− | + | [[Archivo:ClaseBundle.png]] | |
− | + | *Esta clase va a permitir pasar datos entre diferentes '''activity''' y/o '''Framgment''' | |
− | } | + | *Esta clase implementa la interfaz Parcelable y Ser |
+ | *La forma de hacerlo es la siguiente: | ||
+ | #Creamos un objeto de la clase Bundle | ||
+ | #Usando los métodos putxxx(''etiqueta'', ''valor''), vamos preparando parejas etiqueta-valor para pasar a un objeto activity o fragment | ||
+ | #No vamos a poder pasar objetos complejos, sí tipo privitivos. | ||
+ | #Una vez que hayamos terminado de confeccionar todas las parejas etiqueta-valor con los métodos ''putxxx'', asociamos el Bundle a clase Activity o Fragment que le queremos asociar el valor, con el método '''''setArguments(Bundle)''''' de la clase Activity o Fragment. | ||
+ | #Y ya está, luego en la clase podremos recuperar estos valores. | ||
+ | ===Opciones de tipo ratio === | ||
+ | *Tenemos diferentes opciones y queremos seleccionar solo una | ||
+ | *En este caso usaremos el método setSingleChoiceItems(charSequence[] lista,int item_seleccionado,listener) | ||
+ | *Observamos el botón correspondiente para esta accion | ||
+ | *El código siguiente visualiza como adaptar un AlertDialog a este tipo de opciones | ||
+ | <source lang=java> | ||
+ | private void alertaOpcionesRatio() { | ||
+ | // TODO Auto-generated method stub | ||
+ | CharSequence[] sexo={"Hombre","Mujer","Prefiero no contestar"}; | ||
+ | AlertDialog msj = AlertDialog.Builder(getActivity()); | ||
+ | msj.setTitle(titulo) | ||
+ | .setSingleChoiceItems(sexo,-1,new DialogInterface.OnClickListener() { | ||
+ | @Override | ||
+ | public void onClick(DialogInterface dialog, int elemento) { | ||
+ | // TODO Auto-generated method stub | ||
+ | |||
+ | ((Dialogo)getActivity()).opcionRatio(sexo[elemento]); | ||
+ | } | ||
+ | }); | ||
+ | } | ||
</source> | </source> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | *El método ''opcionRatio(String opcion)'' es un método de la clase Dialogo al que pasamos la opcion seleccionada | ||
+ | *En nuestro caso lo único que hace es visualizar la opción | ||
+ | <source lang=java> | ||
+ | public void opcionRatio(CharSequence elemento) { | ||
+ | // TODO Auto-generated method stb | ||
+ | Toast.makeText(this,"Ha seleccionado la opcion "+elemento,Toast.LENGTH_SHORT).show(); | ||
+ | } | ||
+ | </source> | ||
===checkButton como opciones=== | ===checkButton como opciones=== | ||
*Tenemos diferentes opciones y queremos seleccionar algunas de ellas | *Tenemos diferentes opciones y queremos seleccionar algunas de ellas | ||
Línea 125: | Línea 268: | ||
*En este caso debemos invocar al método '''''setMultiChoiceItems''''' | *En este caso debemos invocar al método '''''setMultiChoiceItems''''' | ||
*Este método le pasamos el vector de opciones, un vector de boolenos que nos dice cada opción si está o no seleccionada y un listener. | *Este método le pasamos el vector de opciones, un vector de boolenos que nos dice cada opción si está o no seleccionada y un listener. | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<source lang=java> | <source lang=java> | ||
− | + | private void alertaOpcionesCheck() { | |
− | + | // TODO Auto-generated method stub | |
− | + | CharSequence[] idiomas={"Español","Inglés","Alemán","Rumano"}; | |
− | + | boolean []idiomasSeleccionados = new boolean[idiomas.length]; | |
− | + | AlertDialog msj = AlertDialog.Builder(getActivity()); | |
− | + | msj.setTitle(titulo) | |
− | + | .setMultiChoiceItems(idiomas, idiomasSeleccionados, new DialogInterface.OnMultiChoiceClickListener() { | |
− | + | @Override | |
− | + | public void onClick(DialogInterface dialog, int which, boolean isChecked) { | |
− | + | // TODO Auto-generated method stub | |
− | + | ((Dialogo)getActivity()).opcionCheck(idiomas,idiomasSeleccionados); | |
− | + | ||
− | + | } | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
− | |||
− | |||
− | |||
</source> | </source> | ||
− | + | *En este caso al método '''''setMultiChoiceItems(...)''''' le pasamos tres parámetros | |
− | + | #'''idiomas''' que es el vector de opciones que queremos visualizar | |
− | + | #'''idiomasSeleccionados''' es un vector de booleanos que muestra si cada opción está o no seleccionada | |
− | + | #Una instancia de una clase listener para escuchar los objetos eventos generados por cualquier botón de las opciones | |
− | *En este caso | + | *De nuevo invocamos a un método de la clase '''''Dialogo''''' '''opcionCheck(...), al que pasamos el vector de idiomas y el de booneanos. |
− | + | *El cuerpo del bucle quedaría | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<source lang=java> | <source lang=java> | ||
− | public void | + | public void opcionCheck(CharSequence[] idiomas, boolean[] idiomasSeleccionados) { |
− | + | // TODO Auto-generated method stub | |
− | + | String msj; | |
− | + | msj = "Idiomas seleccionados: \n"; | |
− | + | for (int i=0; i<idiomas.length;i++) | |
− | + | if (idiomasSeleccionados[i]) | |
− | + | msj+=idiomas[i]+"\n"; | |
− | + | Toast.makeText(this, msj,Toast.LENGTH_SHORT).show(); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
− | + | </sourece> | |
− | </ | + | |
− | + | ||
===Ventana dialogo con direfentes opciones=== | ===Ventana dialogo con direfentes opciones=== | ||
+ | *Es una alternativa a visualizar el radio, en cuanto el usuario seleciona uno ya queda seleccionado | ||
*En este caso añadimos el método setItems, en lugar de setMessage | *En este caso añadimos el método setItems, en lugar de setMessage | ||
*El método setItems como primer parámetro le pasaremos un vector de charSequences y el segundo es un listener | *El método setItems como primer parámetro le pasaremos un vector de charSequences y el segundo es un listener | ||
*Vemos el código | *Vemos el código | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<source lang=java> | <source lang=java> | ||
public void clickMsgOpciones(View v){ | public void clickMsgOpciones(View v){ | ||
− | + | ||
AlertDialog.Builder caja = new AlertDialog.Builder(this); | AlertDialog.Builder caja = new AlertDialog.Builder(this); | ||
caja.setTitle("Indica sexo") | caja.setTitle("Indica sexo") | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
.setItems(sexo, new DialogInterface.OnClickListener() { | .setItems(sexo, new DialogInterface.OnClickListener() { | ||
− | + | uublic void onClick(DialogInterface dialog, int elemento) { | |
− | + | ||
// TODO Auto-generated method stub | // TODO Auto-generated method stub | ||
Toast t = Toast.makeText(getApplicationContext(), "Has seleccionado "+sexo[elemento],Toast.LENGTH_LONG); | Toast t = Toast.makeText(getApplicationContext(), "Has seleccionado "+sexo[elemento],Toast.LENGTH_LONG); | ||
Línea 225: | Línea 320: | ||
} | } | ||
}); | }); | ||
− | + | AlertDialog alert = caja.create(); | |
− | AlertDialog alert = caja.create(); | + | alert.show(); |
− | alert.show(); | + | |
} | } | ||
</source> | </source> | ||
− | + | ==Ficheros con lo visto hasta ahora== | |
+ | *Se pueden descargar los ficheros de lo hecho hasta ahora | ||
+ | #La clase Dialogo.java [[Archivo:Dialogo.pdf]] | ||
+ | #La clase VentanaDialogo.java [[Archivo:VentanaDialogo.pdf]] | ||
+ | |||
+ | ==ProgressDialog== | ||
===Barra de progreso circular=== | ===Barra de progreso circular=== | ||
<!-- | <!-- | ||
Línea 268: | Línea 367: | ||
</source> | </source> | ||
--> | --> | ||
+ | |||
===Barra de progreso horizontal=== | ===Barra de progreso horizontal=== | ||
Última revisión de 13:45 11 nov 2013
Trabajo en proceso, espera cambios frecuentes. Tu ayuda y retroalimentación son bienvenidos. Ver página de charlas. |
Preparar la apalicación
- Vamos a realizar una app, en la que vamos a usar la forma recomendada para abrir la ventanas de diálogo
- Para realizar este tipo de acciones tenemos dos opciones. Una de ellas ya está depreciate y se recomienda usar fragment
- En este caso lo vamos a hacer con fragment, concretamente heredando de la clase DialogFragment. Al final de este tema pondré el código de como hacerlo de la otra manera que en principio es más sencilla, pero menos flexible.
La clase diálogo
Nuestra aplicación va a constar de dos clases
- la activity que va a ser nuestra pantalla con los botones
- La ventana diálogo que en función del botón que presionemos visualizará una ventana de diálogo u otra
La clase VentanaDialogo solo un botón
- La clase VentanaDialogo va a ser un Fragment especializado DialogFrament
- Como todo Fragment a la hora de ser ejecutado dependera de una Activity que inicia su ciclo de vida
- Los métodos callback que se ejecutan cuando se inicia el DialogFragment son onCreateDialog() y onCreateView()
- Si vamos a usar una clase ya existen (AlerteDialog, ...), se escribe el código en onCreateDialog(), sin embargo si fuéramos a realizar una caja de diálogo personalizada donde tuviéramos que definirnos un layout, podríamos sobreescribir el callback onCreteView().
- Escribamos el código para visualizar una caja de diálogo ya establecida AlertDialog()
public Dialog onCreateDialog(Bundle instancia) { /*Creamos un objeto de la clase AlertDialog (nuestra caja de dialogo prediseñada*/ AlertDialog msj = new AlertDialog.Builder(getActivity()); /*Le damos propiedades según nuetra conveniencia, la personalizamos*/ msj.setTitle(titulo) .setMessage(mensaje) .setPositiveButton("OK",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub ((Dialogo)getActivity()).opcionSI(tipo); } }); /*Voy debugando en el LogCat */ Log.i("Depurando","Alert Dialog configurado "); /*Retorno mi caja de diálogo*/ return msj.create(); }
- En el cuerpo creamos un objeto de la clase AlertDialog, que explicamos en la siguiente sección, pero como vemos en la imagen es una clase que extiende de Dialog
- Este médoto devuelve un objeto de la clase Dialog que nos retorna el método create de nuestro AlertDialog creado con AlertDialog.Builder
- Veamos el código de setPositiveButton(...)
setPositiveButton(CharSequence texto, DialogInterface.OnClickListener listener)
- Los paŕametros
- texto es un CharSequence que establecerça el texto del botón
- lisener es un objeto listener que escuchará el objeto evento generado, cuando hagamos un click en el botón.
- Este listener es una implementación de la interfaz DialogInterface
- Para crear una instancia de la implementación de la interfaz lo hacemos invocando al método OnClickListnener()
- Como implementamos la interfaz debemos sobreescribier su método onClick()
- El método onClick()recibe dos parámetros:
- El objeto Dialog que ha generado el evento.
- un entero que identifica el botón que ha generado el evento (útil si puedo tener varios botones como en el caso de un ratio o un check, que veremos posteriormente).
- El cuerpo del bucle
((Dialogo)getActivity()).opcionSI(tipo);
- Lo que hacemos es invocar al método opcionSI() que está en la clase Dialogo (la otra de nuestro ejemplo).
- Como estamos en un Fragment, éste para entrar en ejecución depende de una Activity que la ha invocado, siempre podemos acceder a dicha Activity con el método getActivity() de la clase Fragment correspondiente.
- No olvidemos que un DialogFragment es un Fragment.
- Siempre Hemos de hacer un cast al tipo concreto de Activity que vamos a obtener con el método getActivity() en este caso nuestro Dialogo
AlertDialog
- Es una clase que hereda de Dialog y tiene ya un layout establecido la cual se adapta visualmente en fución de que asignemos valores a propidades de la clase
- Una vez creado el objeto le damos las propiedades que necesarias
- Los métodos que asignas propiedades son muy intuitivos, y permiten asignar
- Un título setTitle
- Un mensaje de texto
- Uno, dos o tres botones
- Una lista de items seleccionables, opcionalmente con casilla de verificación (puedo seleccionar varios-checkButtons) u opciones excluyentes (radio buttons).
- El método setCancelable(boolean) convierte la ventana de dialogo en modal respecto al botón de retroceso
- Observar que para dar las diferentes propiedades puedo hacerlo seguido
objeto.propiedad1() .propiedad2() .... .propiedadn();
- De igual forma que hemos visto los métodos anteriores tenemos disponibles otras opciones
AlertDialog.Buider.setNegativeButton(CharSequence titulo, DialogInterface.OnClickListener(..)); AlertDialog.Buider.setNeutralButton.(CharSequence titulo, DialogInterface.OnClickListener(..));
Añadiendo mas botones
- Vamos a preparar nuestra aplicación para visualcizar diferentes cajas de diálogo.
- Queremos tener en la clase Dialogo (Recordemos que es nuestra Activity), una interfaz con tantos botones como cajas de diálogo diferentes queremos que nos visualice nuestra app.
En concreto vamos a hacer una app que nos visualice hasta 9 cajas de diálogo diferentes según vamos a ir viendo.
- La dinámica de nuestra aplicación va a ser la siguiente
- Al arrancar la app se visualizará la interfaz de la Activity Dialogo (imagen anterior).
- Presionaremos un botón.
- Creamos un objeto de la clase VentanaDialogo
- En función del botón presionado se preparará la caja de diálogo con una u otra información.
- Se visualizará la caja de diálogo donde podremos botones y/o opciones para seleccionar.
- Una vez tomada una opción de la ventana de diálogo haremos algo que visualice la opción tomada, o simplemente visualizaremos el diálogo como en el caso de barra de progreso
- La siguiente imagen intenta ilustrar con un sencillo diagrama de transición la relación entre las clases
A continuación vamos a ver como abordamos cada una de las cuestiones anteriores
Pasando información entre las clases
- Primero vemos cómo asociar los valores a la clase
- A continuación como leer los valores desde la clase
- Poniendo los valores
- El primero paso es crear un objeto de la clase VentanaDialogo y de alguna forma le hemos de pasar información para que sepa ese objeto qué botón de los 10 que tenemos lo ha creado.
- Para ello podríamos usar un constructor, pero en android cuando una activity u otro tipo de app javase carga en la pila de ejecución tiene un ciclo de vida. Esto hace que el método callback onCreate() u otro que sepamos que se ejecuta cuando se crea el objeto de la clase realice todo lo que queremos que ocurra cuando se instancia un objeto de la clase. Por este mot aivo no se suelen usar constructores en android, aunque sí que se podría. Pero no sería el primer método que se ejecutaría al instanciar el objeto de la clase.
- Para pasar parámetros entre clases en android podemos usar un método estático en la clase a la que queremos pasar parámetros
- En nuestro caso en la clase VentanaDialogo.
- Será un método estático para que lo pueda invocar antes de crear el objeto
- Este mismo método me generará un objeto de la clase y me lo retornará
- Dentro de él crearemos un objeto de la clase Bundle (ver sección siguiente), y le pasamos los parámetros
public static VentanaDialogo inicializaVentana(int tipo, String titulo, String mensaje){ Log.i("inicializaVentana","haciendo poco"); VentanaDialogo v = new VentanaDialogo(); Bundle parametros = new Bundle(); Log.i("Depurando","en el estatico de inicializaVentana"); parametros.putInt("tipo",tipo); parametros.putString("titulo",titulo); parametros.putString("mensaje",mensaje); v.setArguments(parametros); return v; }
- En nuestro caso queremos pasar dos valores
- tipo es entero que representará el botón que hemos presionado usaremos la lista expuesta a continuación
- título es un String que va a ser el título de la caja de diálogo (todas las cajas de diálogo tendrán un título
final int ALERTAOK = 1; final int ALERTASINO = 2; final int ALERTASINOCANCEL = 3; final int ALERTARATIO = 4; final int ALERTACHECK= 5; final int BARRAPROGRESO1 = 6; final int BARRAPROGRESO2 = 7; final int DIALOGOHORA = 8; final int DIALOGOFECHA = 9;
- Ahora queda poner los valores, lo debe de hacer la clase Dialogo cuando declara un objeto de la clase VentanaDialogo, veámoslo en el código
public void clickOk (View v){ VentanaDialogo mensaje=VentanaDialogo.inicializaVentana(ALERTAOK,"INFORMACION","Acepta esta opción"); ..... }
- Leyendo los valores
- Ahora en la clase VentanaDialogo debemos leer estos valores
- Ello lo haremos dentro del método de Callback que se ejecuta cuando el objeto entra en ejecución en este caso en onCreateDialog(...)
- Para ello usamos el método Bundle getArgument() de la clase Fragment que retorna los argumentos que se pasan a un Fragement cuando este ha sido instanciado con ellos. Nos retorna un Bundle
- Posteriormente usaremos los métodos getxxx(etiqueta, valor), complementarios a los setxxx(etiquet, valor) usados para pasar los valores
- como se puede ver en el código se puede hacer en una línea.
String titulo = getArguments().getString("titulo"); int tipo = getArguments().getInt("tipo");
- De esta forma ya tenemos el tipo de botón que ha presionado la acción, ahora discretizamos con un switch
@Override public Dialog onCreateDialog(Bundle instancia) { ..... String titulo = getArguments().getString("titulo"); int tipo = getArguments().getInt("tipo"); .... switch (tipo){ case ALERTAOK://Ventana tipo OK Log.i("Depurando","En on CreateDialog CAso 1 "); alertaOk(); ..... case ALERTASINO://Ventana tipo SI NO alertaSiNo(); ..... case ALERTASINOCANCEL://Ventana de tipo Si NO CANCEL alertaSiNoCancel(); ..... case ALERTARATIO://Ventana de tipo opciones Ratio Log.i("VentanaDialogo","en el switch caso 4"); alertaOpcionesRatio(); ..... case ALERTACHECK://Ventana de tipo Opciones Check alertaOpcionesCheck(); ..... case BARRAPROGRESO1: Log.i("OnCreateDialog","Dentro de opcion 6 antes de ir al progress"); progress1(); ..... case BARRAPROGRESO2: progress2(); ..... case DIALOGOHORA: alertaHora(); ..... case DIALOGOFECHA: alertaFecha(); ..... } ..... }
Clase Bundle
- Esta clase va a permitir pasar datos entre diferentes activity y/o Framgment
- Esta clase implementa la interfaz Parcelable y Ser
- La forma de hacerlo es la siguiente:
- Creamos un objeto de la clase Bundle
- Usando los métodos putxxx(etiqueta, valor), vamos preparando parejas etiqueta-valor para pasar a un objeto activity o fragment
- No vamos a poder pasar objetos complejos, sí tipo privitivos.
- Una vez que hayamos terminado de confeccionar todas las parejas etiqueta-valor con los métodos putxxx, asociamos el Bundle a clase Activity o Fragment que le queremos asociar el valor, con el método setArguments(Bundle) de la clase Activity o Fragment.
- Y ya está, luego en la clase podremos recuperar estos valores.
Opciones de tipo ratio
- Tenemos diferentes opciones y queremos seleccionar solo una
- En este caso usaremos el método setSingleChoiceItems(charSequence[] lista,int item_seleccionado,listener)
- Observamos el botón correspondiente para esta accion
- El código siguiente visualiza como adaptar un AlertDialog a este tipo de opciones
private void alertaOpcionesRatio() { // TODO Auto-generated method stub CharSequence[] sexo={"Hombre","Mujer","Prefiero no contestar"}; AlertDialog msj = AlertDialog.Builder(getActivity()); msj.setTitle(titulo) .setSingleChoiceItems(sexo,-1,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int elemento) { // TODO Auto-generated method stub ((Dialogo)getActivity()).opcionRatio(sexo[elemento]); } }); }
- El método opcionRatio(String opcion) es un método de la clase Dialogo al que pasamos la opcion seleccionada
- En nuestro caso lo único que hace es visualizar la opción
public void opcionRatio(CharSequence elemento) { // TODO Auto-generated method stb Toast.makeText(this,"Ha seleccionado la opcion "+elemento,Toast.LENGTH_SHORT).show(); }
checkButton como opciones
- Tenemos diferentes opciones y queremos seleccionar algunas de ellas
- En ella el usuario debe checkear distintas opciones (seleccionar idiomas)
- En este caso debemos invocar al método setMultiChoiceItems
- Este método le pasamos el vector de opciones, un vector de boolenos que nos dice cada opción si está o no seleccionada y un listener.
private void alertaOpcionesCheck() { // TODO Auto-generated method stub CharSequence[] idiomas={"Español","Inglés","Alemán","Rumano"}; boolean []idiomasSeleccionados = new boolean[idiomas.length]; AlertDialog msj = AlertDialog.Builder(getActivity()); msj.setTitle(titulo) .setMultiChoiceItems(idiomas, idiomasSeleccionados, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { // TODO Auto-generated method stub ((Dialogo)getActivity()).opcionCheck(idiomas,idiomasSeleccionados); } }
- En este caso al método setMultiChoiceItems(...) le pasamos tres parámetros
- idiomas que es el vector de opciones que queremos visualizar
- idiomasSeleccionados es un vector de booleanos que muestra si cada opción está o no seleccionada
- Una instancia de una clase listener para escuchar los objetos eventos generados por cualquier botón de las opciones
- De nuevo invocamos a un método de la clase Dialogo opcionCheck(...), al que pasamos el vector de idiomas y el de booneanos.
- El cuerpo del bucle quedaría
public void opcionCheck(CharSequence[] idiomas, boolean[] idiomasSeleccionados) { // TODO Auto-generated method stub String msj; msj = "Idiomas seleccionados: \n"; for (int i=0; i<idiomas.length;i++) if (idiomasSeleccionados[i]) msj+=idiomas[i]+"\n"; Toast.makeText(this, msj,Toast.LENGTH_SHORT).show(); } </sourece> ===Ventana dialogo con direfentes opciones=== *Es una alternativa a visualizar el radio, en cuanto el usuario seleciona uno ya queda seleccionado *En este caso añadimos el método setItems, en lugar de setMessage *El método setItems como primer parámetro le pasaremos un vector de charSequences y el segundo es un listener *Vemos el código <source lang=java> public void clickMsgOpciones(View v){ AlertDialog.Builder caja = new AlertDialog.Builder(this); caja.setTitle("Indica sexo") .setItems(sexo, new DialogInterface.OnClickListener() { uublic void onClick(DialogInterface dialog, int elemento) { // TODO Auto-generated method stub Toast t = Toast.makeText(getApplicationContext(), "Has seleccionado "+sexo[elemento],Toast.LENGTH_LONG); t.show(); dialog.cancel(); } }); AlertDialog alert = caja.create(); alert.show(); }
Ficheros con lo visto hasta ahora
- Se pueden descargar los ficheros de lo hecho hasta ahora
- La clase Dialogo.java Archivo:Dialogo.pdf
- La clase VentanaDialogo.java Archivo:VentanaDialogo.pdf
ProgressDialog
Barra de progreso circular
Barra de progreso horizontal
- Ahora le diremos que el objeto que tiene la forma horizontal de línea
- En este caso tenemos una barra que se va rellenando
- Esto implica que el progreso tendrá un valor inicial e irá modificando hasta llegar a estar totalmente rellena
- Vamos a añadir un botón para cancelar