En esta nueva entrada vamos a aprender como crear interfaces de usuario, o UI, que se ajusten a diferentes tamaños de pantalla. Además, veremos también como utilizar los datos que podemos obtener de diferentes elementos de la UI.
Elementos típicos de una UI
Para crear UI hay ciertos elementos con los que podemos llegar a tener una interfaz completa y funcional, como botones o cuadros de introducción de texto. Para diseñar la interfaz de usuario, tenemos que escribir el código correspondiente a cada elemento, modificando sus parámetros para adecuarlo a nuestras necesidades. El código de alguno de los elementos de mayor interés para generar interfaces es:
Botón:
1 2 3 |
var nombre = ui.addButton("texto", posX, posY, ancho, alto).onClick(function() { //código de la función }); |
checkbox: (Modo puede ser true o false y determina si se inicia marcado o no)
1 2 |
var nombre = ui.addCheckbox("texto", posX, posY, ancho, alto, modo).onChange(function(val) { }); |
texto: Imprime un texto por pantalla:
1 |
var nombre = ui.addText("texto", posX, posY, ancho, alto); |
Slider: Crea una barra por donde podemos deslizar un marcador y que nos dará el valor entre el mínimo y el máximo que marquemos.
1 2 3 |
var nombre = ui.addSlider(posX, posY, ancho, alto, min, max).onChange(function(val) { //código de la función }); |
Input: Crea un cuadro de texto donde se puede escribir.
1 2 3 |
var nombre = ui.addInput("Texto",posX, posY, ancho, alto).onChange(function(val) { //código de la función }); |
En el caso del checkbox, podría utilizarse toggle, que crea un botón que puede cambiar de estado, o switch, que generá un botón “deslizable”, pero sin la posibilidad de añadir texto junto al botón, por lo que habría que generar un elemento de texto para indicar cuál es la función del switch. La funcionalidad básica de los tres elementos es la misma, pero dependiendo de las características de la aplicación o nuestros gustos utilizaremos uno u otro.
Para ver como se escriben el resto de las funciones, se puede utilizar la referencia rápida y buscar dentro de UI (lo que puede estar sin actualizar y llevar a errores) o dentro de los ejemplos.
Una buena práctica para crear interfaces es mantener fijo el alto de los elementos, pudiendo así saber donde colocar el siguiente elemento. Por ejemplo, si un elemento tiene un alto h = 150 podemos colocar el siguiente elemento a una distancia ligeramente mayor cambiando la posición, es decir, el valor de la altura más el margen (150 + m). En elementos sucesivos, incluiríamos incrementos hasta colocarlos en la posición deseada. Por ejemplo, dos veces la altura más el margen 2*150 + m.
Creando UI que se adaptan a diferentes tamaños de pantalla
Como podemos acceder a los datos del terminal que se esté utilizando para ejecutar el código, podemos utilizarlo para generar interfaces que se adapten a diferentes tipos de pantalla. Para generar este código, nos valemos de las funciones ui.screenWidth y ui.screenHeight, que devuelven el ancho y el alto de la pantalla, respectivamente.
El código que puede utilizarse para generar este tipo de programas es:
1 2 3 |
var margin = 10; var w = ui.screenWidth - 2 * margin; var h = 150; |
Donde en primer lugar establecemos un margen que utilizaremos para separar los elementos de la UI del borde vertical, y establecer un margen entre los distintos elementos, para evitar que se solapen.
Dependiendo del número de elementos que se incluyan en la interfaz y del tamaño de estos, es posible que el texto que muestran se visualice incorrectamente, por lo que es preferible fijar el alto (h en el código anterior) de los elementos y evitar utilizar altos adaptativos (con el código anterior hacemos que el ancho de los elementos sea adaptativo a diferentes tamaños de pantalla).
Si hacemos que la posición en el “eje X” de los elementos sea margin, como hemos fijado w = ui.screenWidth – 2 * margin los elementos terminarán en el “final” de la pantalla con el mismo margen en ambos lados, dando la impresión a simple vista de una interfaz con un diseño más cuidado.
Variables en Protocoder
Las variables en Protocoder se diferencian del lenguaje Arduino en que no tenemos que determinar el tipo de dato que almacenará la variable. Por ejemplo, en Arduino cuando queremos guardar un número entero utilizaríamos:
1 |
int margin = 10; |
Y en Protocoder:
1 |
var margin = 10; |
Por lo que evitamos problemas de incompatibilidades entre los datos que estamos introduciendo y los que espera recibir la variable, evitando así errores.
Funciones en Protocoder
Para generar una función, en Protocoder utilizamos un código similar a este:
1 2 3 |
function nombre_funcion(variable1,variable2){ //código de la función. } |
Por ejemplo una función que muestre un toast, un mensaje flotante en la pantalla propio de Android, sería así:
1 2 3 |
function showToast (string){ showToast(string); } |
Donde showToast es el nombre de la función y string es el parámetro que hay que pasar a la función. Por ejemplo, para utilizar esta función podríamos utilizar esta línea de código:
1 |
showToast("El curso de programación para makers con Arduino y Protocoder mola!"); |
Creando la UI y programando una aplicación
En este caso, vamos a generar una aplicación que simule una pantalla de acceso de usuario a un servicio, en el que se nos pide nombre de usuario y contraseña para poder acceder una vez que se haya pulsado sobre un botón. Además, incluiremos un checkbox que cambiará la transparencia de una imagen para aprender sobre su uso y un botón con imagen que llevará a un popup con información.
En primer lugar, cambiamos el color del fondo e incluimos el código del apartado anterior, que nos facilitará crear la aplicación:
1 2 3 4 5 |
ui.backgroundColor(55, 155, 155); var margin = 10; var w = ui.screenWidth - 2 * margin; var h = 150; |
Antes de empezar a incluir elementos, vale la pena tomarse un minuto y reflexionar, o incluso dibujar un boceto, sobre qué los elementos que vamos a incluir y donde vamos a colocarlos. En este caso, incluiremos dos entradas de texto y un botón para manejar el usuario y la contraseña, un checkbox y una imagen y el botón que mostrará el popup.
Gestor de contraseña
En primer lugar creamos las variables donde se almacenarán los datos que introducirá el usuario por pantalla y el nombre de usuario y contraseña correcto:
1 2 3 4 |
var userName = ""; var password = ""; var rightUser = "bq"; var rightPass = "bq"; |
A continuación generamos los códigos de las dos entradas de texto:
1 2 3 4 5 6 7 |
var userText = ui.addInput("Username",margin,margin,w,h).onChange(function(val){ userName = val; }); var pass = ui.addInput("Password", margin, h + margin, w, h).onChange(function(val){ password = val; }); |
En el elemento de nombre pass, hemos utilizado la posición Y del elemento como h + margin, debido a que el elemento anterior tiene un tamaño igual a h y queremos que quede separado de este. Para los siguientes elementos utilizaremos 2*h + margin, 3*h +margin, etc.
En ambos elementos, utilizamos la variable val para almacenar en la variable correspondiente, userName o password, que se introduce por teclado.
Para finalizar el gestor de contraseña, tenemos que incluir finalmente un botón que compruebe si el nombre de usuario y la contraseña es correcta:
1 2 3 4 5 6 7 8 9 10 11 12 |
ui.addButton("Log in",margin,2* h +margin,w,h).onClick(function() { username = userText; if (userName == rightUser && password == rightPass){ showToast("Right username & password"); }else if(userName == rightUser && password != rightPass){ showToast("Wrong password"); }else if (userName != rightUser && password == rightPass){ ui.toast("Wrong username"); }else{ showToast("Wrong username & password"); } }); |
Checkbox y cambio de transparencia en elementos
El checkbox es un elemento que permite marcar o desmarcar, normalmente puede utilizarse para cambiar una condición, por ejemplo encender o apagar una luz, marcar o desmarcar una opción. En este programa de Protocoder, utilizaremos el checkbox para cambiar la transparencia, aplha, de una imagen pero puede realizarse con prácticamente cualquier elemento, view.
En primer lugar, creamos el checkbox y le asignamos el nombre alpha:
1 2 3 4 5 6 7 |
var aplha = ui.addCheckbox("Change Alpha Logo",margin,3.5* h +margin,w,h, false).onChange(function(val) { if (val){ img.setAlpha(0); }else{ img.setAlpha(255); } }); |
El Checkbox suele ir acompañado de la opción que vamos a modificar, representada como un texto entre comillas al principio de los parámetros. El valor val que devuelve la función será true o false dependiendo de si la casilla está marcada o no, respectivamente.
Para modificar la transparencia de un elemento, o view, utilizamos la sintaxis:
1 |
nombreView.setAlpha(número) |
Para cambiar la transparencia de algún elemento, tenemos que modificar nombreView por el nombre de variable que hayamos asignado al elemento visual y cambiamos número por un número entre 0 y 255, correspondiendo a transparente y opaco, respectivamente.
Botón con imagen y Popup
Por último, vamos a incluir un botón con una imagen, incluida en las descargas, que puede utilizarse para mostrar información mediante un cuadro de dialogo. En primer lugar, tenemos que subir la imagen al cuadro de subidas de la parte inferior derecha, pasarla a la carpeta del proyecto dentro de la carpeta Protocoder en Android o conectarnos a través de FTP a nuestro terminal (puede activarse el ftp en los ajustes de Protocoder).
Una vez que la imagen esté subida, tenemos que escribir este código para incluir el botón con imagen:
1 2 3 |
var imgBtn = ui.addImageButton(w/2 + w/4,9* h +margin,2*imgSize,2*imgSize,"about_icon.png").onClick(function() { }); |
Donde los parámetros son, respectivamente: posición X, posición Y, tamaño X, tamaño Y, nombre de la imagen. La programación es igual que para cualquier botón, al pulsar sobre éste, se ejecutará el código que se escriba dentro de su definición.
Para usar el Popup, una ventana emergente que se coloca encima del resto de la interfaz, utilizamos el siguiente código:
1 2 3 |
ui.popupInfo("Título", "Texto", "Respuesta_si", "Respuesta_no", function(e) { //Código de la función }); |
En nuestro caso, utilizamos este código:
1 2 3 4 5 6 7 8 |
ui.popupInfo("About", "Protocoder rocks?", "Yes", "No", function(e) { console.log("you pressed " + e); if (e){ showToast("You are right!"); }else{ showToast("Wrooong!"); } }); |
Como podemos saber que opción se ha pulsado puede trabajarse con la respuesta, que será true o false, si se ha pulsado en la Respuesta_si o Respuesta_no.