miércoles, 7 de agosto de 2013

SUDOKU I: Diseño de la Interfaz de Usuario

A la hora de diseñar, podemos utilizar dos métodos: el procedimental, es decir, a través de código (tal y como hace Java), o el declarativo, que muestra cómo queremos que se vea nuestro programa (lenguaje XML). Google recomienda utilizar XML declarativo tanto como se pueda por varias razones: es un lenguaje más comprensible, es menos probable que cambie en versiones futuras y, aunque supone un código más largo, Android dispone de una herramienta de compresión XML muy buena (siendo el archivo comprimido el que se guarda en el móvil).

CREAR LA PANTALLA INICIAL
Tal y como hizo Guille en Hello World, creamos un nuevo proyecto. Podemos nombrarlo del siguiente modo:

-Application name: Sudoku
-Module name: Sudoku
-Package name: hagamosunaapp.blogspot.com.sudoku
-Project location: vuestro directorio de proyectos
-Activity Name: Sudoku

El resto de campos los dejaremos por defecto. Ahora podemos presionar el botón Run (parecido a un Play) para ver nuestra app en acción. Nos pedirá elegir uno de los emuladores móvil que previamente habíamos creado con el AVD Manager. Un consejo es dejar el emulador siempre encendido, ya que así se cargan antes los programas. Como podemos comprobar, hemos creado un programa similar al de Guille: un Hello World, Sudoku.

Vamos a sustituir todo esto por una pantalla inicial en la que el usuario pueda comenzar a jugar, continuar una partida, etc. En primer lugar, vemos que tras crear el proyecto, AS compone una sola actividad automáticamente en Sudoku.java:

Sudoku/src/main/java/hagamosunaapp.blogspot.com.sudoku/Sudoku.java




Lo que hace este código en esencia es crear una actividad, llamando al método onCreate() para iniciarla. También llama a setContentView() para rellenar el contenido de la pantalla con un widget Android, haciendo referencia a R.layout.activity_main, que es un identificador de RECURSO del archivo activity_main.xml. Este es el archivo que en estos momentos está definiendo el diseño de nuestra actividad, por lo que si queremos modificarlo tendremos que ir a su directorio:

Sudoku/src/main/res/layout/activity_main.xml




Un RECURSO es todo aquello que no es código, por ejemplo, una imagen. Como acabamos de ver, suelen guardarse en el directorio res. Pero además, hay que decir que cada vez que introducimos un archivo en este directorio, automáticamente se sincroniza con el archivo R.java situado en el siguiente directorio:

Sudoku/build/source/r/debug/hagamosunaapp…/R.java




Volviendo al directorio anterior activity_main.xml, vemos que se abre por defecto en un entorno visual. Podemos escoger en las pestañas de abajo entre Design y Text para ver el código. En este caso, al generar el proyecto, Android por defecto creó un layout de tipo RelativeLayout. Un LAYOUT es un contenedor de uno o más elementos secundarios, y sirve para posicionar los elementos dentro del marco principal. Algunos de los Layout más usados son:

-FrameLayout: Coloca los elementos en la esquina superior izquierda de la pantalla. Es útil para crear pestañas y controles.
-LinearLayout: Los coloca en una sola fila o columna.
-RelativeLayout: Organiza los elementos en relación a otros o al objeto principal.
-TableLayout: Coloca los elementos en filas y columnas, como una tabla.

En cuanto a algunos de los parámetros que definen el layout, podemos encontrar los siguientes:

-xmlns:android=”http://schemas.android.com/apk/res/android”: Define el espacio de nombres XML para Android.
-android:layout_width=”- ” : Define la anchura del objeto principal. Puede tomar distintos valores, como “match_parent” (similar a fill_parent, solo que es el parámetro utilizado a partir de la versión 1.6 de Android) utilizado para completar todo el ancho; o “wrap_content”, utilizado para ajustarse al contenido.
-android:layout_height=”-”: Similar en altura.

En cuanto al widget secundario <TextView, está definiendo una etiqueta de texto sencilla. Vamos a sustituirla por otro texto y varios botones. Empecemos:

En nuestro archivo activity_main.xml, escribimos lo siguiente:

<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/main_title" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/continue_label" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/new_game_label" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/about_label" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/exit_label" />


</LinearLayout>

Ahora vamos al directorio de strings.xml para darle los valores correspondientes a los botones que hemos creado:

Sudoku/src/main/res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Sudoku</string>
    <string name="action_settings">Settings</string>
    <string name="main_title">Android Sudoku</string>
    <string name="continue_label">Continue</string>
    <string name="new_game_label">New Game</string>
    <string name="about_label">About</string>
    <string name="exit_label">Exit</string>

</resources>


De modo que nuestra página inicial tiene que quedar parecida a esto:




Para darle un toque más estético, vamos a cambiar el tamaño al título, a centrarlo y a usar un color de fondo diferente. Para ello, creamos un archivo Values resourse file en el directorio (con el botón derecho del mouse, en New):

Sudoku/src/main/res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="background">#3500ffff</color>
</resources>
Aplicando los cambios a nuestro archivo activity_main.xml, tendríamos lo siguiente:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/background"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="30dip">


    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/main_title"
            android:layout_gravity="center"
            android:layout_marginBottom="25dip"
            android:textSize="24.5sp"/>
               
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/continue_label" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/new_game_label" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/about_label" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/exit_label" />


    </LinearLayout>
</LinearLayout>



Las siglas dip y sp son unidades de píxeles independientes de densidad y píxeles independientes de escala, respectivamente. Normalmente, se utiliza sp para definir el tamaño del texto, y dip para el resto.

Para comprobar cómo queda en nuestro emulador, presionamos el botón Run. Si queremos verlo en posición Horizontal, no tenemos más que presionar el botón 7 de nuestro teclado numérico y…¿qué ocurre? ¿nos ha desaparecido el botón Exit? 




Para ello crearemos un layout diferente para el modo horizontal. Creamos un archivo denominado res/layout-land/activity_main.xml, y escribimos lo siguiente:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/background"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dip">


    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:paddingLeft="20dip"
        android:paddingRight="20dip">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/main_title"
            android:layout_gravity="center"
            android:layout_marginBottom="20dip"
            android:textSize="24.5sp"/>
        <TableLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:stretchColumns="*" >
            <TableRow>
                <Button
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/continue_label" />
                <Button
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/new_game_label" />
            </TableRow>

            <TableRow>
                <Button
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/about_label" />
                <Button
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/exit_label" />
            </TableRow>
        </TableLayout>

    </LinearLayout>
</LinearLayout>

Como podéis observar, hemos dispuesto los botones en cuadrícula a partir de un TableLayout, definiendo cada fila mediante el comando TableRow. Es importante tener claro que al añadir el sufijo correcto al directorio, podemos encontrar las composiciones que buscamos, tal y como hemos hecho al añadir el sufijo –land a layout-land (modo horizontal en inglés se dice landscape).



Y creo que por hoy ya está bastante bien. Espero que no le cojáis miedo al tema del código, sino más bien todo lo contrario. Mi consejo es que todos estos códigos, en lugar de copiarlos, vayáis escribiéndolos poco a poco. Descubriréis que el propio AS tiene su función de autocompletado, motor de búsqueda de errores,… y os iréis haciendo al lenguaje. Es probable que el proyecto del Sudoku esté introduciendo muchos conceptos nuevos en muy poco tiempo, pero no os preocupéis, ya iremos tocando cada concepto con mayor profundidad.

Un saludo!





Jaime

2 comentarios:

  1. y e codigo del juego lo tienes?

    si es asi mandame el proyecto porfavor
    antonio96_21@hotmail.com

    ResponderEliminar
  2. y e codigo del juego lo tienes?

    si es asi mandame el proyecto porfavor
    antonio96_21@hotmail.com

    ResponderEliminar