martes, 29 de diciembre de 2015

AngularJS: Data Binding

El binding no es más que enlazar la información que tenemos en el "scope" con lo que mostramos en el HTML. Esto se produce en dos sentidos:
One-way binding: 
En este caso la información solamente fluye desde el scope hacia la parte visual, es decir, desde el modelo hacia la representación de la información en el HTML. Lo conseguimos con la sintaxis "Mustache" de las dos llaves.
{{ dato }}
Ese dato estarías trayéndolo desde el scope y mostrándolo en la página. La información fluye desde el scope hacia la representación quiere decir que, si por lo que sea se actualiza el dato que hay almacenado en el modelo (scope) se actualizará automáticamente en la presentación (página).
Two-way binding: 
En este segundo caso la información fluye desde el scope hacia la parte visual (igual que en "one-way binding") y también desde la parte visual hacia el scope. La implementas por medio de la directiva ngModel.
<input type="text" ng-model="miDato" />
En este caso cuando el modelo cambie, el dato que está escrito en el campo de texto (o en el elemento de formulario donde lo uses) se actualizaría automáticamente con el nuevo valor. Además, gracias al doble binding (two-way) en este caso, cuando el usuario cambie el valor del campo de texto el scope se actualizará automáticamente.

Cómo puedo experimentar el binding

Realmente en los ejemplos más sencillos de AngularJS ya hemos experimentado el binding. No me hace falta ni Javascript para poder hacer un ejemplo donde se pueda ver en marcha perfectamente.
<div ng-app>
  <input type="text" ng-model="dato" />
  {{dato}}
  <input type="button" value="hola" ng-click="dato='hola'" />
</div>
Mira, tienes tres elementos destacables.
  • Un campo de texto con ng-model="dato". En ese campo tenemos un "doble binding". 
  • Una expresión {{dato}} donde se mostrará aquello que haya escrito en el campo de texto. En este caso tenemos un binding simple, de un único sentido. 
  • finalmente tienes un botón que no tiene bindig alguno. Simplemente, cuando lo pulses, estás ejecutando una expresión (con ng-click) para cambiar el scope en su variable "dato".
El binding one-way lo ves muy fácilmente. Simplemente escribe algo en el campo de texto y observa como se actualiza el lugar de la página donde estás volcándo el valor con {{dato}}.
Para poder ver bien el doble binding he tenido que crear el botón, que hace cambios en el scope. Aclaro de nuevo que el doble binding de todos modos lo tienes en el INPUT text. Dirección 1) lo ves cuando escribes datos en el campo de texto, que viajan al modelo automáticamente (y sabemos que es cierto porque vemos cómo {{dato}} actualiza su valor. Dirección 2) lo ves cuando haces click en el botón. Entonces se actualiza ese dato del modelo y automáticamente viaja ese nuevo valor del scope hacia el campo de texto.

Por qué el binding es tan útil

Piensa en una aplicación que realizases con Javascript común (sin usar librería alguna), o incluso con jQuery que no tiene un binding automático. Piensa todo el código que tendrías que hacer para implementar ese pequeño ejemplo. Suscribirte eventos, definir las funciones manejadoras para que cuando cambie el estado del campo de texto, volcarlo sobre la página. Crear el manejador del botón para que cuando lo pulses se envíe el nuevo texto "hola" tanto al campo de texto como a la página, etc.
No estamos diciendo que sea difícil hacer eso "a mano", seguro que la mayoría es capaz de hacerlo en jQuery, pero fíjate que para cada una de esas pequeñas tareas tienes que agregar varias líneas de código, definir eventos, manejadores, especificar el código para que los datos viajen de un lugar a otro. Quizás no es tan complicado, pero sí es bastante laborioso y en aplicaciones complejas comienza a resultar un infierno tener que estar pendiente de tantas cosas.
Otra ventaja, aparte del propio tiempo que ahorras, es una limpieza de código muy destacable, ya que no tienes que estar implementando muchos eventos ni tienes necesidad de enviar datos de un sitio a otro. Tal como te viene un JSON de una llamada a un servicio web lo enganchas al scope y automáticamente lo tienes disponible en la vista, lo que es una maravilla. Esto se ve de manera notable en comparación con otros frameworks como BackboneJS.
Nota: Osea que el doble binding de Angular nos ahorra mucho trabajo, pero ojo, quizás no sea necesario para cualquier tipo de aplicación. Si tus necesidades no son muy grandes igual no consigues adelantar tanto. Incluso en aplicaciones con inmensa cantidad de datos puede que el doble binding te pueda ralentizar un poco la aplicación porque toda esa gestión del binding se haga pesada, igual de manera innecesaria. En esos casos quizás otra librería funcione mejor que AngularJS. Sin embargo, la inmensa mayoría de las aplicaciones se beneficiarán de ese doble binding.

Dónde encontrarás el binding

El binding que dispones en AngularJS se implementa automáticamente en muchas otras directivas que existen en el framework.
Es muy útil cuando trabajamos con colecciones y directivas como ngOptions o ngRepeat, que nos sirven para realizar recorridos a esas colecciones para crear los campos OPTION de un SELECT o simplemente para repetir cualquier pedazo del DOM. En estos casos, cuando la colección cambia, nuestra página se actualiza automáticamente.
También puedes hacer binding a atributos de diversas etiquetas de la página, con las directivas ngHref o ngSrc, ngStyle, ngClass. También funciona en formularios con una especie de framework de validación "Validations" o con el propio ngSubmit.

See the Pen DataBinding Example by Gerardo (@gelopfalcon) on CodePen.

Read More »

lunes, 28 de diciembre de 2015

Android: Botones



Gracias por leer mi blog. En este post estaré explicándoles sobre los diferentes botones en Android. Si descargan el código de github y lo ejecutan en Android Studio, verán una pantalla como esta:



El SDK de Android nos proporciona tres tipos de botones: los clásicos de texto (Button), los que pueden contener una imagen (ImageButton), y los de tipo on/off (ToggleButton y Switch).

No voy a comentar detalladamente sobre ellos dado que son controles de sobra conocidos por todos, ni vamos a enumerar todas sus propiedades porque existen decenas. A modo de referencia, a medida que voy comentando iré poniendo enlaces a su página de la documentación oficial de Android para poder consultar todas sus propiedades en caso de necesidad.

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.







Este botón quedaría como se muestra en la siguiente imagen:


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.




El botón se mostraría de alguna de las dos formas siguientes, dependiendo de su estado:
toggle_button
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:




Y su aspecto sería el siguiente:




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. Normalmente asignaremos esta propiedad con el descriptor de algún recurso que hayamos incluido en las carpetas /res/drawable. Así, por ejemplo, en nuestro caso vamos a incluir una imagen llamada “ic_estrella.png” por lo que haremos referencia al recurso “@drawable/ic_estrellaAdicionalmente, 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.

En una aplicación el botón anterior se mostraría de la siguiente forma:

Cabe decir además, que aunque existe este tipo específico de botón para imágenes, también es posible añadir una imagen a un botón normal de tipo Button, a modo de elemento suplementario al texto (compound drawable). 

Por ejemplo, si quisiéramos añadir un icono a la izquierda del texto de un botón utilizaríamos la propiedad android:drawableLeft indicando como valor el descriptor (ID) de la imagen que queremos mostrar, y si fuera necesario podríamos indicar también el espacio entre la imagen y el texto mediante la propiedad android:drawablePadding:


El botón mostrado en este caso sería similar a éste:

Eventos de un botón
Como podéis imaginar, aunque estos controles pueden lanzar muchos otros eventos, el más común de todos ellos y el que querremos capturar en la mayoría de las ocasiones es el eventoonClick, que se lanza cada vez que el usuario pulsa el botón. Para definir la lógica de este evento tendremos que implementarla definiendo un nuevo objeto View.OnClickListener() y asociándolo al botón mediante el método setOnClickListener(). La forma más habitual de hacer esto es la siguiente:

btnBotonSimple = (Button)findViewById(R.id.BtnBotonSimple);
 
btnBotonSimple.setOnClickListener(new View.OnClickListener() {
    public void onClick(View arg0)
    {
        lblMensaje.setText("Botón Simple pulsado!");
    }
});
En el caso de un botón de tipo ToggleButton o Switch suele ser de utilidad conocer en qué estado ha quedado el botón tras ser pulsado, para lo que podemos utilizar su métodoisChecked(). En el siguiente ejemplo se comprueba el estado del botón tras ser pulsado y se realizan acciones distintas según el resultado.
btnToggle = (ToggleButton)findViewById(R.id.BtnToggle);
 
btnToggle.setOnClickListener(new View.OnClickListener() {
    public void onClick(View arg0)
    {
        if(btnToggle.isChecked())
            lblMensaje.setText("Botón Toggle: ON");
        else
            lblMensaje.setText("Botón Toggle: OFF");
    }

});

Personalizar el aspecto un botón (y otros controles)
En las imágenes mostradas durante este apartado hemos visto el aspecto que presentan por defecto los diferentes tipos de botones disponibles. Pero, ¿y si quisiéramos personalizar su aspecto más allá de cambiar un poco el tipo o el color de la letra o el fondo?
Para cambiar la forma de un botón podríamos simplemente asignar una imagen a la propiedad android:background, pero esta solución no nos serviría de mucho porque siempre se mostraría la misma imagen incluso con el botón pulsado, dando poca sensación de elemento “clickable“.
La solución perfecta pasaría por tanto por definir diferentes imágenes de fondo dependiendo del estado del botón. Pues bien, Android nos da total libertad para hacer esto mediante el uso de selectores. Un selector se define mediante un fichero XML localizado en la carpeta /res/drawable, y en él se pueden establecer los diferentes valores de una propiedad determinada de un control dependiendo de su estado.
Por ejemplo, si quisiéramos dar un aspecto diferente a nuestro botón ToggleButton, para que sea de color azul y con esquinas redondeadas, podríamos diseñar las imágenes necesarias para los estados “pulsado”  y “no pulsado”  y crear un selector como el siguiente:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false" android:drawable="@drawable/toggle_off" />
    <item android:state_checked="true" android:drawable="@drawable/toggle_on" />
</selector>

En el código anterior vemos cómo se asigna a cada posible estado del botón una imagen (un elemento drawable) determinada. Así, por ejemplo, para el estado “pulsado” (state_checked=”true”) se asigna la imagen toggle_on.
Este selector lo guardamos por ejemplo en un fichero llamado toggle_style.xml y lo colocamos como un recurso más en nuestra carpeta de recursos /res/drawable. Hecho esto, tan sólo bastaría hacer referencia a este nuevo recurso que hemos creado en la propiedadandroid:background del botón:
<ToggleButton android:id="@+id/BtnPersonalizado"
        android:textOn="@string/on"
        android:textOff="@string/off"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/toggle_style" />

En la siguiente imagen vemos el aspecto por defecto de nuestro ToggleButton personalizado con los cambios indicados:

Botones sin borde
Otra forma de personalizar los controles en Android es utilizando estilos. Los estilos merecen un capítulo a parte, pero comentaremos aquí algunos muy utilizados en las últimas versiones de Android, concretamente en el tema que nos ocupa de los botones.
En determinadas ocasiones, como por ejemplo cuando se utilizan botones dentro de otros elementos como listas o tablas, es interesante contar con todas la funcionalidad de un botón pero prescindiendo sus bordes de forma que adquiera un aspecto plano y se integre mejor con el diseño de la interfaz. Para ello, podemos utilizar el estilo borderlessButtonStyle como estilo del botón (propiedad style), de forma que éste se mostrará sin bordes pero conservará otros detalles como el cambio de apariencia al ser pulsado. Veamos cómo se definiría por ejemplo un ImageButton sin borde:
<ImageButton android:id="@+id/BtnSinBorde"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/icono_ok"
        android:src="@drawable/ic_estrella"
        style="?android:borderlessButtonStyle"/>

En la siguiente imagen vemos cómo quedaría este botón integrado dentro de un LinearLayout y alineado a la derecha:

El separador vertical que se muestra entre el texto y el botón se consigue utilizando las propiedades showDividersdivider, y dividerPadding del layout contenedor (para mayor claridad puede consultarse el código completo):
<LinearLayout
        android:id="@+id/BarraBtnSinBorde"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:showDividers="middle"
        android:divider="?android:dividerVertical"
        android:dividerPadding="6dp" >

Otro lugar muy habitual donde encontrar botones sin borde es en las llamadas barras de botones (button bar) que muestran muchas aplicaciones. Para definir una barra de botones, utilizaremos normalmente como contenedor un LinearLayout horizontal e incluiremos dentro de éste los botones (Button) necesarios, asignando a cada el elemento su estilo correspondiente, en este caso buttonBarStyle para el contenedor, y buttonBarButtonStyle para los botones. En nuestro ejemplo crearemos una barra con dos botones, Aceptar y Cancelar, que quedaría así:
<LinearLayout
    android:id="@+id/BarraBotones"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    style="?android:attr/buttonBarStyle">
 
    <Button android:id="@+id/BtnAceptar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/Aceptar"
        style="?android:attr/buttonBarButtonStyle" />
 
    <Button android:id="@+id/BtnCancelar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/Cancelar"
        style="?android:attr/buttonBarButtonStyle" />
 
</LinearLayout>

Visualmente el resultado sería el siguiente:

Botones flotantes (Floating Action Button / FAB)
Como contenido extra de este capítulo voy a hacer mención a un nuevo “tipo de botón” aparecido a raiz de la nueva filosofía de diseño Android llamada Material Design. Me refiero a los botones de acción flotantes que están incorporando muchas aplicaciones, sobre todo tras su actualización a Android 5 Lollipop.

Con la reciente publicación por parte de Google de la librería Design Support Library, añadir este tipo de botones a nuestras aplicaciones es algo de lo más sencillo, y además aseguramos su compatibilidad no sólo con Android 5.x sino también con versiones anteriores. En esta librería se incluye un nuevo componente llamado FloatingActionButton con la funcionalidad y aspecto deseados.
Lo primero que tendremos que hacer para utilizarlo será añadir la librería indicada a nuestro proyecto.
Una vez añadida la librería al proyecto como se describe en la nota anterior, podremos añadir un botón flotante a nuestra interfaz añadiendo un nuevo elemento a nuestro layout principal activity_main.xml de la siguiente forma:
<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_add"
    app:fabSize="normal"
    app:borderWidth="0dp" />

La propiedad más relevante, al igual que en el caso de un ImageButton, es android:src, con la que podemos asignar al control la imagen/icono a mostrar. En mi caso de ejemplo he utilizado un nuevo icono (ic_add) añadido al proyecto de la misma forma que explicamos al principio del artículo.
Vemos también la propiedad app:fabSize. Esta propiedad puede recibir los valores “normal” y “mini“, que determinan el tamaño del control dentro de los dos tamaños estandar definidos en las especificaciones de Material Design.
La última propiedad asignada, app:borderWidth=”0dp”, es necesaria temporalmente (en el momento de actualizar este artículo la versión actual de la librería es la 22.2) para evitar que el botón flotante aparezca sin sombra o con aspecto no estandar en algunas versiones de Android (por ejemplo APIs 16 o 22). Previsiblemente, este error lo corregirán en la siguiente versión de la librería, por lo que puede que en un futuro muy próximo ya no sea necesario asignar esta propiedad.
¿Y como seleccionamos el color del botón? Pues bien, si no indicamos nada, el botón flotante tomará por defecto el accent color si lo hemos definido en el tema de la aplicación  o el color de selección actual. Si queremos utilizar otro color debemos hacerlo desde el código java de la aplicación, por ejemplo en el onCreate() de la actividad principal, llamando al método setBackgroundTintList() del control FloatingActionButton.
fabButton = (FloatingActionButton)findViewById(R.id.fab);
 
fabButton.setBackgroundTintList(
    getResources().getColorStateList(R.color.fab_color));

Como parámetro debemos pasarle un objeto de tipo ColorStateList, que no es más que un selector de color (similar al selector que creamos antes para el ToggleButon personalizado) que crearemos en la carpeta /res/color por ejemplo con el nombre fab_color.xml y que recuperaremos en nuestro código mediante el método getResources().getColorStateList().
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="#B90000" />
    <item android:color="#FF0000"/>
</selector>

Como podemos ver, en el selector hemos definido el color normal del botón y su color cuando está pulsado.

Puedes bajar el código de https://github.com/gelopfalcon/Android/tree/master/curso-android-src-as-master/android-botones

Saludos.
Read More »