Creación de una interfaz de usuario usando XML

En el ejemplo anterior hemos creado la interfaz de usuario directamente en el código. 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. Un principio importante en el diseño de software es que conviene separar todo lo posible el diseño, los datos y la lógica de la aplicación.

Android proporciona una alternativa para el diseño de interfaces de usuario: los ficheros de diseño basados en XML. Veamos uno de estos ficheros. Para ello accede al fichero res/layout/activity_main.xml de nuestro proyecto. Se muestra a continuación. Este layout o fichero de diseño proporciona un resultado similar al del ejemplo de diseño por código anterior:

<android.support.contraint.ContraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</android.support.contraint.ContraintLayout>

NOTA: Cuando haces doble clic en el  explorador del proyecto sobre activity_main.xml, probablemente lo abra en modo gráfico. Para verlo en modo texto selecciona la pestaña Text 

Resulta sencillo interpretar su significado. Se introduce un elemento de tipo CoinstraintLayout, cuya función como se estudiará más adelante  es contener otros elementos de tipo View. Este CoinstraintLayout tiene seis atributos. Los tres primeros, xmlns:android, xmlns:app 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 CoinstraintLayout solo tenemos un elemento de tipo TextView. Este dispone de varios atributos. Los dos primeros definen el ancho y alto (se ajustará al texto contenido). El  siguiente indica el texto a mostrar. Los cuatro siguientes indican la posición de la vista dentro del CoinstraintLayout.

Ejercicio paso a paso: Creación del Interfaz de usuario con XML

1.    Para utilizar el diseño en XML regresa al fichero MainActivity.java y deshaz los cambios que hicimos antes (elimina las tres últimas líneas y quita el comentario).

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

2.    Ejecuta la aplicación y verifica el resultado. Ha de ser muy similar al anterior.

3.    Modifica elvalor de hello_world en el fichero res/values/strings.xml.

4.    Vuelve a ejecutar la aplicación y visualiza el resultado.

 Analicemos ahora la línea en la que acabas de quitar el comentario:

       setContentView(R.layout.activity_main) ;

Aquí, R.layout.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. La definición de la clase R puede ser similar a:

 

public final class R {
    public static final class attr {
 }
    public static final class drawable {
        public static final int ic_launcher=0x7f020000;
    }
    public static final class id {
       public static final int action_settings=0x7f070000;
    }
    public static final class layout {
        public static final int activity_main=0x7f030000;
    }
    public static final class menu {
        public static final int main=0x7f060000;
    }
    public static final class string {
        public static final int app_name=0x7f040000;
    ...

NOTA: Este fichero se genera automáticamente. Nunca debes editarlo.

Has de tener claro que 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.

Ejercicio: El fichero R.java.

1.    En Android Studio, el fichero R.java no es accesible desde el explorador de proyecto. No obstante, puedes acceder a él si pulsas con el botón derecho sobre app y seleccionas Show in Explorer. Desde esta carpeta abre el fichero:

app\build\generated\source\r\debug\nombre\del\paquete\R.java

Donde nombre\del\paquete has de reemplazarlo por el que corresponda al paquete de tu aplicación.

2.    Comparalo con el fichero mostrado previamente. ¿Qué diferencias encuentras? (RESPUESTA: cambia los valores numéricos en hexadecimal y contiene muchos más identificadores).

3.    Abre el fichero MainActivity.java y reemplaza R.layout.activity_main por el valor numérico al que corresponde en R.java.

4.    Ejecuta de nuevo el proyecto. ¿Funciona? ¿Crees que sería adecuado dejar este valor numérico?

5.   Aunque haya funcionado, este valor puede cambiar en un futuro. Por lo tanto para evitar problemas futuros vuelve a reemplazarlo por R.layout.activity_main.

Preguntas de repaso: Diseño del interfaz de usuario en XML y en código

Preguntas de repaso: El fichero R.java