Ejercicio Básico A - Vistas y Layouts

10

Click here to load reader

Transcript of Ejercicio Básico A - Vistas y Layouts

Page 1: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  1  de  10    

 

Curso PUDE

“Desarrollo de Aplicaciones Móviles en Android”

Ejercicio Básico A: Vistas y Layouts

  En  el  primer  ejercicio,  construimos  una  aplicación  sencilla  entre  todos  paso  a  paso.  En  este  segundo  ejercicio  el  objetivo  es  que  empecemos  a  coger  un  poco  de  soltura  escribiendo  código  para  aplicaciones  Android,  tanto  XML  como  Java.  

A. Descripción  En   este   ejercicio   nos   concentraremos   en   modificar   solamente   tres   archivos   de   un  

proyecto   Android:   la   Actividad   (Java),   la   interfaz   (XML)   y   los   textos   (XML).   Esto   lo  conseguiremos   añadiendo   vistas   (views)   a   una   aplicación   por   medio   de   XML,   y   luego   nos  conectaremos  a  ellas  a  través  de  código  Java  para  poder  actuar  cuando  se  produzcan  eventos,  como   la  pulsación  de  un  botón  En  el  camino,   iremos  descubriendo  nuevas  vistas,  además  de  nuevas  propiedades  y  listeners.  

B. Implementación  Comenzaremos   este   ejercicio   creando   un   nuevo   proyecto   Android   desde   Eclipse.   Le  

asignamos  un  nombre,  le  damos  una  versión  (recomendamos  2.2),  un  nombre  a  la  aplicación,  a  nuestro   paquete   (por   ejemplo:   com.[mi_nombre].android.apps.BasicoA)   y   a   la   Actividad   que  queremos  que   se  nos   cree  por  defecto;   finalmente  ponemos  un  “8”  en  el   campo  de  versión  mínima  de  SDK.  Una  vez  le  demos  a  Finalizar  estaremos  listos.  

B.1.  Primer  layout  Vamos  a  comenzar  editando  el  archivo  de  layout,  el  main.xml.  En  él  tendremos  ya  la  

estructura  creada  por  defecto,  en  la  que  destaca  un  TextView  con  un  texto.  Comenzaremos  a  trabajar  añadiendo  Views  y  ViewGroups1 bajo  éste.  Lo  que  queremos  hacer  es  un  clásico  CheckBox  para  habilitar  o  no  un  ViewGroup,  donde  guardaremos  una  vista.  Debido  a  que  también  queremos  practicar   los  eventos  de   las  Views,  necesitamos  también  un  TextView  que  acompañe  al  ya  mencionado  CheckBox.  

                                                                                                                         1  Las  clases  son  en  realidad  View  y  ViewGroup,  pero  para  hacer  más  fácil  entender  que  hablamos  de  más  de  una,  las  mencionamos  en  plural  y  con  la  letra  utilizada  por  el  Eclipse.  

Page 2: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  2  de  10    

 

El  código  XML  para  poder  añadir  un  CheckBox  seguido  de  un  TextView (main.xml)  es  el  siguiente:

 

 

Como  vemos,  hemos  añadido  dos  Views,  un  CheckBox  y  un  TextView.  A  ambas  les  hemos  dado  un  id,  para  poder  referenciarlas  desde  el  código  Java,  y  les  hemos  puesto  las  mismas  características  de  anchura  y  altura.    

El  CheckBox   viene   acompañado   de   un  TextView   internamente,   ahorrándonos   la  tarea  de  tener  que  añadirlo  nosotros  para  que  sea   intuitivo  de  usar.  Para  poder  asignarle  un  texto   solamente   tenemos   que   utilizar   la   propiedad   text.   Por   último,   hemos   puesto   por  defecto   que   el   CheckBox   no   esté   marcado   (checked=”false”)   En   el   caso   de   que  queramos  tenerlo  marcado  por  defecto  solamente  tenemos  que  ponerlo  a  true.  El  TextView  es  muy   sencillo.   Las   dos  únicas   propiedades  que   asignamos   son  número  mínimo  de   líneas   y  número  máximo  de   líneas,   de   forma  que   tenga   altura   suficiente   para  mostrar   dos   líneas   de  texto.  Es  una  forma  para  “forzar”  al  TextView  a  que  tenga  la  altura  que  queremos,  pero  no  la  mejor  (veremos  en  otro  ejercicio  una  forma  mucho  más  correcta  y  elegante)  

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello"> </TextView> <CheckBox android:id="@+id/enableViews" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/enableViews" android:checked="false"> </CheckBox> <TextView android:id="@+id/eventsTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="2" android:minLines="2"> </TextView> </LinearLayout>  

Page 3: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  3  de  10    

 

Con  esto  ya  tenemos  un  interruptor  y  un  lugar  donde  escribir.  Ahora  nos  hace  falta  un  LinearLayout  que  nos  guarde  las  vistas  con  las  que  vamos  a  practicar  un  poco.  Realmente,  este  Layout  que  vamos  a  añadir  no  es  necesario,  pero   lo  usamos  para  aprender.  El   código  que   sigue  al   último  TextView   (el    eventsTextView)   y   que   termina  antes  del   cierre  del  LinearLayout  principal  (o  raíz),  es  el  siguiente:  

 

 

A   este   LinearLayout   le   hemos   dado   un   id,   y   le   hemos   asignado   unas  características   de   anchura   y   altura   similares   a   las  Views   que   hemos   visto   antes.   Le   hemos  dicho   que   queremos   que   nos   coloque   las   Views   una   debajo   de   otra  (orientation=”vertical”),   y   le   hemos   dado   un   valor   de   layout_margin.   El  layout_margin   (como   su   nombre   indica)   es   una   distancia   que   separa   una  View/ViewGroup  cualquiera  del  marco  en  el  que  está  situada,  sean  los  límites  de  la  pantalla  u  otra  View.  layout_margin    tiene  una  propiedad  hermana,  padding,  que  en  este  caso  representa  un  margen  dentro  de   la  propia  View.  Existen  muchos  casos  en   la  práctica  en   los  que   es   muy   fácil   confundirlos   porque   sus   resultados   son   iguales,   pero   en   ningún   caso  representan  lo  mismo.  Para  nuestro  ejemplo,  utilizamos  un  layout_margin  de  7dp (“dp” se   explicará   en   un   ejercicio   posterior,   por   ahora   interpretar   que   son   píxeles),   es   decir,   un  margen   de   7   píxeles   respecto   a   las   cuatro   esquinas.   El   layout_margin   (al   igual   que   el  padding)  no  tiene  por  qué  ser  respecto  a  las  cuatro  esquinas;  también  puede  ser  respecto  a  una  esquina  o   lado  en  concreto   (ver   la  propiedad  layout_marginLeft y  similares)  Para  terminar  con  el  LinearLayout,  tenemos  la  propiedad  visibility  puesta  a  gone.  Como  su   nombre   indica,   la   propiedad  visibility   determina   si   el  LinearLayout   es   visible   o  no,  y   lo   interesante  es  que  si  el  LinearLayout  no  es  visible,  sus  hijos  no  lo  serán,  aunque  éstos   sean   visibles.   Una   View   tiene   tres   posibles   estados   de   visibilidad:   visible   (por  

<LinearLayout android:id="@+id/myViewsLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_margin="7dp" android:visibility="gone"> <!-- Botón circular --> <RadioButton android:id="@+id/myRadioButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/myRadioButton"> </RadioButton> </LinearLayout>

Page 4: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  4  de  10    

 

defecto),   invisible   y   gone.   visible   es   autoexplicativo,   y   la   diferencia   entre  invisible   y   gone   la   veremos   en   el   último   apartado.   Para   terminar   aquí,   tenemos   el  RadioButton,   que   es   hijo   de   nuestro   nuevo  LinearLayout.   Un  RadioButton   es   un  botón  especial;  deriva  de  la  clase  Button,  y  se  parece  mucho  a  un  CheckBox,  salvo  por  una  cosa:   el   CheckBox   puede   funcionar   como   interruptor   (apagado   /   encendido   o   viceversa),  pero  el  RadioButton  no.  El  RadioButton,  una  vez  marcado,  no  puede  desmarcarse.  Por  lo  demás,  su  declaración  no  contiene  nada  nuevo.  

Ahora   lo   ideal   sería   marcharnos   a   modificar   código   Java,   pero   no   podemos.   Como  Eclipse   ya   os   habrá   avisado,   existen   errores   que   debemos   solucionar.   Si   todo   ha  marchado  bien,  los  errores  provienen  de  las  propiedades  text,  que  referencian  a  una  cadena  (String)  del   archivo   strings.xml   que   aún   no   hemos   añadido.   Por   tanto,   vayámonos   al   archivo  strings.xml  y  dejémoslo  como  está  aquí:  

 

Con   este   código   XML,   los   errores   del  main.xml deberían   desaparecer.   Ahora,   por  fin,  podemos  empezar  a  jugar  con  Java.  

B.2.  Java  y  eventos    

Abrimos   nuestra   Actividad,   y   lo   primero   que   haremos   es   preparar   las   cosas   como   a  nosotros  nos  gustan:  nuestro  método  initConfig().  Comenzaremos  dejando  el  código  de  nuestra  Actividad  (lo  que  va  dentro  de  la  definición  de  la  clase)  como  vemos  aquí:  

<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, ViewsAndLayouts!</string> <string name="app_name">Vistas y Layouts</string> <string name="enableViews">Activar Layout</string> <string name="myRadioButton">Botón circular</string> </resources>  

Page 5: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  5  de  10    

 

 

Como   habréis   adivinado,   el   grueso   de   nuestro   código   de   hoy   va   dentro   del  método  initConfig().   Sin   embargo,   antes   de   empezar,   necesitamos   declarar   las   variables   que  vamos   a   utilizar.   Para   ello,   añadimos   el   siguiente   código   justo   antes   del   método  onCreate():  

 

Éstas  son  las  cuatro  referencias  que  vamos  a  necesitar.  Lo  siguiente  es  inicializar  las  variables  en  el  método    initConfig():  

 

Sin   duda,   éste   es   un   buen   momento   para   arrancar   la   aplicación.   Al   hacerlo,   vemos  nuestro  CheckBox,  y  al  tocarlo  vemos  que  se  marca  y  que  se  desmarca,  pero  no  ocurre  nada  más.  ¿Qué  es  lo  que  queremos  que  ocurra?  Pues  que  el  LinearLayout  se  vuelva  visible  si  el  CheckBox  está  marcado.  ¿Cómo  lo  hacemos?  Con  un  listener:  

 

 

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // llamamos a nuestro método de inicialización initConfig(); } private void initConfig() { setContentView(R.layout.main); }  

private CheckBox enableViews; private TextView eventsTextView; private LinearLayout myViewsLayout; private RadioButton myRadioButton;  

enableViews = (CheckBox) findViewById(R.id.enableViews); eventsTextView = (TextView) findViewById(R.id.eventsTextView); myViewsLayout = (LinearLayout) findViewById(R.id.myViewsLayout); myRadioButton = (RadioButton) findViewById(R.id.myRadioButton);  

Page 6: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  6  de  10    

 

 

 

Este  listener  nos  da  como  parámetros  el  botón  en  cuestión,  que  no  nos  hace  falta,  y  un  boolean   con   la   situación  actual   sobre   si   está  marcado  o  no.   Es   importante   tener  presente  que  esta   llamada   se  produce  después  de  que  el  CheckBox   cambie  de  estado,  no  antes.   Lo  único  que  debemos  hacer  es  cambiar  el  estado  de  visibilidad  según  el  booleano,  a  visible  o  a  gone.  Con  esto,  ya  deberíamos  conseguir  nuestro  objetivo:  que  sea  vea  y  que  no  sea  vea  el  RadioButton.  ¿Qué  nos  queda?  El  propio  RadioButton:  

   

Probemos   ahora.   Vemos   que   funciona   perfectamente,   pero   se   nos   formula   otra  pregunta,  y  es,  ¿cuántas  veces  se  ejecuta  este  listener?  Averiguarlo  es  muy  fácil.  Lo  primero  es  declarar   una   variable  de   tipo  int,   por   ejemplo  clickTimes;   la   declaramos   como  privada  debajo  de   las  demás  variables,   justo  encima  del  método  onCreate().   Luego,  alteramos  el  código  del  listener,  añadiendo  una  línea  antes  para  inicializar  clickTimes  a  cero:  

 

 

 

 

 

enableViews.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { myViewsLayout.setVisibility(View.VISIBLE); } else { myViewsLayout.setVisibility(View.GONE); } } });  

myRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { eventsTextView.setText("myRadioButton ha cambiado de estado."); } });  

Page 7: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  7  de  10    

 

 

Es  importante  señalar  que  la  línea  clickTimes = 0  se  ejecuta  una  sola  vez,  pero  el  código  que  está  dentro  del  setOnCheckedChangeListener se  ejecuta  cada  vez  que  el    RadioButton   cambie   de   estado,   que   es   lo   que   nos   promete   este   listener.   Solamente  tenemos   que   ejecutar   este   código   para   probarlo.   Si   de   verdad   quisiéramos   contar   cuántas  veces  hacemos  click  en  el  RadioButton,   lo  único  que  tendríamos  que  hacer  es  cambiar  de  listener,   y   utilizar   el   onClickListener,   que   se   ejecuta   una   vez   por   cada   click,  independientemente  de  si  se  cambia  de  estado  o  no:  

B.3  Visibilidad      

El   último   apartado   de   este   ejercicio   es   también   el   más   corto.   Aquí,   finalmente,  descubrimos   la   diferencia   entre   que   una  View   tenga   visibilidad  invisible   o  gone.   Para  ello,  debemos  volver  al  main.xml,  y  añadir  una  nueva  View,  justo  donde  lo  dejamos  antes,  es   decir,   tras   el   cierre  (</LinearLayout>)   del  Layout   que   guarda   al  RadioButton.  Éste  es  el  código  a  añadir:  

clickTimes = 0; myRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { clickTimes++; eventsTextView.setText("Clicked " + clickTimes + " times."); } });  

clickTimes = 0; myRadioButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { clickTimes++; eventsTextView.setText("Clicked " + clickTimes + " times."); } });

Page 8: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  8  de  10    

 

 

El   ToggleButton   es   una   mezcla   (a   nivel   de   concepto)   entre   el   CheckBox   y   el  Button  convencional.  Básicamente,  es  un  botón  clásico  con  estado,  donde  una  luz  nos  indica  si  está  marcado  o  no.  Visualmente,  se  parece  mucho  más  a  un  interruptor  que  un  CheckBox,  pero   a   nivel   práctico   (de   programación,   no   así   para   el   usuario)   son   lo   mismo.     La   primera  novedad  es  que  no  hemos  declarado  que  ocupe  todo  el  ancho  de  la  pantalla,  lo  cual  nos  da  pie  para   la   nueva   propiedad   que   vemos   allí,   layout_gravity.   Lo   que   nos   permite  layout_gravity   es   decirle   al   contenedor   (padre)   de   una   View   dónde   quiere   que   nos  coloque  en  el  caso  de  que  no  ocupemos  todo  el  espacio  que  podemos  ocupar.  Por  ejemplo  en  este  caso,  ninguna  otra  View  se  colocará  a  la  misma  altura  de  este  ToggleButton,  por   lo  que  nosotros  hemos  decidido  que  queremos  que  esté  en  el  centro.  Después  tenemos  que   la  propiedad  text  está  dividida  en  dos  casos  aquí,  una  para  cuando  el  botón  esté  presionado  o  marcado  (textOn),  y  otra  para  cuando  no  lo  está  (textOff).  

Como  siempre,  si  todo  ha  ido  bien,  los  errores  que  tendremos  serán  porque  nos  falta  declarar  las  dos  cadenas  en  el  archivo  strings.xml:  

 

 

  Ahora   volvemos   al   código   Java,   que   es   donde   se   producen   los   cambios.   ¿Qué  queremos   con  el   botón?  Muy   sencillo:   siempre   y   cuando  el  CheckBox   no   esté   activo,   si   el  ToggleButton   está   apagado   la   visibilidad   de   myLinearLayout   será   gone,   y   si   está  activado   será  invisible.   Los  dos   siguientes  pasos  os   los  dejamos   a   vosotros:   declarar   la  variable  ToggleButton toggleVisibility   y   unirla   con   la  View   de   la   interfaz   XML.  Por   último,   y   ya   para   terminar,   añadimos   este   código   al   initConfig(),   y   habremos  terminado:  

 

 

 

<ToggleButton android:id="@+id/toggleVisibility" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textOn="@string/invisible" android:textOff="@string/gone"> </ToggleButton>  

<string name="invisible">Invisible</string> <string name="gone">Gone</string>  

Page 9: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  9  de  10    

 

 

 

 

 

 

C. Conclusión    

El   objetivo  de  este  ejercicio  no  era   aburriros,   ni  mucho  menos   sino  que  os   sintierais  cómodos   trabajando  con   la  parte  XML  y   la  de   Java  que  permite   construir   las   interfaces.  Hay  muchas  propiedades  y  muchos  listeners  que  descubrir,  ¡así  que  adelante!  

   

toggleVisibility.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!enableViews.isChecked()) { if (isChecked) myViewsLayout.setVisibility(View.INVISIBLE); else myViewsLayout.setVisibility(View.GONE); } } });  

Page 10: Ejercicio Básico A - Vistas y Layouts

 

   

       

 Desarrollo de Aplicaciones Móviles en Android Ejercicio Básico A: Vistas y Layouts Autores: Jorge Carballo Franquis David D. Harjani Harjani

Página  10  de  10    

 

D. Opcionales    

Para   aquellos   alumnos   a   los   que   el   ejercicio   os   ha   sabido   a   poco,   o   que   habéis  terminado  antes,  proponemos  una  serie  de  cambios  o  modificaciones:  

-­‐ ¿Qué   ocurre   si   myViewsLayout,   en   vez   de   ser   de   tipo   LinearLayout,   lo  pusiéramos  de  tipo  ViewGroup,  relizando  los  cambios  pertinentes  en  nuestro  código  Java?  ¿Funcionaría?  ¿Se  comportaría  el  código  de  la  misma  forma?  ¿Por  qué?  

-­‐ El  CheckBox  enableViews  lo  estamos  inicializando  desde  XML,  dándole  un  texto  y  un  estado  de  “no  marcado”.  En  vez  de  hacerlo  en  XML,  hagámoslo  en   Java.  Primero  habría   que   borrar   las   dos   líneas   pertinentes   en   el   XML,   y   luego   añadir   otras   dos   de  código  Java.  

-­‐ Hemos  visto  que  el  RadioButton  sólo  puede  ser  marcado  una  vez.  ¿Qué  podemos  hacer  para  intentar  que  funcione  como  un  botón  normal?    ¿Funciona?    

-­‐ La  forma  en   la  que  utilizamos  el  ToggleButton  no  es  del  todo  correcta,  porque  si  cuando   los   dos   están   activados   (ToggleButton   y   el  CheckBox)   desactivamos   el  CheckBox,   myViewsLayout   se   queda   en   gone   en   vez   de   invisible  (ToggleButton  marcado)  Solucionarlo.   (Pista:  ¿de  qué   tipo  son  View.VISIBLE,  View.INVISIBLE  y  View.GONE?)