Diseño de la interfaz de usuario: vistas y layouts

Curso Android

Creación de la interfaz de usuario por código

No es la forma recomendable para trabajar.

@Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_main);
    TextView texto = new TextView(this);
    texto.setText("Hello, Android");
    setContentView(texto);
}

Ejemplo

  • La interfaz de usuario de Android está basada en una jerarquía de clases descendientes de la clase View (vista).

  • Una vista es un objeto que se puede dibujar y se utiliza como un elemento en el diseño de la interfaz de usuario (un botón, una imagen, una etiqueta de texto como en el utilizado en el ejemplo, etc.).

  • Cada uno de estos elementos se define como una subclase de la clase View; la subclase para representar un texto es TextView.

  • El ejemplo comienza creando un objeto de la clase TextView. El constructor de la clase acepta como parámetro una instancia de la clase Context (contexto).

  • Un contexto es un manejador del sistema que proporciona servicios como la resolución de recursos, obtención de acceso a bases de datos o preferencias.

  • La clase Activity es una subclase de Context, y como la clase MainActivity es una subclase de Activity, también es de tipo Context. Por ello, puedes pasar this (el objeto actual de la clase MainActivity) como contexto del TextView.

     

Creación de una interfaz de usuario usando XML

 A veces puede ser muy complicado programar interfaces de usuario, ya que pequeños cambios en el diseño pueden corresponder a complicadas modificaciones en el código.

Android proporciona una alternativa para el diseño de interfaces de usuario: los ficheros de diseño basados en XML.

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.myapplication.MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
</RelativeLayout>
  •  RelativeLayout, cuya función  es contener otros elementos de tipo View. Este RelativeLayout tiene cinco atributos:
    • Los dos primeros, xmlns:android, y  xmlns:tools son  declaraciones de  espacios de nombres de XML que utilizaremos en este fichero (este tipo de parámetro solo es necesario especificarlo en el primer elemento).
    • Los dos siguientes permiten definir el ancho y alto de la vista. En el ejemplo se ocupará todo el espacio disponible.
    • El último atributo indica la actividad asociada a este Layout.
  • Dentro del RelativeLayout solo tenemos un elemento de tipo TextView. Este dispone de tres atributos.
    • Los dos primeros definen el ancho y alto (se ajustará al texto contenido).
    • El último indica el texto a mostrar.

strings.xml

  • Es la práctica recomendada en Android para la inserción de textos en la aplicación.
  • Facilita su localización a la hora de realizar la traducción a otros idiomas.
<resources>
    <string name="app_name">My Application</string>
    <string name="hello_world">Hello World!</string>
</resources>

Clase R

  • Generado automaticamente por el compilador.
  • Se trata de una clase llena de variables estáticas en las que se identifica cada tipo de recurso .
public final class R {
 public static final class attr {
 }
 public static final class dimen {
 
 public static final int activity_horizontal_margin=0x7f040000;
 public static final int activity_vertical_margin=0x7f040001;
 }
 public static final class drawable {
 public static final int ic_launcher=0x7f020000;
 }
 public static final class id {
 public static final int action_settings=0x7f080001;
 public static final int texto1=0x7f080000;
 }
 public static final class layout {
 public static final int activity_main=0x7f030000;
 }
 public static final class menu {
 public static final int main=0x7f070000;
 }
 public static final class string {
 public static final int action_settings=0x7f050001;
 public static final int app_name=0x7f050000;
 public static final int hello_world=0x7f050002;
 public static final int hola_mundo=0x7f050003;
 }
 public static final class style {
 public static final int AppBaseTheme=0x7f060000;
 
 public static final int AppTheme=0x7f060001;
 }
}

Todas estas estructuras XML serán leidas cuando la aplicación arranque …. pero como nos encontramos en una plataforma movil el trabajo con XML directo podría ser demoledor y lento .

Por lo tanto Android despues de leer el fichero XML carga todas las estructuras que se han solicitado en memoria y mantiene el fichero R como referencia directa a los recursos que se han cargado de esta manera el acceso será directo y sencillo para el programador.

Usando la clase R

public class MainActivity extends Activity {
 
@Override
 protected void onCreate(Bundle savedInstanceState) {
 
 super.onCreate(savedInstanceState);
 
 setContentView(R.layout.activity_main);
 TextView texto1= (TextView) findViewById(R.id.texto1);
 texto1.setText(R.string.world);
 }

}
<resources>
    <string name="app_name">HolaMundo</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="hola_mundo">Hola Mundo</string> 
</resources>
<TextView android:id="@+id/texto1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />

setContentView(R.layout.activity_main) ;

Aquí, R.layout.activity_main corresponde a un objeto View que será creado en tiempo de ejecución a partir del recurso activity_main.xml.  Trabajar de esta forma, en comparación con el diseño basado en código, no quita velocidad y requiere menos memoria. Este identificador es creado automáticamente  en la clase R del proyecto a partir de los elementos de la carpeta res.

Los identificadores de la clase R son meros números que informan al gestor de recursos, que datos ha de cargar. Por lo tanto no se trata de verdaderos objetos, estos serán creados en tiempo de ejecución solo cuando sea necesario usarlos.

Edición visual de las vistas

Atributos de la clase View

Posición de la vista dentro del layout

  • layout_width, layout_height ajustar la anchura y altura de la vista. Dimensión concreta (por ejemplo, 200px), aunque lo habitual es utilizar uno de los siguientes valores:
    • wrap_content Ajusta el tamaño a las dimensiones necesarias para representar el contenido.
    • match_parent Ajusta el tamaño al máximo posible según el layout padre que la contiene. Ha sido renombrado match_parent a partir del nivel de API 8, aunque podemos utilizar también el nombre anterior.
  • layout_margin, layout_margin_botton, layout_margin_left, layout_margin_right, layout_margin_top Establece un margen exterior a la vista.
  • layout_gravity Centra o justifica la vista dentro del layout.
  • layout_weight Cuando estamos en un LinearLayout y se dispone de espacio libre sin utilizar, podemos repartirlo entre las vistas del layout, de forma que este se reparte proporcionalmente al valor indicado en este parámetro.

Definen el comportamiento

  • id Define el identificador que nos permitirá acceder a la vista.
    • Para crear nuevos identificadores utilizaremos la expresión "@+id/nombre_identificador".
    • Identificadores que ya han sido definidos en el sistema. Por ejemplo, utilizaremos "@android:id/list" para crear un ListView.
  • tag: Permite almacenar un string que podrá ser utilizado para cualquier fin. Es decir, una información extra que el programador podrá usar para fines específicos.
  • contentDescription: Cadena de caracteres que describe el contenido de la vista.
  • clickable Indica si la vista reacciona ante eventos de tipo onClick (se pulsa sobre la vista).
  • onClick Nombre del método que se invocará cuando ocurra un evento onClick (a partir de la versión 1.6). 
  • longClickable Indica si la vista reacciona a eventos de tipo pulsación larga (más de un segundo).
  • focusable Indica si la vista puede tomar el foco.
  • focusableInTouchMode Establece que cuando el dispositivo tenga capacidades de pantalla táctil y se pulsa sobre la vista, esta tomará el foco.
  • nextFocusDown, nextFocusLeft, nextFocusUp, nextFocusRight Permite especificar el movimiento del foco cuando usamos las cuatro teclas de cursor. En la mayoría de los casos no hace falta indicarlo, ya que se ajustará automáticamente según la posición de las vistas.

Aspectos visuales

  • visibility Permite hacer invisible una vista.
    • visible La vista es visible.
    • invisible La vista es invisible pero ocupa lugar.
    • gone La vista es invisible pero no ocupa lugar.
  • background Permite establecer una imagen de fondo.
  • style Permite aplicar un estilo a la vista.  
  • minWidth, minHeight Anchura y altura mínimas de la vista.
  • padding, paddingBottom, paddingTop, paddingLeft, paddingRight Establece un margen interior en la vista. Tiene sentido en vistas como Button para establecer un margen entre el texto y el borde del botón. Por el contrario, layout_margin establece la separación entre el borde del botón y otras vistas.

Atributos de dimensión

Tamaño de pantalla

  • Tamaño físico real para cuya medición se considera la diagonal de la pantalla.
  • Categorías generalizadas: pequeño, normal, grande y extragrande.

Densidad de pantalla

  • Cantidad de píxeles dentro de un área física de la pantalla, a la que en general se hace referencia como “dpi” (puntos por pulgada).
  •  Seis categorías generalizadas: baja, media, alta, extraalta, extra extraalta y extra extra extraalta.

Orientación

  • Orientación de la pantalla desde el punto de vista del usuario. Es horizontal o vertical, lo cual significa que la relación de aspecto se considera a lo ancho o a lo alto, respectivamente.

Resolución

  • Número total de píxeles físicos en una pantalla.
  • Cuando se agrega compatibilidad para pantallas múltiples, las aplicaciones no tienen una interacción directa con la resolución; se centran únicamente en la densidad y el tamaño de pantalla, como se especifica en los grupos de densidad y tamaño generalizados.

 

En muchas ocasiones tenemos que indicar la anchura o altura de una vista, un margen, el tamaño de un texto o unas coordenadas. Este tipo de atributos se conocen como atributos de dimensión. 

Android nos permite indicar estas dimensiones de varias formas.

 

px   (píxeles): Estas dimensiones representan los píxeles en la pantalla.

mm  (milímetros): Distancia real medida sobre la pantalla.

in    (pulgadas): Distancia real medida sobre la pantalla.

pt    (puntos): Equivale a 1/72 pulgadas.

 

dp  (Píxeles independientes de la densidad)

El píxel independiente de la densidad es equivalente a un píxel físico en una pantalla de 160 dpi, valor que representa la densidad de referencia que considera el sistema para una pantalla de densidad “media”. En el tiempo de ejecución, el sistema maneja de forma transparente cualquier ajuste de las unidades dp, cuando resulta necesario, según la densidad actual de la pantalla en uso. La conversión de unidades dp a píxeles de pantalla es simple: px = dp * (dpi / 160). Por ejemplo, en una pantalla de 240 dpi, 1 dp es igual a 1,5 píxeles físicos. Siempre debes usar unidades dp cuando defines la IU de tu aplicación, para asegurarte de que tu IU se muestre de manera apropiada en pantallas con diferentes densidades.

 

sp   (píxeles escalados): Similar a dp, pero también se escala en función del tamaño de fuente que el usuario ha escogido en las preferencias. Indicado cuando se trabaja con fuentes.

Layouts

  • Si queremos combinar varios elementos de tipo vista tendremos que utilizar un objeto de tipo Layout.
  • Un Layout es un contenedor de una o más vistas y controla su comportamiento y posición.
  • Hay que destacar que un Layout puede contener a otro Layout y que es un descendiente de la clase View.

Tipos de Layouts

  • LinearLayout: Dispone los elementos en una fila o en una columna.

  • TableLayout: Distribuye los elementos de forma tabular.

  • RelativeLayout: Dispone los elementos en relación a otro o al padre.

  • AbsoluteLayout: Posiciona los elementos de forma absoluta.

  • FrameLayout: Permite el cambio dinámico de los elementos que contiene.

  • ConstraintLayout: Versión mejorada de RelativeLayout, que permite una edición visual desde el editor y trabajar con porcentajes.

RelativeLayout

Permite comenzar a situar los elementos en cualquiera de los cuatro lados del contenedor e ir añadiendo nuevos elementos pegados a estos.

<RelativeLayout
   xmlns:android="http://schemas...
   android:layout_height="match_parent"
   android:layout_width="match_parent">
 <AnalogClock
   android:id="@+id/AnalogClock01"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignParentTop="true"/>
 <CheckBox
   android:id="@+id/CheckBox01"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_below="@id/AnalogClock01"
   android:text="Un checkBox"/>
 <Button
   android:id="@+id/Button01"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="Un botón"
   android:layout_below="@id/CheckBox01"/>
 <TextView
   android:id="@+id/TextView01"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignParentBottom="true"
   android:text="Un texto cualquiera"/>
</RelativeLayout>

LinearLayout

Es uno de los Layout más utilizado en la práctica. Distribuye los elementos uno detrás de otro, bien de forma horizontal o vertical.

<LinearLayout  xmlns:android="http://...
       android:layout_height="match_parent"      
       android:layout_width="match_parent"
       android:orientation ="vertical">
  <AnalogClock 
       android:layout_width="wrap_content"   
       android:layout_height="wrap_content"/>
  <CheckBox
       android:layout_width="wrap_content"   
       android:layout_height="wrap_content"
       android:text="Un checkBox"/>
  <Button
       android:layout_width="wrap_content"   
       android:layout_height="wrap_content"  
       android:text="Un botón"/>
  <TextView       
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"            
        android:text="Un texto cualquiera"/>
</LinearLayout>

TableLayout

Distribuye los elementos de forma tabular. Se utiliza la etiqueta <TableRow> cada vez que queremos insertar una nueva línea.

<TableLayout xmlns:android=”http://...
        android:layout_height="match_parent"
        android:layout_width="match_parent">
  <TableRow>
     <AnalogClock 
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"/>
     <CheckBox
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"  
        android:text="Un checkBox"/>
  </TableRow>
  <TableRow>
     <Button
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"   
        android:text="Un botón"/>
     <TextView  
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"   
        android:text="Un texto cualquiera"/>
  </TableRow>
</TableLayout>

AbsoluteLayout

Permite indicar las coordenadas (x,y) donde queremos que se visualice cada elemento. No es recomendable utilizar este tipo de Layout. De hecho, este tipo de Layout ha sido marcado como obsoleto.

<AbsoluteLayout xmlns:android="http://schemas.       
      android:layout_height="match_parent"       
      android:layout_width="match_parent">
  <AnalogClock 
      android:layout_width="wrap_content"   
      android:layout_height="wrap_content"
      android:layout_x="50px"
      android:layout_y="50px"/>
  <CheckBox
      android:layout_width="wrap_content"    
      android:layout_height="wrap_content"
      android:text="Un checkBox"
      android:layout_x="150px"
      android:layout_y="50px"/>
  <Button
      android:layout_width="wrap_content"    
      android:layout_height="wrap_content"   
      android:text="Un botón"
      android:layout_x="50px"
      android:layout_y="250px"/>
  <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"  
       android:text="Un texto cualquiera"
       android:layout_x="150px"
       android:layout_y="200px"/>
</AbsoluteLayout>

FrameLayout

Posiciona las vistas usando todo el contenedor, sin distribuirlas espacialmente. Este Layout suele utilizarse cuando queremos que varias vistas ocupen un mismo lugar. Podemos hacer que solo una sea visible, o superponerlas.

<FrameLayout  xmlns:android="http://schemas...
  android:layout_height="mach_parent"       
  android:layout_width="match_parent">
  <AnalogClock
     android:layout_width="wrap_content"    
     android:layout_height="wrap_content"/>
  <CheckBox
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="Un checkBox"/>
  <Button
     android:layout_width="wrap_content"    
     android:layout_height="wrap_content"
     android:text="Un botón"
     android:visibility="invisible"/>
  <TextView       
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="Un texto cualquiera"
     android:visibility="invisible"/>
</FrameLayout>

Otros Layouts

  • ScrollView: Visualiza una columna de elementos; cuando estos no caben en pantalla se permite un deslizamiento vertical.

  • HorizontalScrollView: Visualiza una fila de elementos; cuando estos no caben en pantalla se permite un deslizamiento horizontal.

  • FragmentTabHost, TabLayout ó TabHost: Proporciona una lista de ventanas seleccionables por medio de etiquetas que pueden ser pulsadas por el usuario para seleccionar la ventana que desea visualizar.

     

     

ListView: Visualiza una lista deslizable verticalmente de varios elementos. Su utilización es algo compleja.

 

GridView: Visualiza una cuadrícula deslizable de varias filas y varias columnas.

 

RecyclerView: Versión actualizada que realiza las mismas funciones que ListView o GridView. 

ViewFlipper: Permite visualizar una lista de elementos de forma que se visualice uno cada vez. Puede ser utilizado para intercambiar los elementos cada cierto intervalo de tiempo.

Material Design

Guía para el diseño visual de las aplicaciones, que Google no quiere aplicar exclusivamente a dispositivos móviles, sino que pretende utilizar material design en todo tipo de contenidos digitales

  • Diseños y colores planos.
  • Uno de sus principios es dar peso o materialidad a los elementos del interfaz de usuario. Para ello va a tratar de darle volumen o profundidad utilizando sombras, capas y animaciones.
  • La idea es que parezcan que están construidos de material físico.

Uno de los principios que se definen en Material Design es el uso del color. Google propone usar colores vivos y alegres.

Recursos Alternativos

Una aplicación Android va a poder ser ejecutada en una gran variedad de dispositivos. El tamaño de pantalla, la resolución o el tipo de entradas puede variar mucho de un dispositivo a otro. Por otra parte, nuestra aplicación ha de estar preparada para diferentes modos de funcionamiento, como el modo “automóvil” o el modo “noche”, y para poder ejecutarse en diferentes idiomas.

Afortunadamente, la plataforma Android nos proporciona una herramienta de gran potencia para resolver este problema: el uso de los recursos alternativos.

Creando layout alternativo

  • Pulsa con el botón derecho sobre la carpeta res/layout y selecciona New > Layout resorce file.
  • Aparecerá una ventana donde has de rellenar en File name (el mismo nombre que el fichero original) y en Available qualifiers: selecciona Orientation y pulsa en el botón >>.
  • En el desplegable Screen orientation: selecciona Landscape. Pulsa en OK.
  • Observa como ahora hay dos recursos para un mismo fichero. El primero es el recurso por defecto mientras que el segundo es el que se usará cuando el dispositivo esté en orientación Landscape.

Android utiliza una lista de sufijos para expresar recursos alternativos. Estos sufijos pueden hacer referencia a la orientación del dispositivo, al lenguaje, la región, la densidad de píxeles, la resolución, el método de entrada,…

Por ejemplo, si queremos traducir nuestra aplicación al inglés, español y francés. Siendo el primer idioma el usado por defecto, crearíamos tres versiones del fichero strings.xml y lo guardaríamos en los siguientes tres directorios:

res/values/strings.xml
res/values-es/strings.xml
res/values-fr/strings.xml

Aunque internamente el SDK de Android utiliza la estructura de carpetas anterior, en Android Studio el explorador del proyecto muestra los recursos alternativos de la siguiente manera:

res
  values
    strings.xml(3)
      strings.xml
      strings.xml(es)
      strings.xml(fr)

Creando un recurso alternativo

Crea un nuevo recurso alternativo para strings.xml (en):

  • Pulsa con el botón derecho en res/values,
  • Selecciona New > Values resource file e introduce strings.xml como nombre de fichero.
  • Mueve el cualificador Locale desde el marco de la izquierda a la derecha, pulsando el botón >>.
  • En Language seleciona en: English, en Specific Region Only deja el valor Any Region Only deja el valor Any Region y pulsa OK.

Otro ejemplo de utilización de recursos diferenciados lo podemos ver con el icono que se utiliza para lanzar la aplicación. Observa como, al crear una aplicación, este icono se crea en cinco carpetas drawable diferentes, para utilizar un icono distinto según la densidad de píxeles del dispositivo:

res/mipmap-mdpi/ic_launcher.png
res/mipmap-hdpi/ic_launcher.png
res/mipmap-xhdpi/ic_launcher.png
res/mipmap-xxhdpi/ic_launcher.png
res/mipmap-xxxhdpi/ic_launcher.png

Tipos de recursos y recursos del sistema

Añadir un recurso a nuestra aplicación es muy sencillo, no tenemos más que añadir un fichero dentro de una carpeta determinada de nuestro proyecto. Para cada uno de los recursos que añadamos el sistema crea, de forma automática, un id de recurso dentro de la clase R.

Tipos de recursos

Carpeta
identificador

Descripción

 

res/drawable/
R.drawable

Ficheros en bitmap (.png, .jpg o .gif). Ficheros PNG en formato Nine-patch (.9.png). Ficheros XML con descriptores gráficos (ver clase Drawable)

res/mipmap/
R.mipmap
Ficheros en bitmap (.png, .jpg o .gif). Estos gráficos no son rescaldados para adaptarlos a la densidad gráfica del dispositivo, sino que se buscará en las subcarpetas el gráfico con la densidad más parecida y se utilizará directamente.

res/layout/
R.layout

Ficheros XML con los Layouts usados en la aplicación.

res/menu/
R.menu

Ficheros XML con la definición de menús. Podemos asignar una actividad o una vista.

res/anim/
R.anim

Fichero XML que permiten definir una animaciones Tween también conocidas como animaciones de vista.

res/animator
R.animator

Ficheros XML que permiten modificar las propiedades de un objeto a lo largo del tiempo. (Véase apartado "Animación de propiedades"). Solo desde la versión 3.0.

res/xml/
R.xml

Otros ficheros XML, como los ficheros de preferencias

res/raw/
R.raw

Ficheros que se encuentran en formato binario. Por ejemplo ficheros de audio o vídeo.

res/values/

Ficheros XML que definen un determinado valor para definir un color, estilo, cadena de caracteres, etc. Se describen en la siguiente tabla.

Tipos de recursos dentro de values

Fichero por defecto
identificador

Descripción

strings.xml
R.string

Identifica cadenas de caracteres

<string name="saludo">¡Hola Mundo!</string>

colors.xml
R.color

Un color definido en formato ARGB (alfa, rojo, verde y azul). Los valores se indican en hexadecimal en uno de los siguientes formatos: #RGB, #ARGB, #RRGGBB ó #AARRGGBB

<color name="verde_opaco">#0f0</color>
<color name="red_translucido">#80ff0000</color>

 

dimensions.xml
R.dimen

Un número seguido de una unidad de medida.

px - pixeles, mm - milímetros, in – pulgadas, pt – puntos (=1/72 pulgadas), dp – píxeles independientes de la densidad (=1/160 pulgadas), sp – igual que dp pero cambia según las preferencias de tamaño de fuente.

<dimen name="alto">2.2mm</dimen>
<dimen name="tamano_fuente">16sp</dimen>

 

styles.xml
R.style

 

Definen una serie de atributos que pueden ser aplicados a una vista o a una actividad. Si se aplican a una actividad se conocen como temas.

<style name="TextoGrande" parent="@style/Text">         
   <item name="android:textSize">20pt</item>       
   <item name="android:textColor">#000080</item>    </style>

 

 

 

R.int

Define un valor entero.

<integer name="max_asteroides">5</integer>

R.bool

Define un valor booleano.

<bool name="misiles_ilimitados">true</bool>

R.id

Define un recurso de id único. La forma habitual de asignar id a los recursos es utilizando el atributo id="@+id/nombre". Aunque en algunos casos puede ser interesante disponer de id previamente creado, para que los elementos así nombrados tengan una determinada función. Este tipo de id se utiliza en las vistas TabHost y ListView.

<item type="id" name="button_ok"/>
<item type="id" name="dialog_exit"/>

R.array

Una serie ordenada de elementos. Pueden ser de strings, de enteros o de recursos (TypedArray)

<string-array name="dias_semana">                   

<item>lunes</item>
      <item>martes</item>
</string-array>

<integer-array name="primos">
       <item>2</item><item>3</item><item>5</item>
</integer-array>
<array
 name="asteroides">                  <item>@drawable/asteroide1</item>                 <item>@drawable/asteroide2</item>
</array>

   
   

Acceso a los recursos

<ImageView   

android:layout_height="@dimen/alto"
android:layout_width="match_parent"
android:background="@drawable/asteroide"
android:text="@string/saludo"
android:text_color="@color/verde_opaco"/>

 

Para acceder a un recurso definido en los ejemplos anteriores desde Java usaremos el siguiente código:

Resources res =getResources();
Drawable drawable =res.getDrawable(R.drawable.asteroide);
String saludo = res.getString(R.string.saludo);
int color =res.getColor(R.color.verde_opaco);
float tamanoFuente =res.getDimension(R.dimen.tamano_fuente);
int maxAsteroides =res.getInteger(R.integer.max_asteroides);
boolean ilimitados = res.getBoolean(R.bool.misiles_ilimitados);
String[] diasSemana =res.getStringArray(R.array.dias_semana);
int[] primos =res.getIntArray(R.array.primos);
TypedArray asteroides =res.obtainTypedArray(R.array.asteroides);
Drawable asteroide1 =asteroides.getDrawable(0);

Recursos de sistema

Usar recursos del sistema tiene muchas ventajas.

  • No consumen memoria en nuestra aplicación, al estar ya incorporados al sistema.
  • Los usuarios están familiarizados con ellos. Por ejemplo, si utilizamos el recurso android.R.drawable.ic_menu_edit se mostrará al usuario el icono:  
  • Estos recursos se adaptan siempre a las configuraciones locales. Si yo utilizo el recurso android.R.string.cancel este será “Cancelar”, “Cancel”, “取消”,... según el idioma escogido por el usuario.

Para acceder a los recursos del sistema desde código usaremos la clase android.R. Se utiliza la misma estructura de jerárquica de clases. Por ejemplo android.R.drawable.ic_menu_edit. Para acceder desde XML utiliza la sintaxis habitual pero comenzando con @android:. Por ejemplo @android:drawable/ic_menu_edit.

 

Estilos y temas

Estilos

Un estilo es una colección de propiedades que definen el formato y apariencia que tendrá una vista. Podemos especificar cosas como tamaño, márgenes, color, fuentes, etc. Un estilo se define en ficheros XML,  diferente al fichero XML Layout que lo utiliza.

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="#00FF00"
    android:typeface="monospace"
    android:text="Un texto" />
<TextView
    style="@style/MiEstilo"
    android:text="Un texto" />
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <style name="MiEstilo"
     parent="@android:style/TextAppearance.Medium">
       <item name="android:layout_width">match_parent</item>
       <item name="android:layout_height">wrap_content</item>
       <item name="android:textColor">#00FF00</item>
       <item name="android:typeface">monospace</item>
   </style>
</resources>

Heredar de un estilo propio

<style name="MiEstilo.grande">
     <item name="android:textSize">18pt</item>
</style>
<style name="MiEstilo.grande.negrita">
     <item name="android:textStyle">bold</item>
</style>

Temas

Un tema es un estilo aplicado a toda una actividad o aplicación, en lugar de a una vista individual. Cada elemento del estilo solo se aplicará a aquellos elementos donde sea posible.

Para aplicar un tema a toda una aplicación edita el fichero AndroidManifest.xml y añade el parámetro android:theme en la etiqueta <application>:

<application android:theme="@style/MiTema">

También puedes aplicar un tema a una actividad en concreto:

<activity android:theme="@style/MiTema">

Además de crear tus propios temas vas a poder utilizar algunos disponibles en el sistema. Puedes encontrar una lista de todos los estilos y temas disponibles en Android en:http://developer.android.com/reference/android/R.style.html

Vistas básicas

Button

Un control de tipo Button es el botón más básico que podemos utilizar y normalmente contiene un simple texto. En el ejemplo siguiente definimos un botón con el texto “Click” asignando su propiedad android:text. Además de esta propiedad podríamos utilizar muchas otras como el color de fondo (android:background), estilo de fuente (android:typeface), color de fuente (android:textcolor), tamaño de fuente (android:textSize), etc.

<Button android:id="@+id/BtnBotonSimple"
        android:text="@string/click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Toogle Button

Un control de tipo ToggleButton es un tipo de botón que puede permanecer en dos posibles estados, pulsado o no_pulsado. En este caso, en vez de definir un sólo texto para el control definiremos dos, dependiendo de su estado. Así, podremos asignar las propiedades android:textOn y android:textoOff para definir ambos textos. Veamos un ejemplo a continuación.

<ToggleButton android:id="@+id/BtnToggle"
        android:textOn="@string/on"
        android:textOff="@string/off"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Switch

Un control Switch es muy similar al ToggleButton anterior, donde tan sólo cambia su aspecto visual, que en vez de mostrar un estado u otro sobre el mismo espacio, se muestra en forma de deslizador o interruptor. Su uso sería completamente análogo al ya comentado:

<Switch android:id="@+id/BtnSwitch"
        android:textOn="@string/on"
        android:textOff="@string/off"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Image Button

En un control de tipo ImageButton podremos definir una imagen a mostrar en vez de un texto, para lo que deberemos asignar la propiedad android:src. Adicionalmente, al tratarse de un control de tipo imagen también deberíamos acostumbrarnos a asignar la propiedad android:contentDescription con una descripción textual de la imagen, de forma que nuestra aplicación sea lo más accesible posible.

<ImageButton android:id="@+id/BtnImagen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/icono_ok"
        android:src="@drawable/ic_estrella" />

Checkbox

Un control checkbox se suele utilizar para marcar o desmarcar opciones en una aplicación, y en Android está representado por la clase del mismo nombre, CheckBox.

<CheckBox android:id="@+id/ChkMarcame"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/marcame"
    android:checked="false" />
if (checkBox.isChecked()) {
    checkBox.setChecked(false);
}

RadioButton

Puede estar marcado o desmarcado, pero en este caso suelen utilizarse dentro de un grupo de opciones donde una, y sólo una, de ellas debe estar marcada obligatoriamente, es decir, que si se marca una de las opciones se desmarcará automáticamente la que estuviera activa anteriormente. En Android, un grupo de botones radio button se define mediante un elemento RadioGroup, que a su vez contendrá todos los elementos RadioButton necesarios.

<RadioGroup android:id="@+id/GrbGrupo1"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <RadioButton android:id="@+id/RbOpcion1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/opcion_1" />
 
    <RadioButton android:id="@+id/RbOpcion2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/opcion_2" />
</RadioGroup>
RadioGroup rg = (RadioGroup)findViewById(R.id.GrbGrupo1);
rg.clearCheck();
rg.check(R.id.RbOpcion1);
int idSeleccionado = rg.getCheckedRadioButtonId();

ImageView

El control ImageView permite mostrar imágenes en la aplicación.

  • android:src, que permite indicar la imagen a mostrar.
  • android:maxWidth y android:maxHeight: tamaño máximo que puede ocupar la imagen.
  • android:scaleType (5=CENTER, 6=CENTER_CROP, 7=CENTER_INSIDE, …) o para indicar cómo debe adaptarse la imagen al tamaño del control.
  •  android:contentDescription: breve descripción textual de la imagen, algo que hará nuestra aplicación mucho más accesible.
<ImageView android:id="@+id/ImgFoto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher"
    android:contentDescription="@string/imagen_ejemplo" />

TextInputLayout

<android.support.design.widget.TextInputLayout
    android:id="@+id/TiLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >
 
    <EditText android:id="@+id/TxtInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Escribe un número par" />
 
</android.support.design.widget.TextInputLayout>
txtInputLayout = (TextInputLayout)findViewById(R.id.TiLayout);
txtInputLayout.setErrorEnabled(true);
 
txtInput = (EditText)findViewById(R.id.TxtInput);
 
btnComprobar = (Button)findViewById(R.id.BtnInputLayout);
btnComprobar.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String num = txtInput.getText().toString();
 
        if(num.isEmpty() || Integer.parseInt(num)%2 != 0)
            txtInputLayout.setError("Error: No es un número par!");
        else
            txtInputLayout.setError(null);
    }
});

Diseño de la interfaz de usuario

By Marina Garcia

Diseño de la interfaz de usuario

  • 1,241