Búsqueda personalizada

Blog personal para aprender a programar en Android desde cero.

Mostrando entradas con la etiqueta HelloWorld. Mostrar todas las entradas
Mostrando entradas con la etiqueta HelloWorld. Mostrar todas las entradas

martes, 9 de marzo de 2010

Hello Views VI

List View

Para crear una lista de elementos scrollables utilizaremos ListView. Estos elementos se insertarán automáticamente en la lista usando un ListAdapter.

En el ejemplo que nos proponen en Android Labs, veremos una lista de países que leeremos de un array de strings. Cuando seleccionemos un elemento, un Toast se mostrará diciéndonos su posición en la lista.

Los pasos resumidos son:

  1. Crear el proyecto con Eclipse indicando la Activity HelloListView
  2. Crear un fichero llamado list_item.xml y copiar el contenido en el directorio res/layout/. Es el layout para cada elemento de la lista.
  3. Modificar la clase padre de HelloListView. Ahora tiene que heredar de ListActivity
  4. Rellenar el método onCreate()
  5. Copiar el array de paises (o lo que queramos listar)
  6. Ejecutar la aplicación




Ahora vamos comentar los puntos más importantes del ejemplo.

  • Podemos ver que list_item.xml simplemente nos dice que cada elemento de la lista será una TextView. Aquí podríamos añadir por ejemplo una imagen al lado del texto.
  • ¿Porqué heredamos de ListActivity? Pues porque un ListActivity nos permite mostrar una lista de elementos vinculados a un data source, como un array. Además permite eventos sobre los elementos de la lista.
  • En el método onCreate() vemos cosas interesantes. Por ejemplo, que no cargamos ningún fichero de layout. En vez de esto, indicamos un ListAdapter con setListAdapter(ListAdapter), que añade automáticamente un ListView que rellena toda la pantalla de la ListActivity.
  • Al setListAdapter(ListAdapter) le pasamos como parámetros un ArrayAdapter. Para construir este objeto tenemos que pasarle el contexto (en nuestro caso con el this), el layout que utilizaremos para mostrar los elements (list_item.xml), y el array o lista de objecto que queremos mostrar (los países).
  • El método setTextFilterEnabled(boolean) de la ListView hace posible que podamos filtrar el listado.
  • El método setOnItemClickListener(OnItemClickListener) define un onClick listener para cada elemento, como vimos en el HelloGridView.
  • La manera de definir el array de strings, en hardcode, no es la mejor. Para hacerlo de una manera más elegante y práctica es mejor referenciarlo desde un fichero externo. El array deberemos declararlo de la siguiente forma, y ubicándolo el fichero strings.xml en el directorio res/values:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="countries_array">
<item>Bahrain</item>
<item>Bangladesh</item>
<item>Barbados</item>
<item>Belarus</item>
<item>Belgium</item>
<item>Belize</item>
<item>Benin</item>
</string-array>
</resources>

  • Ahora para cargar el ListAdapter tenemos que pasar el array de strings de la siguiente forma:
                   String[] countries = getResources().getStringArray(R.array.countries_array);
                   setAdapter(new ArrayAdapter(this, R.layout.list_item, countries));


Dudas
Me surge la duda de si el método setTextFilterEnabled(boolean) sólo funciona cuando nuestros elementos son TextView, o siempre aunque sean de otro tipo y el filtro se haga por algún identificador o descripción.

Notas
Como nos indica Android Labs en el ejemplo, android ya proporciona unos layouts de serie, cosa que no conocía hasta ahora. Os dejo el enlace.




sábado, 6 de marzo de 2010

Hello Views V

TabLayout

Como nos dicen en Android Labs, para crear una interfaz con pestañas o tabs, necesitaremos usar un TabHost y un TabWidget. El TabHost será el nodo raíz de nuestro layout, que tendrá el TabWidget para mostrar las pestañas, y un FrameLayout para enseñar el contenido de las pestañas.

Existen dos formas de implementar un IU con pestañas: en una sola Activity o en una Activity por pestaña. Este último método es el más indicado ya que tendremos separadas las funcionalidades, y lo utilizaremos para este ejemplo.






Los pasos resumidos son:
  1. Crear el proyecto con Eclipse indicando la Activity HelloTabWidget
  2. Crear 3 Activity's más: ArtistsActivity, AlbumsActivity y SongsActivity. Poniendo en cada método onCreate de las 3 Activity un TextView identificativo
  3. Para cada pestaña necesitamos dos imágenes, una para cuando está activada y otra para cuando no (en la página de Android Labs sólo vemos la imagen del micro, podemos coger otras para realizar el ejemplo). Además necesitamos un fichero XML, que hace de selector para realizar precisamente esa acción. Tanto las imágenes como los ficheros XML se guardan en res/drawable
  4. Crear o copiar el contenido del fichero main.xml
  5. Modificar la Activity principal, HelloTabWidget, para que herede de TabActivity en vez de Activity
  6. Copiar todo el código del método onCreate
  7. Cambiar el tema de la aplicación
  8. Ejecutar aplicación
    Los puntos clave de este ejemplo (bajo mi punto de vista) son:
    • El selector: La manera de mostrar una imagen para cuando la pestaña está activa o no se realiza en un fichero XML,  y un fichero por Activity. El tag es <selector> y dentro muestra los items que puede mostrar. Con el atributo android:state_selected="true" indicamos cuál es la imagen/item a mostrar cuando la pestaña está activa. Este recurso (fichero XML), se lo tenemos que pasar al método setIndicator a cada Tab.
        
          <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
                    <!-- When selected, use grey -->
                    <item android:drawable="@drawable/ic_tab_artists_grey" android:state_selected="true" />
                    <!-- When not selected, use white-->        
                      <item android:drawable="@drawable/ic_tab_artists_white" />
    </selector>

    • main.xml: Vemos que la vista empieza y acaba por con el TabHost. Después de indicar el xmlns, id y forma de relleno, vemos un LinearLayout. Dentro de ésto vemos lo importante, un TabWidget y un FrameLayout. El TabWidget ocupa a lo ancho el mismo espacio que su parent, y a lo alto el espacio necesario para mostrarse entero, es decir, el tamaño de la imagen.
    •  onCreate: Conseguimos los recursos, el TabHost con getTabHost (método específico de la clase TabActivity). Creamos un TabHost.TabSpec, que sirve para indicar las propiedades de una pestaña. Esta variable la vamos reutilizando una vez añadimos una pestaña al TabHost con addTab(spec).
    • Themes: En el ejemplo lo único que hace este tema es no mostrar el título de la aplicación. Pero se pueden hacer muchísimas más cosas. Más info aquí.
    Notas

    • En el código del ejemplo hay un fallo, en el método onCreate indica mTabHost.addTab(spec); cuando quiere decir tabHost.addTab(spec);.
    • No os olvidéis de cada pestaña tiene dos imágenes y un XML (selector), y que desde el XML se hace referencia al recurso de la imagen (<item android:drawable="@drawable/nombre_imagen"/>). Y que todo va dentro del directorio res/drawable/.
    • Y tampoco os olvidéis de incluir las 3 Activity en el fichero main.xml.



    jueves, 4 de marzo de 2010

    Hello Views IV

    GridView

    Un GridView también es un ViewGroup, que muestra sus hijos en una grid scrollable de manera bidimensional. A diferencia de las otras vistas, los elementos no se van añadiendo en el main.xml, sino que lo hacen a través de un ListAdapter.

    En el ejemplo de AndroidLabs nos enseñan a crear una GridView con imágenes en miniatura. Los pasos que tenemos que seguir, y que luego explicaré, son los siguientes:

    1. Crear el proyecto con Eclipse indicando la Activity HelloGridView.
    2. Copiar las imágenes que queremos visualizar en res/drawable (las del ejemplo son estas
    3. Crear o copiar el contenido del fichero main.xml
    4. Crear y copiar el contenido de la clase ImageAdapter, que hereda de la clase BaseAdapter
    5. Copiar el siguiente texto en el método onCreate de la Activity:
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.main);

                 GridView gridview = (GridView) findViewById(R.id.gridview);
                 gridview.setAdapter(new ImageAdapter(this));

                 gridview.setOnItemClickListener(new OnItemClickListener() {
                        public void onItemClick(AdapterView parent, View v, int position, long id) {
                            Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
                        }
                });

    En este caso lo más importante no es el main.xml, pero que también voy a comentar:

    • android:columnWidth: ancho de la columna
    • android:numColumns: número de columnas. (auto-fit, se ajusta automáticamente)
    • android:verticalSpacing: separación vertical entre elementos
    • android:horizontalSpacing: separación horizontal entre elementos
    • android:stretchMode: forma de estirar el contenido. columnWidth, a lo ancho de la columna 


    La 'chicha' empieza en el método onCreate de la Activity:

    GridView gridview = (GridView) findViewById(R.id.gridview); 
    gridview.setAdapter(new ImageAdapter(this));

    Obtenemos el id de nuestra vista, la grid. Hemos indicado ese id en el fichero main.xml, cuando hemos creado el GridView.

    gridview.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View v, int position, long id) {
      Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
    }
    });

    Añadimos un Listener para cuando hacemos click en el item, una imagen. Al pulsar mostramos un Toast (especie de popup) en el que vemos la posicion de la imagen.

    Por último encontramos la clase ImageAdapter, que hereda de la clase BaseAdapter. El método importante es getView(). Este método esta sobreescribiendo al método de la clase Adapter, de la que hereda BaseAdapter, y es llamado cada vez que se va a pintar un elemento de la GridView. En nuestro caso carga las imágenes que hemos descargado antes, y en el orden que le indicamos en el array mThumbIds.

    Dudas 
    Creo que el parámetro convertView viene a null la primera vez que cargamos la GridView, pero en las siguientes llamadas nos viene ya la ImageView. Por eso comprobamos si viene a null o no. ¿Me equivoco?

    Hello Views III

    TableLayout
    Como las anteriores vistas, la clase TableLayout es una ViewGroup que muestra sus hijos (Views), en filas y columnas. Y también empezamos del mismo modo:

    1. Crear el proyecto con Eclipse indicando la Activity HelloTableLayout.
    2. Crear o copiar el contenido del fichero main.xml.
    3. Cargar la vista en el método onCreate de nuestra Activity.
    4. Ejecutar
    Podemos ver dos tablas, que se identifican por el tag TableLayout, y en este caso los atributos importantes son los siguientes:


    • android:stretchColumns: el número de columnas empezando por el 0. Es decir, el 1 indica que hay dos columnas.
    • android:layout_column: índice de la columna en la que queremos mostrar un elemento.
    • android:padding:el relleno
    • android:gravity: la manera de alinear el texto cuando es más pequeño que la vista.
    Como veis es bastante parecido a las tablas HTML.




    Curiosidad
    Me ha parecido bastante curioso la forma de crear las lineas de separación entre las dos tablas:
                           <View
                                     android:layout_height="2dip"
                                     android:background="#FF909090" />

    Es un elemento View, clase de la que heredan los TextView, etcétera, con una altura de 2dip (en otro post explicaré porqué es aconsejable usar este tipo de unidad), con un color de fondo determinado en RGB.




    martes, 2 de marzo de 2010

    Hello Views II


    RelativeLayout
    La clase RelativeLayout, al igual que LinearLayout, hereda de ViewGroup. Pero en este caso los elementos se muestran de manera relativa los unos con los otros.
    Seguimos los pasos del tutorial:

    1. Crear el proyecto con Eclipse indicando la Activity HelloRelativeLayout.
    2. Crear o copiar el contenido del fichero main.xml
    3. Cargar la vista en el método onCreate de nuestra Activity.
    4. Ejecutar
    En el fichero main.xml podemos identificar el inicio y el final de nuestro layout <RelativeLayout>...</RelativeLayout>. Pero en este caso lo más importante lo encontramos dentro de cada componente View, su posición relativa. En el ejemplo:

    • android:id="@+id/xxx": El + de @ que el id del elemento se crea automáticamente si no existe.
    • android:layout_below="@id/label": Debajo de. En el ejemplo podemos ver que la caja de texto está debajo de la etiqueta. Tenemos que poner el id del elemento del cuál nos posicionamos relativamente. 
    • android:layout_alignParentRight="true": Si es cierto, el lado derecho del elemento coincide con el lado derecho del padre. Vemos que el botón de Ok, además de estar debajo de la caja de texto, está a la derecha, coincidiendo con el lado derecho del parent.
    • android:layout_marginLeft="10dip": Indica la cantidad de margen que queremos en el lado izquierdo de nuestro elemento.
    • android:layout_toLeftOf="@id/ok": A la izquierda de. En el ejemplo vemos como el botón de cancelar se sitúa a la izquierda del botón de Ok.
    • android:layout_alignTop="@id/ok": La parte superior alineado con. El lado superior del botón cancelar está a la misma altura que el lado superior del botón Ok.




    Para otros atributos del RelativeLayout mirar RelativeLayout.LayoutParams.

    Siempre es aconsejable manusear un poco el código que cogemos de ejemplo. ¿Lo habéis hecho? ¿Alguna duda?



    Hello Views I

    Continuando con los recursos de Android Labs, lo siguiente que vamos hacer es un HelloWorld para cada tipo de vista. En esta primera entrega veremos el LinearLayout.

    LinearLayout
    Este layout es una vista en grupo, la cuál muestra los subelementos de manera lineal.Si vamos a la api de  la clase LinearLayout vemos que hereda de la clase ViewGroup.
    Vamos a seguir los pasos del tutorial:
    1. Crear el proyecto con Eclipse indicando la Activity HelloLinearLayout.
    2. Crear o copiar el contenido del fichero main.xml
    3. Cargar la vista en el método onCreate de nuestra Activity.
    4. Ejecutar
    Como podemos ver en la pantalla tenemos dos layouts, uno horizontal mostrando 4 colores, y uno vertical mostrando 4 filas con texto:

      Ahora vamos a comentar lo importante, el fichero main.xml. Como decíamos, podemos identificar los dos layouts: 
      • <LinearLayout android:orientation="horizontal"...>...</LinearLayout>
      • <LinearLayout android:orientation="vertical"...>...</LinearLayout>
      Los atributos que configuran nuestros LinearLayout son:
      • android:orientation :indica la orientación del layout.
      • android:layout_width: indica el modo de relleno a lo ancho. fill_parent hace que ocupe todo el espacio que nos deja el elemento "padre".
      • android:layout_height: indica el modo de relleno a lo largo/alto.
      • android:layout_weight: indica la importancia del elemento dentro de la vista. El 0 es el valor menos importante. (más información en Common Layout Objects)
      Dentro de los LinearLayouts están los TextView que contienen el texto a enseñar, cosa que no es muy práctica pero que nos sirve para simplificar el ejemplo.

      Dudas
      Después de estar un rato jugando con el fichero main.xml y modificar los valores del atributo android:layout_weight de los TextView, he visto que efectivamente cambia el tamaño al variar los valores. Concretamente he puesto un 2 a los TextView rojo y amarillo, que han incrementado su tamaño pero no ocupan lo mismo, el amarillo ocupa más.
      No sé cuál es el motivo, ¿pero es por el tamaño del texto? yellow es más largo que red.



      domingo, 28 de febrero de 2010

      Hello World / Hello Android

      Una vez tenemos el entorno preparado vamos hacer nuestro primer proyecto. Siguiendo como guía Android Labs, nos recomiendan hacer el típico HelloWorld.
      Los pasos que nos indican son los siguientes:
      1. Crear el AVD, que ya hicimos en el último paso del post anterior.
      2. Crear el projecto en Eclipse.
      3. Construir la Interfaz de Usuario dentro de la clase.
      4. Ejecutar la aplicación.
      Esta manera de crear la interfaz de usuario dentro del código se llama programática. Puede ser útil para interfaces sencillas, y también se puede utilizar para crear algún elemento de manera dinámica. Pero esta forma es difícil de mantener, y por ello Android ofrece la posibilidad de crear las IU a partir de layouts en ficheros XML. Por ejemplo:



      <?xml version="1.0" encoding="utf-8"?>
      <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="@string/hello"/>

      ¿Dónde ubicamos estos ficheros XML? Primero vamos a ver la estructura de directorio:


      • src/: código de nuestras clases
      • gen/: código generado
      •  assets/: desconozco!
      • res/drawable/: imágenes
      • res/layout/: layouts para nuestra IU
      • res/value/: textos 

      Para más detalles, recomiendo mirar Application Fundamentals. En los próximos post intentaré explicar de manera sencilla el contenido de esta página.

      Ya hemos acabado con nuestro HelloWorld!! Si ejecutamos veremos que los resultados son iguales, tanto creando la IU programáticamente como con layouts.

      Problemas
      La guía de Android Labs es bastante sencilla de seguir, pero durante la realización me encontré con un problema. Después de estar jugando con los ficheros, me daba el siguiente error:
      main.out.xml already defined
      Después de googlear un rato no supe cuál era el motivo, pero lo solucioné eliminando el archivo main.out.xml a mano.