Este tutorial pertenece a la siguiente serie:
Cuando hablamos sobre el "Diseño Web Responsive", la mayoría de la gente cita el cásico artículo escrito por Ethan Marcotte (lo encontrarás en la sección de Referencias). Te animamos a que lo leas si no tienes ni idea del concepto "Diseño Web Responsive". Él debe ser el primero (hasta donde yo sé) que habla sobre este tema y por primera vez se apunta al término "Diseño Web Responsive". En su artículo, Marcotte, el término viene inspirado por el de "Arquitectura Responsive", el cual se refiere a la cantidad de personas que la visitan. Por lo tanto, a medida que más y más dispositivos pueden visitar una página web, nuestra página web (o aplicación web), esta requiere un diseño responsive.
El "Diseño Web Responsive" no es una nueva técnica. Simplemente es un enfoque que permite a la página web ser vistar perfectamente por distintos dispositivos. Según el artículo de Marcotte, hay 3 elementos que podemos usar para completar este requisito de diseño.
Más información sobre los 3 elementos en la sección de Referencias
ZK soporta el diseño web responsive y mejora sus propios componentes para tener en cuenta los dispositivos tablet. ZK también añade los atributos necesarios en la vista para sus componentes para ayudar a los desarrolladores a optimizar la experiencia de usuario. Por ejemplo si ZK detecta que el dispositivo cliente (mediante la cabecera user-agent) es una tablet, automáticamente se establece el tamaño del atributo viewport al tamaño del dispositivo y no se admite reescalado de pantalla mediante meta tags. Como por ejemplo escalar la pantalla, puesto que normalmente esto rompe el layout.
Información más detallada sobre esto en la sección de Referencias
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
A continuación, en las siguientes secciones, hablaremos sobre las características que ayudan a los desarrolladores a lograr un "Diseño Web Responsive".
En el artículo de Marcotte, tanto la malla/grid fluidos como las imágenes flexibles son 2 elementos básicos del "Diseño Web Responsive". Los componentes de layout en ZK ya son flexibles y como si de una malla/grid fluido se tratase, cambian según el tamaño del dispositivo. Para otros componentes diferentes de la malla/grid, podemos usar las propiedades hflex y vflex para hacerlos fexibles según el tamaño de la pantalla del dispositivo. Las propiedades "hflex" y "vflex" indican si el componente se puede estirar o no vertical y horizontalmente. Cuando hablamos de "Estirar", nos referimos a cómo debe distribuir el espacio vacío entre sus componentes hijos. Vamos a verlo en un ejemplo a continuación.
Información más detallada sobre "hflex" y "vflex" en la sección de Referencias
También podemos usar CSS3 Media Querys en un fichero zul para que se apliquen diferentes estilos, de acuerdo con las diferentes características del dispositivo. Para customizar el estilo de un componente correctamente te sugeremos que leas ZK Style Guide.
<zk>
<style>
@media screen and (max-width: 1024px) {
.style-for-larger-screen {
...
}
}
@media screen and (max-width: 750px) {
.style-for-smaller-screen {
...
}
}
</style>
</zk>
Si queremos controlar los componentes de acuerdo a las características del dispositivo o detectar la horientación de los mismo, debemos escuchar el evento ClientInfoEvent. Este evento se envía únicamente cuando se registra un cambio que afecta al elemento root. Podemos obtener diferente información del cliente a través de este objeto. Por ejemplo getOrientation() retorna "landscape" (horizontal) o "portrait" (vertical) para indicar la orientación del dispositivo. getDesktopWidth() devuelve el alto del navegador, pero del área que disponible a la web (inner displaying area), no su alto total, y normalmente es inferior que el valor devuelto por getScreenWidth().
<window onClientInfo="@command('updateDeviceStatus', orientation=event.orientation)">
...
</window>
Podemos detectar si el dispositivo cliente es un dispositivo móvil o no mediante los métodos Executions.
// Detect if client is mobile device (such as Android or iOS devices)
public boolean isMobile(){
return Executions.getCurrent().getBrowser("mobile") !=null;
}
ZK pone a tu disposición atributos en los componentes para establecer si son flexibles horizontal o verticalmente, en vez de que sean componentes estáticos en cuanto a ancho y alto en píxeles.
Por ejemplo:
<hlayout vflex="1">
<window title="Column 25%" vflex="1" hflex="1" sclass="column1" border="normal">
toffee candy canes cheesecake gummies apple pie. Pie cupcake cheesecake sugar plum tart donut
bear claw caramels. Sesame snaps candy candy faworki sesame snaps chocolate wypas cheesecake.
Cupcake cupcake chupa chups dragée bonbon cotton candy pudding.
</window>
<window title="Column 25%" vflex="1" hflex="1" sclass="column2" border="normal">
toffee candy canes cheesecake gummies apple pie. Pie cupcake cheesecake sugar plum tart donut
bear claw caramels. Sesame snaps candy candy faworki sesame snaps chocolate wypas cheesecake.
Cupcake cupcake chupa chups dragée bonbon cotton candy pudding.
</window>
<window title="Column 50%" vflex="1" hflex="2" sclass="column3" border="normal">
toffee candy canes cheesecake gummies apple pie. Pie cupcake cheesecake sugar plum tart donut
bear claw caramels. Sesame snaps candy candy faworki sesame snaps chocolate wypas cheesecake.
Cupcake cupcake chupa chups dragée bonbon cotton candy pudding.
</window>
</hlayout>
En el ejemplo anterior, usamos los atributos vflex y hflex para que el alto y el ancho sean flexibles proporcionalmente al tamaño de la pantalla en diferentes dispositivos.
En internet, hay muchos diseños responsive populares. Vamos a enseñarte uno de ellos, Mondrian pattern. Creo que lo nombran así porque este layout es similar a la pintura Composition de Piet Mondrian, la cual divide la imágen en múltiples rectángulos. Por lo tanto, este patrón de diseño divide la pantalla en 3 rectángulos. Cuando disponemos de menos tamaño, porque la pantalla es más pequeña, cambiamos la ubicación y ancho de los rectángulos para que se adapten.
Información más detallada sobre Piet Mondrian en la sección de Referencias
El patrón tiene 3 rectángulos. Cuando la pantalla se vuelve o és más pequeña, los rectángulos de la derecha fuyen hacia abajo del rectángulo de la izquierda. Podemo susar 2 componentes Hlayout para implementar este tipo de fluidez. El primer Hlayout es el componente padre que contiene 3 rectángulos; el segundo Hlayout está dentro del primero y contiene 2 rectángulos a la derecha. El Hlayout dentro de la estructura DOM usa un HTML <div> para contener cada componente dentro de él y cada HTML <div< contenido recibe una clase CSS, z-hlayout-inner. Los divs que están dentro del principal controlan el ancho y ajustes de los componentes que contiene. Por lo tanto, necesitamos ajustar el ancho de estos sobreescribiendo la clase CSS z-hlayout-inner mediante CSS3 Media Query.
Información más detallada sobre las clases css, y z-hlayout-inner en la sección de Referencias
Extraído de adaptive.zul (Ver el código fuente completo)
<zk>
<style>
.first-layout{
background-color:black
}
.second-layout{
height: 100%;
}
.first-layout>.z-hlayout-inner:first-child {
width: 66%;
height: 100%;
}
.first-layout>.z-hlayout-inner:last-child {
width: 33%;
height: 100%;
}
.second-layout>.z-hlayout-inner{
width: 100%;
height: 50%;
display:block;
}
@media screen and (max-width: 1024px) {
.first-layout>.z-hlayout-inner:first-child {
width: 100%;
height: 50%;
}
.first-layout>.z-hlayout-inner:last-child {
width: 100%;
height: 50%;
display:block;
}
.second-layout>.z-hlayout-inner{
width: 50%;
height: 100%;
display:inline-block;
}
}
@media screen and (max-width: 750px) {
.first-layout>.z-hlayout-inner:first-child {
width: 100%;
height: 33%;
}
.first-layout>.z-hlayout-inner:last-child {
width: 100%;
height: 66%;
}
.second-layout>.z-hlayout-inner{
width: 100%;
height: 50%;
display:block;
}
}
</style>
<hlayout vflex="1" hflex="1" sclass="first-layout">
<vbox width="100%" height="100%" pack="center" align="center">
<label sclass="title">ZK Car Center</label>
<image src="car1.png"/>
</vbox>
<hlayout sclass="second-layout">
<div sclass="description-area" height="100%">
<label sclass="description">
Nissan Primera
</label>
</div>
<div sclass="description-area" height="100%">
<label sclass="description">
The Nissan Primera was produced between 2002 and 2008. It was available as a 4-door sedan
or a 5-door hatchback or estate.
The entry-level 1.6-liter petrol feels underpowered for a large car. The 1.8-liter petrol is keen,
the refined 2.0-liter unit is the star performer.
</label>
</div>
</hlayout>
</hlayout>
</zk>
Es muy común, en el "Diseño Web Responsive" que el menú del lado izquierdo de una página se vuelva una barra de opciones flotante cuando se accede desde un dispositivo web con la pantalla muy pequeña. La aplicación de ejemplo que presentamos aquí tiene 2 tipos de layout, en uno vemos el menú de modo fijo para navegadores tradicionales de escritorio, o tabletas en oritentación "landscape" u horizontal, el menú siempre está visible.
En el área central, usamos un componente Cardlayout y este, soporta diferentes formas de cambiar imágenes según sea un PC o un dispositivo móvil. En un PC, los usuarios pueden hacer clic en los iconos pequeños de navegación para cambiar su imagen. En un navegador de un dispositivo móvil, los usuarios pueden cambiarlo arrastrando sus dedos.
Información más detallada sobre Cardlayout en la sección de Referencias
El otro layout del ejemplo es en el que el menú flota cuando el dispositivo móvil está en orientación "portrait" o vertical. No hay menú en la parte izquierda, pero sí aparece un botón en la cabecera, que al pulsarlo nos presentará el menú flotante.
La aplicación de ejemplo cambia su layout según las siguientes reglas:
Este ejemplo usa el componente Borderlayout y su componente hijo West que contiene el menú en su interior a su vez dentro de un componente Window. Conseguimos pasar la barra de menú de fija a flotante cambiando el componente Window entre "embedded" y "overlapped" (atributos). La principal idea de este ejemplo es cambiar la visibilidad de los componentes según detectemos la orientación o ancho del navegador.
Extraído de sidebar.zul (Ver el código fuente completo)
<window apply="org.zkoss.bind.BindComposer" width="100%" height="100%"
onClientInfo="@command('updateClientInfo', width=event.desktopWidth, orientation=event.orientation)"
viewModel="@id('vm') @init('org.zkoss.document.SidebarVM')">
<borderlayout>
<north height="28px" sclass="header">
<hbox width="100%">
<button sclass="menu-button" visible="@bind(vm.menuAreaWidth eq '0px')"
image="menu.png"
onClick='@command("toggleMenu")' />
<!-- other icons-->
</hbox>
</north>
<west width="@load(vm.menuAreaWidth)">
<window mode="@load(vm.windowMode)" visible="@bind(vm.floatMenuVisible)" width="200px" top="35px" left="10px">
<!-- menu -->
</window>
</west>
<center>
<!-- content area, other components -->
</center>
</borderlayout>
</window>
Extraído de SidebarVM.java (Ver el código fuente completo)
public class SidebarVM {
private boolean floatingMenuVisible = true;
private boolean isMobile = false;
private String orientation;
private String windowMode = "embedded";
private String menuAreaWidth= "200px";
@AfterCompose
public void init(){
ServletRequest request = ServletFns.getCurrentRequest();
// Detect if client is mobile device (such as Android or iOS devices)
isMobile = Servlets.getBrowser(request, "mobile") != null;
if (isMobile){
toFloatingMenu();
}
}
@Command
@NotifyChange("floatingMenuVisible")
public void toggleMenu(){
floatingMenuVisible = !floatingMenuVisible;
}
@Command
@NotifyChange({"windowMode","menuAreaWidth","floatingMenuVisible"})
public void updateClientInfo(@BindingParam("orientation") String orientation, @BindingParam("width")int width ){
if (isMobile){
if (!orientation.equals(this.orientation)){
this.orientation = orientation;
if (orientation.equals("protrait") || width < 800){
toFloatingMenu();
}else{
toFixedMenu();
}
}
}
}
private void toFloatingMenu(){
floatingMenuVisible = false;
windowMode = "overlapped";
menuAreaWidth = "0px";
}
private void toFixedMenu(){
floatingMenuVisible = true;
windowMode = "embedded";
menuAreaWidth = "200px";
}
}
ZK provee layout flexibles, componentes y media query para que tus aplicaciones sean responsive design. Tanto para experimentados como para nuevos usuarios de ZK, ellos pueden fácilmente hacer que su aplicación se adapte a múltiples dispositivos y mantener los mismos componentes, con muy poco esfuerzo.
Este documento es un extracto de la documentación oficial del Framework ZK, traducido y ampliado por Francisco Ferri. Colaborador de Potix (creadores del Framework ZK). Si quieres contactar con él puedes hacerlo en franferri@gmail.com, en twitter @franciscoferri o en LinkedIn