Author Archives: admin

Presentación Cooperativa Integral

OBJETIVOS: ¿QUÉ QUEREMOS?

  • Crear una red comunitaria que, bajo los principios de la ayuda mutua y la solidaridad, resuelva los problemas concretos de nuestra vida cotidiana.
  • Facilitar el intercambio de conocimientos, servicios y productos entre personas que viven en un mismo entorno local.
  • Potenciar economías locales basadas en la cercanía y el conocimiento mutuo.
  • Impulsar la participación en la construcción de un modelo de economía solidaria y social.

¿CÓMO NOS ORGANIZAMOS?

  • Para la gestión del mecanismo de Moneda Complementaria se propone convertir la Comisión de BdT en un “Concejo de Mora” integrado por los miembros representantes de las asambleas locales que impulsen en su localidad la Moneda, y por cualquier otra persona que voluntariamente quiera participar.
  • Periódicamente se realizarán Ferias itinerantes en que se presentaran los servicios, se expondrán y venderán los productos de los usuarios y se premiaran las historia de trueque y la cadena de cambio más diversificadas, más rápidas y más creadoras de riqueza. Las historias de trueque recogidas en los billetes nos permitirán visualizar la historia de los flujos y el proceso de reconstrucción de la inteligencia colectiva que significa el uso de la Moneda Complementaria.

¿CÓMO NOS ORGANIZAMOS?

Funciones de la administración:

  • Gestión de las solicitudes pendientes (comprobar datos, contactar, aprobar.)
  • Revisar las transacciones e informar delos posibles errores.
  • Dinamizar el CES (boletines, información de nuevos mercadillos y presentaciones, bienvenida a las nuevas altas…)•Hacer una copia de seguridad mensual de la basede datos.
  • Cobrar la oxidación, cada dos meses.
  • Participar en las jornadas de presentación del Sistema de Intercambio en los municipios, si procede.
  • Acompañar durante dos meses a las nuevas personas que asumen la administración
  • Comunicación con otros coordinadores/as localesa través de: bdt.sierra@gmail.com•Comunicación con la administración general del CES.

TÉRMINOS Y CONDICIONES (en constante revisión para mejorar)

  • Una MORA tendrá una equivalencia a 1 €, pero no será canjeable en euros.
  • Los servicios tendrán todos el valor de 10 MORAS/Hora, salvo para personas desempleadas y proyectos de autoempleo.
  • Se recomienda que los servicios sean 100% en MORAS (para servicios hora) pero pueden complementarse con euros hasta un máximo del 50% del valor (para productos y para personas desempleadas o en dificultades laborales).
  • Iniciaremos el sistema de intercambio con un límite de crédito de 100 Moras por cada persona inscrita.
  • Los tiempos de desplazamiento entre pueblos correrán a cargo del demandante del servicio en el caso de 100%MORAS, pero podrán ir incluidos en el precio en el caso de pago parcial en euros.
  • Oxidación moneda: la moneda que no se use perderá un 10% de su valor cada 3 meses y un 20% cada 6 meses

Banco de tiempos: crear una comunidad

Crear una nueva comunidad de intercambio o registrate en una existente

¿No tienes una comunidad de intercambio en tu área?

Si no hay una CES de intercambio en tu área porque no creas una? Si sientes que hay suficiente gente en tu comunidad que puede estar interesada en comercio sin usar la moneda establecida en el pais, o gente que está metida en serios problemas creados por un sistema basado en el crédito, entonces registra una nueva comunidad de intercambio. Nos pondremos en contacto contigo después de que nos llegue tu registro y empezaremos el proceso de configurarlo.

Register a new or existing exchange with the CES

« Back

Your details…
Details of Exchange Group
Full title of exchange: (e.g. New Town Community Exchange)
Short name for exchange: (e.g. New Town) – this gets used in menus
Four letter code for exchange: (e.g. NTCE) – exchange ID; account number prefix
Location (City/Town/Place): (where this exchange is located)
County/Province/State etc: (where this exchange is located)
Country:
Currency name: (e.g. Green Dollar, Talent)
Currency symbol: (e.g. G$, T)
Web site of exchange: (if any)
Language: (default language for new members)
Other language: (if not listed above)
Motivation:
If this is a new exchange please tell us about your vision for it; if it is an existing exchange tell us something about its history and your vision for the future.
Administrator’s Details
First name: Tel (home):
Surname: Tel (work):
Address: Fax:
Address (cont.): Mobile:
City/Town/Place: Email:
County/Province/State etc:
Postcode/Zip:
Country:
Additional detail can be provided after your new exchange has been set up. You will be able to submit your logo and modify default text to customise your site.

Unete a un grupo existente de la red CES

Su ya eres miembro de un grupo de intercambio que tiene algún tipo de moneda social, como por ejemplo el grupo LETS o un banco de tiempos, porque no registrar tu grupo en la red CES y te conviertes en parte de la red CES que permite intercambios a nivel global. Enganchando tu grupo al CES puedes beneficiarte de un avanzado sistema y avanzadas herramientas de gestión.

Intercambio de crédito mútuo o banco de tiempos?

La red CES puede acoger grupos de intercambio mútuo de crédito, donde la unidad de valor estaá basada en la moneda nacional o cualquier otro standard ; y los bancos de tiempo, donde la unidad de valor está basada en el tiempo.

Ningun coste en moneda convencional

No hay coste en moneda convencional para formar parte de la red CES. Estamos haciendo todo lo posible para eliminar nuestra necesidad del dinero convencional y crear un sistema de intercambio que es soportado por su propia energia.

Herramientas de gestión

Para gestionar las transacciones en el intercambio, hay tres interfaces de gestion que te ofrece la red CES

  • un interfaz administrativo sofisticado Administrative Interface desde donde el administrador o equipo administrador gestiona el intercambio y guarda registro de lo que está sucediendo. Para ver las funciones que están contenidas en el interfaz de usuario, miralo aqui click here.
  • un interfaz de Coordinacion de miembros Membership Co-Ordinator’s Interface para menejar asuntos de registro de los miembros. Puedes verlo aqui click here.
  • Un interfaz de coordinador para miembros apuntados que realicen acciones departe de otros (por ejemplo para aquellos que no tienen ordenador ni internet). Para ver qué funciones están contenidas en este interface , mira  click here.

Si necesitas más información escribe a  

Nota importante:

Registrar una comunidad de intercambio significa que tu o tu organización se convierte en el Administrador del intercambio. Lo que CES proporciona es solo la herramienta que gestiona ese intercambio, pero no es el intercambio en sí mismo. Una comunidad de intercambio es un entidad real establecida con el proposito de facilitar el comercio en tu comunidad sin el uso de la moneda convencional. Para conocer más sobre lo que significa ser administrador , podemos leer lo siguiente read here.

Qué significa ser Administrador?

Cuando se envia una solicitud de registro de grupo de intercambio automáticamente te conviertes en el Administrator  del grupo. La web del CES es sólo una herramienta para la gestión del intercambio, pero no es el intercambio en si mismo.

Mucha gente se ha registrado como comunidad de intercambio esperando que los intercambios se crearán por si mismos cuando la gente se registre y empiece a hacer transacciones. En la práctica no sucede asi. Un intercambio es un entidad de la vida real. Tiene que comenzar desde abajo, y no en el ciberespacio. Debe ser promocionado en la comunidad y constantemente debe realizar actividades que motiven a la gente a hacer actividades juntos, tales como mercados de intercambio, reuniones y otros eventos. Tiene que haber uno o más gente apsionada con la idea cuando el intercambio empieza a funcionar.

Ser Administrador viene con ciertas responsabilidades y obligacines. El Administrator tiene acceso a un interfaz de administracion, que tiene un conjunto de herramientas de intercambio. Las obligaciones del Administrator incluyen lo siguiente:

  • Aprobar nuevas suscripciones al grupo
  • Dar soporte a los dudas de los usuarios
  • Mantener a los usuarios informados. Esto incluye, entre otras cosas:
    • Enviar un estado de cuentas mensual
    • Enviar una lista de las ofertas regularmente
    • Enviar una lista de las demandas regularmente
    • Enviar noticias sobre el grupo
  • Mantenimiento (bloqueo de cuentas , transferencia de usuario, borrar anuncios caducados, etc)
  • Monitorear estadisticas y datos de transacciones para ver que los intercambios se realizan bien y que ciertos usuarios no están abusando del sistema.
  • Meter transaciones, anuncios y otra información de parte de otros usuarios
  • Ser árbitro de las disputas

Apart from the above the Administrator needs to promote the exchange in the community to ensure its growth to a position of critical mass, when the exchange tends to take on a life of its own.

Often the Administration consists of a committee and the tasks of administration are shared. Every exchange is different.

Please consider the above before sending in your application for a new exchange. Administration is a rewarding position but for an exchange to be a success it does require some effort!


Dojo: custom builds

En este tuto explicaremos como hacer un sistema dojo reducido para que el rendimiento de nuestra app mejore (menos peso de librerias). Esta guia brevemente nos enseña los usos más comunes y parámetros. Para información detallada ver full build documentation.

Introducción

Un custom build de dojo mejora el rendimiento por medio de lo siguiente:

Se trata de diseñar los módulos de cada capa con un “profile” , que es algo similar a un script de Ant o un Makefile. Pero esto no es dificil si conoces tu app bien.

La entrada al build system es el árbol de codigo fuente del dojo, más cualquier fuente para asuntos personalizados que quieras incluir… más el profile. La salida es una distribución de Dojo que puedes poner en tu web server.

Prerequisitos

Necesitas lo siguiente instalado en tu ordenador para ejecutar el Dojo’s build system:

  • Java 1.4.2 or later (Java 1.5 recommended).
  • El código fuent de Dojo, que puedes obtener de http://download.dojotoolkit.org/. Los builds de código fuente tienen el sufijo “-src”. Si quieres descargarte la última versión del repositorio Subversion , puedes hacerlo en Using Subversion .

Parámetros de perfiles y de linea de comando

El build system es manejado por el script build.sh (o build.bat para Windows), que acepta varios parámetros en la línea de conados, uno de los cuales debe indicar qué build profile se debe utilizar para hacer el build. Los parámetros especificados en la línea de comando y el profile son combinados para hacer el build.

Nota: In Dojo versions 1.X CHECK FACT and later, if parameter values from the profile override parameters of the same name on the command line. Prior to version 1.X CHECK FACT, parameters on the command line override parameters of the same name from the profile.

Donde de ponen los profiles?

Cuando especificamos el nombre del profile por el parámetro profile , el directorio por defecto para los profiles es :

util/buildscripts/profiles.

Podemos poner los profiles fuera de la estructura de directorios de Dojo (lo cual no es mala idea de forma que podamos utilizarlo en subsecuentes versiones de Dojo), puedes utilizar el parámetro profileFile para que apunte a tu profile en cualquier sitio del disco.

Nomenclatura de los profiles

Tus profiles deben seguir siempre la siguiente nomenclatura  name.profile.js. El parámetro  profile automaticamente añade  profile.js a la string que sea especificada para determinar el nombre del fichero.

Ejemplo: Crear un Custom Profile

En el siguiente ejemplo, que está dentro del directorio  util/buildscripts/profiles , crearemos un fichero profile build llamado foo.profile.js que contendrá lo siguiente:

dependencies ={

  layers:  [
      {
      name: "mydojo.js",
      dependencies: [
          "dijit.Button",
          "dojox.wire.Wire",
          "dojox.wire.XmlWire",
          "explosive.space.Modulator"
      ]
      }
  ],

  prefixes: [
      [ "dijit", "../dijit" ],
      [ "dojox", "../dojox" ],
      [ "explosive", "../../explosive" ]
  ]

};

La sección dependencies dentro de layer lista todos los módulos que puedes invocar “directamente”. Cualquier módulo referenciado también será incluido, asi que no tienes que preocuparte de las dependencias. También, los módulos base de Dojo están implicitos, asi que no necesitas listar cosas como “dojo.query”. (Los módulos core , sin embargo , sí necesitan ser listados)

Los módulos encontrados en layer son reunidos para hace el fichero “layer”, en nuestro ejemplo: “mydojo.js”. Entonces ya solo tienes que cargar este js en tus páginas en la script tag para empezar a funcionar con dojo. Fácil!

 

 

The prefixes section list any modules that need inclusion. Note our “explosive” module, which is located away from the Dojo tree. You need to list these if you use them, even if you don’t want any modules from it in your layer file.

For the 1.0+: If you choose to optimize the JS files in a prefix directory (via the optimize= build parameter), you can choose to have a custom copyright text prepended to the optimized file. To do this, specify the path to a file tha contains the copyright info as the third array item in the prefixes array. For instance:

prefixes: [
    [ "explosive", "../../explosive", "../../explosive/copyright.txt"]
]

If no copyright is specified in this optimize case, then by default, the dojo copyright will be used.

Running The Build

After specifying a profile file as shown above that statically specifies the resources you want to include, and saving it as /buildscripts/profiles/foo.profile.js, you run the Rhino interpreter on it and specify the profile name as a parameter. For example, from the buildscripts directory:

$ cd util/buildscripts
$ build.sh profile=foo action=release

On Windows PC’s, substitute build.bat for build.sh. For both platforms, you may also specify additional build options. Run build.sh with no options to see a list of all supported options. Here is a sample of the supported options:

profile
The name of the profile to use for the build. It must be the first part of the profile file name in the profiles/ directory. For instance, to use base.profile.js, specify profile=base. Default: base
profileFile
A file path to the profile file. Use this if your profile is outside of the profiles directory. Do not specify the “profile” build option if you use “profileFile” Default: “”
action
The build action(s) to run. Can be a comma-separated list, like action=clean,release. The possible build actions are: clean, release Default: “help”.Note: the ”release” action automatically implies the ”clean” action, except when you have used the advanced parameter ”buildLayers” in your profile.

version
The build will be stamped with this version string Default: “0.0.0.dev”
localeList
The set of locales to use when flattening i18n bundles Default: “en-gb,en-us,de-de,es-es,fr-fr,it-it,pt-br,ko-kr,zh-tw,zh-cn,ja-jp”
releaseName
The name of the release. A directory inside ‘releaseDir’ will be created with this name Default: “dojo”
releaseDir
The top level release directory where builds end up. The ‘releaseName’ directories will be placed inside this directory Default: “../../release/”
loader
The type of dojo loader to use. “default” or “xdomain” are acceptable values.” defaultValue: “default”
internStrings
Turn on or off widget template/dojo.uri.cache() file interning Default: true
optimize
Specifies how to optimize module files. If “comments” is specified, then code comments are stripped. If “shrinksafe” is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If “shrinksafe.keepLines” is specified, then the Dojo compressor will be used on the files, and line returns will be preserved. If “packer” is specified, Then Dean Edwards’ Packer will be used Default: “”Note: using the ”packer” option is discouraged in most environments. In environments where the http server supports gzip compression automatically, ”shrinksafe” will provide better performance. ”packer” also does more transformations to the underlying source code.

layerOptimize
Specifies how to optimize the layer files. If “comments” is specified, then code comments are stripped. If “shrinksafe” is specified, then the Dojo compressor will be used on the files, and line returns will be removed. If “shrinksafe.keepLines” is specified, then the Dojo compressor will be used on the layer files, and line returns will be preserved. If “packer” is specified, Then Dean Edwards’ Packer will be used Default: “shrinksafe”
copyTests
Turn on or off copying of test files Default: true
log
Sets the logging verbosity. See jslib/logger.js for possible integer values Default: logger.TRACE
xdDojoPath
If the loader=xdomain build option is used, then the value of this option will be used for the path to Dojo modules. The dijit and dojox paths will be assumed to be sibilings of this path. The xdDojoPath should end in ‘/dojo’ Default: “”

Cross Domain (XDomain) Builds

Doing an xdomain build allows you to load Dojo and your custom modules from another domain.

Benefits

  • You get more connections in MSIE, since you can load from another domain. Faster loading.
  • You get increased cacheability/startup if many of your applications use the same installation.
  • Resource loading does not block the rest of the page from filling in as with Dojo’s normal, synchronous loading.
  • With a local install, your ISP may charge you for all of those Dojo bits that you are serving.

Implications/Limitations

  • Not all external resources can be xdomain loaded, in particular some support files that need to be loaded from the same domain as the HTML page. See module-specific notes below.
  • Requires a “xdomain” build of Dojo (see below for more info on how to make a xdomain build).
  • Asynchronous loading. You MUST use dojo.ready() to register a callback function to get notification of package loading. This can be used even after the initial page load. Just do the dojo.require()s that you need, and then call dojo.ready() with a callback function, and once those new packages are loaded (or if they are already loaded), then the callback will be called. This technique works even for the normal Dojo loader, so this is a good practice to use even when not using an xdomain build.
  • Avoid using document.write(): Since module can load asynchronously, after the page is loaded, document.write can cause problems.

Module-specific Notes

dojo.io.iframe.create(), dijit.Editor, dijit._editor.RichText: You need to save dojo/resources/blank.html to the same domain as your HTML page and set dojoConfig.dojoBlankHtmlUrl to the path on that domain.Note: The dijit.Editor/dijit._editor.RichText has a bug in release 1.1.0 where it was not using this dojoConfig parameter. It is fixed in Dojo 1.1.1 and later.

dojo.back: You need to save dojo/resources/blank.html to the same domain as your HTML page and set dojoConfig.dojoIframeHistoryUrl to the path on that domain.

dojox.flash.Info(): It uses document.write() which will cause problems if dojox.flash is loaded via dojo.require().

Doing xdomain builds

Sample xdomain build command:

$ cd util/buildscripts
$ build.sh profile=foo loader=xdomain xdDojoPath=http://my.server.com/path/to/buildoutputdir action=release

xdDojoPath is optional. It just burns in the location of dojo, dijit and dojox into the built dojo.js. If you do not specify that option, then you will need to use dojoConfig.modulePaths/dojo.registerModulePath() in your HTML page to set the xdomain locations for dojo, dijit and dojox. For your own custom modules, you will have to set dojoConfig.modulePaths/dojo.registerModulePath() even if you use the xdDojoPath build option.

For Dojo 0.9 through 1.1.x: there is a bug about loading dojox.gfx with an xdomain build. This is fixed in Dojo 1.2. If you want to use dojox.gfx with an xdomain build of Dojo 0.9-1.1.x, there are some workarounds until the bug gets fixed:

How to use xdomain builds in web pages

  • In dojoConfig, add useXDomain = true.
  • In dojoConfig, add a modulePaths object that maps where to find your modules.
  • Only use dojo.require() to load xdomain layers. Do not reference the .xd.js file for the layer file. The one exception is dojo.xd.js. If your layer does not map to a real module name, then specify a resourceName: property for that layer in your build profile. The other option is to load the built .js file (not .xd.js file) in a script tag.
  • Register a callback function to get notification of when the packages are loaded by using dojo.ready().
  • Optional: set a wait time in milliseconds (dojoConfig.xdWaitSeconds) that specifies how long the resource loader should wait for a resource to load until returning an error. Since script elements do not give information about failed or long-running requests, this timeout is used to prevent infinite waiting in the browser. An exception will be thrown to indicate a load error. The default xdWaitSeconds is 15.

XDomain Example

Here is an example showing how to load local modules along with an xdomain-loaded dojo and dijit. You can download this example.

TODOC: everything. outline here:

  • summary
  • requirements / setup
  • creating a profile
  • command line arguments
  • special builds: * layers * css
  • file structure

link to full docs to cover:

  • excludeStart/Stop
  • restoreRequire
  • layerDependencies
  • discard
  • .uncompressed.js
  • customBase
  • more..

Android: guia de diseño de iconos

Un icono launcher  es un gráfico que representa tu app. Los iconos de launcher son utilizados por las aplicaciones Launcher y aparecen en la pantalla Home del usuario. Los iconos launcher pueden ser también utilizados como accesos directos para iniciar tu app (como el enlace directo de un contacto que abre información detallada del contacto).

Como se describe en Providing Density-Specific Icon Sets y en Supporting Multiple Screens, debes crear iconos separados para todas las densidades de pantallas lo cual incluye  low-, medium-, high-, y extra-high-density. Esto te asegura que tus iconos se ven bien en todos los tipos de dispositivos en los que se puede instalar tu app. Ver Tips for Designers para sugerencias de como trabajar con varios conjuntos de iconos.

Una versión de alta resolución del icono launcher de tu app también es necesitado por Google Play para utilizarlo en los listados de apps. Para más detalles ver  Application Icons on Google Play más abajo.

Nota: hay una versión antigua de este documento en launcher icon guidelines archive.

Objetivos del icono launcher

Example launcher icons for system and third-party applications

Figure 1. Ejemplos de iconos launcher para aplicaciones de sistema (izquierda) y para aplicaciones third party (derecha)

Los iconos de launcher tiene tres objetivos principales:

  1. Promocionar la marca y reflejar de qué va la app.
  2. Ayudar a los usuarios a descubrir la app en Google Play
  3. Funcionar bien en un Launcher

Promocionar la marca y de lo que va

Los iconos de launcher de la app son una oportunidad para mostrar tu marca y contar de qué va tu app. Así, deberiamos:

App launcher icons are an opportunity to showcase the brand and hint at the story of what your app is about. Thus, you should:

  • Create an icon that is unique and memorable.
  • Use a color scheme that suits your brand.
  • Don’t try to communicate too much with the icon. A simple icon will have more impact and be more memorable.
  • Avoid including the application name in the icon. The app name will always be displayed adjacent to the icon.

Help users discover the app on Google Play

App launcher icons are the first look that prospective users will get of your app on Google Play. A high quality app icon can influence users to find out more as they scroll through lists of applications.

Quality matters here. A well-designed icon can be a strong signal that your app is of similarly high quality. Consider working with an icon designer to develop the app’s launcher icon.

Note: Google Play requires a high-resolution version of your icon; for more details on this, see Application Icons in Google Play below.

Para que un icono funcione bien como Launcher

El launcher o pantalla de inicio de aplicaciones es donde los usuarios interactuan con el icono más frecuentemente. Un icon launcher bien hecho aparece bien en todas las situaciones: sobre cualquier fondo , al lado de otros iconos y widgets de app. Para conseguir esto , recuerda lo siguiente:

  • Comunica bien en todos los tamaños
  • Se ve bien sobre un amplio rango de fonfos
  • Refleja el implied lighting model of the launcher (top-lit).????
  • Si el icono es 3D, utiliza una perspectiva que no parezca que está fuera de lugar con otros iconos, ponle el perfil en el que mejor salga.
    • Los iconos 3D se ven mejor con un sombra alrededor que le de profundidad.
  • Mejor tener una única silueta para que sea reconocido rápidamente; no todos los iconos de apps tienen que ser cuadrados.
    • Procura que los iconos no presenten un vista cortada de una imagen más grande.
  • Procura que el peso del icono tenga un peso similar a los que ya existen: los iconos que son muy delgaditos o que no usan suficiente espacio pueden no resultar atractivos a la atención del usuario ; o pueden no quedar bien para todos los fondos.

Cosas que debes hacer y cosas que no debes hacer

Vamos a enumerar cosas que debes hacer y cosas que no debes hacer para crear los iconos de tu aplicación:

Side by side: overly complicated vs. simpler launcher icons Los iconos no deben ser demasiado complicados. Recuerda que los iconos launcher serán usados a menudo en tamaños pequeños, asi que deben poder distinguirse en estos tamaños.
Side by side: cropped and glossy vs. matte and single-shape launcher icons Los iconos no deben ser recortes. Usa formas únicas donde sean apropiadas; recuerda que los iconos launcher deben diferenciar tu aplicación de otras. Adicionalmente , no utilices demasiado brillo a menos que el objeto representado sea de un material brillante.
Side by side: overly thin vs. thicker, weightier icons Los iconos no deben ser delgados. Deben tener un pso similar al resto de iconos. Los iconos delgaditos no se distinguen bien en todos los fondos.
Side by side: full-frame vs. subtly rounded and treated icons Los iconos deben hacer uso del canal alpha, y no deberian ser simplemente imagenes full-frame. Cuando sea oportuno, distingue tu icono con algún detalle visual atractivo.

Tamaño y Formato

Los iconos Launcher deben ser PNGs de 32-bit con un canal alpha para la transparencia. Las dimensiones del icono launcher que se corresponden a una determinada densidad de pantalla se muestran en la tabla siguiente:

Table 1. Summary of finished launcher icon dimensions for each generalized screen density.

ldpi (120 dpi)
(Low density screen)
mdpi (160 dpi)
(Medium density screen)
hdpi (240 dpi)
(High density screen)
xhdpi (320 dpi)
(Extra-high density screen)
Launcher Icon Size 36 x 36 px 48 x 48 px 72 x 72 px 96 x 96 px

Puedes además incluir unos pocos pixeles de apdding en los iconos de launcher para mantener una consistencia visual de peso con los iconos adyacentes. Por ejemplo, un icono launcher de 96×96 pixels xhdpi puede contener una figura de 88×88 de tamaño con 4 pixeles a cada lado de padding. Este padding puede también ser utilizado para hacer espacio para poner un borde de sombra que le de profundidad al icono al ponerlo en determinados colores de fondo.

Iconos de aplicación en Google Play

Si estás publicando tu aplicación en Google Play , además necesitas proporcionar un icono de aplicación de alta resolución de 512×512 pixeles. Se subirá en la developer console en el momento de publicación de la app. Este icono será utilizado en varias localizaciones de Google Play y no sustituirá al icono launcher.

Para trucos y recomendaciones sobre crear iconos launcher de alta resolución que pueden ser fácilmente escalados a 512×512 ver  Tips for Designers.

Para información y especificaciones sobre iconos de aplicación de alta resolución en Google Play , échale un vistazo al siguiente artículo :

Graphic Assets for your Application (Google Play Help) »

La importancia de un buen análisis funcional

[Fuente: http://jummp.wordpress.com/2009/11/28/la-importancia-de-un-buen-analisis-funcional/]

De todos es sabido que cuanto antes se solucione un problema en un proyecto de desarrollo de software, menos coste tiene para el mismo y de ello salen beneficiados tanto proveedor como cliente.

Por ese motivo resulta esencial que un proyecto sea sólido desde la base, siendo la misma el análisis funcional, lo que hace que sea muy importante la figura del analista que es la persona o grupo de personas (si el proyecto es grande) que se tienen que encargar de entender, interpretar y traducir lo que el usuario demanda, sentando las bases de los posteriores procesos de diseño y construcción del sistema de información.

Hacer un buen análisis es una tarea bastante compleja, ya que resulta muy complicado obtener todos los requerimientos del usuario desde etapas muy tempranas, ya que por regla general el usuario empieza a descubrir el detalle de todo lo que quiere cuando empieza a utilizar el producto ya construido con ejemplos reales de su día a día de trabajo (también suelen comentar nuevos requisitos o enmendar requisitos previos, en otras etapas conforme se le vaya presentando la evolución del proyecto, de hecho no es malo que se corrijan, ya que cuanto más avanzado esté el proyecto, el esfuerzo de hacer los cambios es mucho mayor). De hecho es prácticamente inevitable no hacer evolutivos que solventen esos flecos que no se detectaron en análisis para dejar el producto lo más próximo posible a lo que los usuarios necesitan y demandan. Como consecuencia de lo anterior, y como es lógico, se puede considerar que un análisis funcional es más bueno conforme sea menor el número de ajustes que haya que hacer en etapas posteriores del proyecto.

Es importante matizar que un proyecto de desarrollo de software no es una barra libre y que es importante que el usuario conozca sus responsabilidades en el proceso de definición del sistema y que no se pueden estar cambiando de requisitos continuamente, como tampoco podría estar cambiando frecuentemente de opinión si le están construyendo una casa. Todo lo anterior además hay que compatibilizarlo con que todas las partes están interesadas en el que el proyecto vaya a buen término, por lo que tampoco es una buena política ser inflexibles en la modificación del catálogo de requisitos, porque si el resultado final no es el que quiere el usuario, el sistema de información tendrá muchas papeletas para no ser utilizado. Equilibrio complicado: evitar que los usuarios modifiquen continuamente requisitos y tener un poco de mano izquierda cuando se planteen esos cambios. Como ese equilibrio es complicado de mantener y es fuente frecuente de conflictos, hay que intentar que el análisis tenga la mayor calidad posible.

Hacer un análisis funcional por tanto es una tarea compleja, a lo que hay que sumar que en muchos casos hay que aprender mucho sobre el proceso de negocio que se pretende informatizar, para entender de mejor manera lo que el usuario demanda, ya que resulta todo más fácil si el lenguaje que se utiliza es el mismo. En muchas ocasiones esos procesos de negocio son tremendamente complejos y además se dispone también de poco tiempo para entenderlos, teniendo en cuenta que por regla general y como he comentado muchas veces en mi blog, los proyectos informáticos suelen estar infravalorados (por el que contrata y/o por el que es contratado (para conseguir el contrato)).

Dado que el análisis funcional consiste en abstraer un conjunto de necesidades de los usuarios es muy importante la implicación de los mismos y eso no siempre se consigue. Si los usuarios no están implicados, por muy buen analista funcional que tenga el proyecto, las probabilidades de que este salga mal crecen exponencialmente. Evidentemente un buen analista puede paliar esos huecos que deja el usuario e incluso conseguir una mayor participación de los usuarios, pero más tarde o más temprano los problemas aparecerán y al final siempre termina pagando el proyecto (en primera instancia) y el que lo desarrolla (en segunda). Por todo lo anterior, se puede pedir que un analista funcional aprenda un proceso de negocio complejo, que consiga extraer de los usuarios lo que buscan y necesitan y que además lo haga en un tiempo record, pero lo que no se le puede pedir es que haga magia y resuelva problemáticas que le trascienden, como el caso que he comentado de la inacción de los usuarios en determinados proyectos, siendo esa falta la implicación la primera causa de que un análisis no salga bien y por tanto una de las causas más importantes del fracaso de un proyecto y no se trata en este caso de tirar pelotas fuera y ponerme del lado de mis colegas de profesión, se trata de algo que he podido vivir en diferentes proyectos de manera muy directa.

Nadie es infalible y un analista funcional tampoco lo es. Habrá errores (independientemente de que la causa de los mismos sea provocada por circunstancias adversas en el proyecto o no), puede que en este proyecto sean muy pocos y que en otros sean mayores, por eso es importante que el analista lo tenga asumido desde un principio, como también lo es que de esos errores se debe aprender y que resultarán fundamentales en la formación del mismo. Al final esos errores terminan curtiendo y permiten que cada vez los análisis que se realicen sean mejores. Por tanto, la experiencia resulta importante. En cualquier caso, suponer un análisis perfecto es suponer que en un proyecto se dan circunstancias ideales y que todas las variables que pueden influir en que las cosas vayan mejor o peor, están todas a favor.

De todo lo comentado en los párrafos anteriores se extrae que es importante que un analista funcional sea un buen comunicador, primero con el usuario ya que resulta fundamental que el usuario conozca todo lo que hemos entendido y cómo se pretende llevar a cabo (no conseguir eso es ir a ciegas) y segundo con el equipo de proyecto ya que tiene que trasladar a documentación y hacerles entender la interpretación de lo que el usuario quiere y cómo lo quiere.

Un buen análisis funcional no asegura el éxito del proyecto, ya que la ejecución técnica del mismo también tiene un peso importante, pero lo que sí es seguro es que si el análisis funcional no es bueno, la ejecución técnica difícilmente puede salvar las deficiencias del mismo y tocará corregir el producto una vez construido y además, por regla general, en diferentes evoluciones, lo cual es muy costoso y tampoco asegura que ese árbol que empezó torcido, termine por enderezarse

 

TDD: Programación orientada a pruebas

[Fuente: http://net.tutsplus.com/tutorials/php/the-newbies-guide-to-test-driven-development/]

Probar el código es molesto, pero el impacto de no hacerlo puede crear molestias de magnitudes muy superiores!.  En este artículo, utilizaremos programación orientada a objetos (test-driven development) para programar y probar nuestro código más eficientemente.

Qué es el TDD o Programación Orientada a Pruebas (POP)?

Desde el principio de los tiempos, los programadores y los fallos han luchado los unos con los otros. Incluso los mejores programadores tienen fallos. Ningún código es 100% seguro. Es por ello que hacemos testing. Los programadores, al menos los sanos, pruebas su código ejecutando en máquinas de desarrollo par estar seguros que el código hace lo que se supone que debe hacer.


Programador que prueba sus programas.
Image courtesy of http://www.youthedesigner.com


Programador que no prueba sus programas
Image courtesy of http://www.internetannoyanceday.com

“La programación orientada a objetos es una técnica de programación que requiere que se programen a la vez el código y sus pruebas automatizadas. Esto asegura que pruebas tu código – y te permite reprobar tu código rápida y fácilmente, ya que está automatizado”

Cómo funciona?

El desarrollo orientada a pruebas , o TDD como lo llamaremos desde ahora, recuerda como a un corto ciclo de desarrollo iterativo que va de la siguientes pasos:

  1. Antes de escribir cualquier código, debes primero escribir un test automatizado para el código. Mientras escribir el código automatizado, debes tener en cuenta todas las posibles entradas de datos, errores y salidas. De esta forma, tu mente no estará confundida con código que ya ha sido escrito.
  2. La primera vez que ejecutas las pruebas automatizados, el test debe fallar – indicando que el código no esta listo aún.
  3. Después, puedes empezara programar. Ya que hay un test automático, tan pronto como el código falle, eso significa que aún no esta listo. El código puede ser arreglado hasta que pase todos los assertions.
  4. Una vez que el código pasa el test, puedes empezar a limpiarlo, utilizando refactoring. Mientras el código siga pasando los test, significa que funcione. No te tienes que preocupar sobre los cambios que introduzcan nuevos fallos.
  5. Comienza desde el principio con cualquier otro método o programa.

Ok , pero por qué esto es mejor que las pruebas normales?

Has pasado a proposito de probar un programa porque:

  • sientes que es una perdida de tiempo, ya que solo fue un cambio pequeño?
  • te da pereza probar todo otra vez?
  • no tienes tiempo suficiente para probar porque el gestor del proyecto lo quiere en producción ASAP?
  • te dijiste a ti mismo que ya lo harías mañana?
  • tenias que elegir entre pruebas a mano , o ver el último episodio de Barrio Sesamo?

La mayor parte del tiempo, nada sucede, y pones tu código en producción sin ningún problema. Pero algunas veces, después de que lo has puesto en producción, todo empieza a ir mal. Y estas acorralado arreglando multitud de errores en un barco que se hunde, con más errores apareciendo  a cada momento. Seguro que no quieres verte en esta situación.

TDD fue creado para que no tengamos excusas. Cuando un programa ha sido desarrollado utilizando TDD, te permite hacer cambios y probarlo rápidamente y eficientemente. Todo lo que necesitamos es ejecutar los tests automatizados y voila! Si pasa todos los test automatizados, entonces vamos bien – si no, entonces hemos roto algo con los ultimos cambios que hemos hecho. Conociendo qué parte del código ha fallado, también te permite fácilmente averiguar en qué parte del código está el fallo, haciendo el arreglo de errores mucho más fácil.

Lo he vendido . ¿Cómo lo hago?

Hay muchos frameworks de testing automático para PHP que podemos utilizar, Uno de los más ampliamente utilizados es PHPUnit.

PHPUnit puede integrarse fácilmente en nuestros proyectos, u otros proyecto que han sido construidos sobre otros frameworks PHP populares.

Para nuestros propositos, no necesitamos la multitud de funciones que ofrece PHPUnit. En vez de ello, optaremos por crear nuestros propios test utilizando un framework de testing mucho más simple, llamado SimpleTest.

En los siguiente pasos, asumiremos que estamos programando una aplicación de libro de invitados donde cualquier usuario puede añadir y ver entradas del libro.

Asumiremos que ya tenemos una maqueta de la aplicación, y que simplemente estamos haciendo una clase que contiene la lógica de la aplicación, que es la que lee y escribe en la BBDD. La parte de lectura es lo que vamos a desarrollar y probar.

Primer Paso: Configurar SimpleTest

Descarga  SimpleTest here, y extrae a la carpeta que quieras – preferiblemente a la carpeta donde vas a programar tu código , o en el include_path de PHP para más comodidad.Para esto tutorial , he configurado una carpeta como se ve aqui:

index.php ejecutará nuestro guestbook.php, e invoca el método view y mostrará las entradas. Dentro de la carpeta “classes” es donde pondremos la clase “guestbook.php”, y la carpeta test es donde colocaremos la libreria simpletest.

Segundo paso. Planeemos nuestro ataque

El segundo paso, que es de hecho el más importante, es empezar a crear tus pruebas. Para esto, realmente necesitas planificar y pensar qué hara tu función, qué posibles entradas recoge y que correspondientes salidas enviará. Este paso recuerda a jugar al ajedrez – necesitas saber todo sobre tu oponente (el programa), incluyendo todas sus debilidades (posibles errores) y fortalezas (lo que sucede si todo se ejecuta correctamente).

Asi que para nuestra aplicación guestbook , veamos cuál es el esquema:

View

  • Esta función no tendrá ninguna entrada ya que recupera todas las entradas de la BBDD y las envía de vuelta para que sean escritas en pantalla
  • Retornará un array de los registros del libro de invitados, conteniendo cada registro el nombre y su mensaje. Si no hay registros, entonces , debe devolver un array vacío.
  • Si hay registros , el array tendrá uno o más valores dentro.
  • Al mismo tiempo, el array tendrá un estructura específica , algo como esto:
  • Array (
    	[0] => Array (
    		['name'] = "Bob"
    		['message'] = "Hi, I'm Bob."
    	)
    	[1] => Array (
    		['name'] = "Tom"
    		['message'] = "Hi, I'm Tom."
    	)
    )
    
    
    
    

Tercer paso: Escribe un test!

Ahora, podemos escribir nuestro test. Empecemos creando un fichero llamado guestbook_test.php dentro de la carpeta test.

<?php
	require_once(dirname(__FILE__) . '/simpletest/autorun.php');
	require_once('../classes/guestbook.php');
	class TestGuestbook extends UnitTestCase {

		function testViewGuestbookWithEntries()
		{
			$guestbook = new Guestbook();
			// Add new records first
			$guestbook->add("Bob", "Hi, I'm Bob.");
			$guestbook->add("Tom", "Hi, I'm Tom.");
			$entries = $guestbook->viewAll();
			$count_is_greater_than_zero = (count($entries) > 0);
			$this->assertTrue($count_is_greater_than_zero);
			$this->assertIsA($entries, 'array');
			foreach($entries as $entry) {
				$this->assertIsA($entry, 'array');
				$this->assertTrue(isset($entry['name']));
				$this->assertTrue(isset($entry['message']));
			}
		}

		function testViewGuestbookWithNoEntries()
		{
			$guestbook = new Guestbook();
			$guestbook->deleteAll(); // Delete all the entries first so we know it's an empty table
			$entries = $guestbook->viewAll();
			$this->assertEqual($entries, array());
		}
	}
?>
Con las aserciones te aseguras que una cosa es lo que se supone que debe ser – basicamente, te asegura que lo que está retornando es lo que se espera que debe retornar. Por ejemplo, si un función se supone que retorna true si ha ido todo bien, entonces en nuestro test, deberiamos hacer un assert que chequea que el valor de retorno es igual a true.
Como puedes ver aqui, en el test estamos probando el listado de las entradas del guestbook con los que tiene y con los vacios.Chequeamos is estos dos escenarios pasan nuestros criterios desde el paso 2. Probablemente hayas visto que las dos funciones de test comienzan con la palabra ‘test’. Lo hacemos asi porque, cuando  SimpleTest ejecuta esta clase, busca todas las funciones que empiezan con este prefijo para ejecutarlas.
En nuestro clase de test, también hemos puesto algunos métodos assert, como assertTrue, assertIsA y asserEquals. La función assertTrue chequea si un valor es o no true.AssertIsA chequea si una variable es de un cierto tipo o clase. Hay otros método de assertion que proporciona SimpleTest:
assertTrue($x) Fail if $x is false
assertFalse($x) Fail if $x is true
assertNull($x) Fail if $x is set
assertNotNull($x) Fail if $x not set
assertIsA($x, $t) Fail if $x is not the class or type $t
assertNotA($x, $t) Fail if $x is of the class or type $t
assertEqual($x, $y) Fail if $x == $y is false
assertNotEqual($x, $y) Fail if $x == $y is true
assertWithinMargin($x, $y, $m) Fail if abs($x – $y) < $m is false
assertOutsideMargin($x, $y, $m) Fail if abs($x – $y) < $m is true
assertIdentical($x, $y) Fail if $x == $y is false or a type mismatch
assertNotIdentical($x, $y) Fail if $x == $y is true and types match
assertReference($x, $y) Fail unless $x and $y are the same variable
assertClone($x, $y) Fail unless $x and $y are identical copies
assertPattern($p, $x) Fail unless the regex $p matches $x
assertNoPattern($p, $x) Fail if the regex $p matches $x
expectError($x) Swallows any upcoming matching error
assert($e) Fail on failed expectation object $e

Assertion method list courtesy of http://www.simpletest.org/en/unit_test_documentation.html

Cuarto Paso: Tener errores para ganar

Una vez que has terminado de escribir el código del test, ejecutas el test. La primera vez que ejecutas el test, debe FALLAR. Si no lo hace , entonces es que el test no prueba nada.
Para ejecutar el test , simplemente ejecuta guestbook_test.php en tu navegador. Primero debes ver esto:

Esto sucede porque no hemos creado nuestra clase guestbook aún. Para hacerlo, crearemos guestbook.php dentro de la carpeta classes. La clase debe contener los métodos que estamos planeando utilizar, aunque de momento los ponemos vacios. Recuerda, estamos escribiendo los test antes que el código.

<?php
class Guestbook
{
	public function viewAll() {
	}

	public function add( $name, $message ) {
	}

	public function deleteAll() {
	}
}

Si ahora ejecutamos el test otra vez, debe aparecer algo esto:

Como ves ahora, nuestro test esta ahora funcionando aunque falle!. Esto significa que nuestro test está listo para ser “respondido”.

Quinto Paso:  Responde tu test escribiendo código

Ahora que tenemos un test automático funcionando, podemos empezar a escribir código. Abramos guestbook.php y empecemos a dar respuesta a nuestro test:
<?php
class Guestbook {

	var $entries = array(
		array (
			'name' => 'Kirk',
			'message' => 'Hi, I'm Kirk.'
		),
		array (
			'name' => 'Ted',
			'message' => 'Hi, I'm Ted.'
		)
	);

	// To save time, instead of creating and connecting to a database, we're going to
	// simulate a "database" by creating a static entries array here.
	// It will be like we have two entries in the table.

	function viewAll() {
		// Here, we should retrieve all the records from the database.
		// This is simulated by returning the $entries array
		return $this->entries;

	}
	function add($name, $message) {
		// Here, we simulate insertion into the database by adding a new record into the $_entries array
		// This is the correct way to do it: self::$_entries[] = array('name' => $name, 'message' => $message );
		$this->entries [] = array('notname' => $name, 'notmessage' => $message ); //oops, there's a bug here somewhere
                return true;

	}
	function deleteAll() {
		// We just set the $_entries array to simulate
		$this->entries = array();
		return true;
	}

}
?>

Una vez que ejecutamos nuestros test , debemos ver algo como esto:

La salida del test nos muestra en qué test y en que assertions nuestro código falla. Vemos claramente que en las lineas 16 y 17 está la assertion que arrojó el error. (Se han introducido fallos a proposito en las lineas 16 y 17).

El error estaba en que la key que metiamos no era la correcta , arreglamos esas lineas y ya obtenemos que todo va bien:

Sexto paso: Refactorizar y Refinar el código

Since the code we’re testing here is pretty simple, our testing and bug fixing didn’t last very long. But if this was a more complex application, you’d have to make multiple changes to your code, make it cleaner so it’s easier to maintain, and a lot of other things. The problem with this, though, is that change usually introduces additional bugs. This is where our automated test comes in—once we make changes, we can simply run the test again. If it still passes, then it means we didn’t break anything. If it fails, we know that we made a mistake. It also informs us where the problem is, and, hopefully, how we’ll be able to fix it.

Step 7. Aclarado y repetimos

Eventually, when your program requires new functionality, you’ll need to write new tests. That’s easy! Rinse and repeat the procedures from step two (since your SimpleTest files should already be set up), and start the cycle all over again.


Conclusion

There are a lot more in-depth test-driven development articles out there, and even more functionality to SimpleTest than what was displayed in this article—things like mock objects, stubs, which make it easier to create tests. If you’d like to read more, Wikipedia’s test-driven development page should set you on the right path. If you’re keen on using SimpleTest as your testing framework, browse the online documentation and be sure to review its other features.

Testing is an integral part of the development cycle, however, it’s too often the first thing to be cut when deadlines are imminent. Hopefully, after reading this article, you’ll appreciate how helpful it is to invest in test-driven development.

What are your thoughts on Test-Driven Development? Is it something you’re interested in implementing, or do you think it’s a waste of time? Let me know in the comments!

Los 5 mitos más populares sobre los programadores “viejos”

[Fuente: http://www.lessonsoffailure.com/developers/pervasive-myths-older-software-developers]

Recientemente celebré mi 40 cumpleaños. Un amigo bromeo: “Ei, parece que ya eres demasiado viejo para programar ”. En ese momento me hizo gracia, pero después me hizo pensar. La discriminación por edad no es nada de lo que hay que bromear en ese campo.Los programadores de COBOL tienen este problema cada año a medida que programadores Java como yo están ascendiendo profesionalmente. En esos momentos nos reíamos de los que programan en código nativo que es inflexible a las nuevas tecnologías.

Ahora la broma me ha tocado a mi. Y si no me ha tocado ya , será pronto. Quizás ya no tenemos ganas de reirnos. Asi pensaba yo. Nuestro campo esta maduro en el sentido de la discriminación por edad en muchos sentidos. Valoramos las nuevas tecnologías, la habilidad de adaptarse rápido a ellas, trabajar infinitas horas extras para sacar lo antes posible los productos- todas estas cosas son atribuidas a trabajadores jovencitos. He mencionado que a los jovencitos son más baratos? Mucho más baratos.

Sin embargo las tendencias de los titulados en ciencias de la información no pintan muy bien en cuanto a tener un buena hornada de jóvenes y baratos programadores a disposición de los managers indefinidamente:

Computer Science Degree Trends 1996-2008

De hecho, todos los datos apuntan a una conclusion: los titulados en IT ha ido decreciendo o se han quedado en lo mismo en la última década.Además la situación para contratarlos tampoco es muy halagueña: http://www.codinghorror.com/blog/2010/02/the-nonprogramming-programmer.html

Si estas pensando en eliminar “la materia gris” de tu equipo de desarrollo, piénsatelo dos veces. Hay muchos mitos sobre programadores “viejos” que aún viven en el mundo IT y que en principio los ponen en desventaja en este campo. Todos estos mitos no tienen ninguna validez y vamos a desmontarlos uno por uno:

MITO 1Los programadores “viejos” son más caros que los jóvenes, con lo cual los jovencitos son más deseables

REALIDAD: La verdadera razón por la cual los programadores experimentados son etiquetados como caros es debido a que los salarios son el gasto nº 1 de cualquier compañía. El hecho es desde luego que los más jóvenes son más baratos. Pero, mientras inexperimentados, jóvenes programadores pueden ahorrarte algunos ceros en tu presupuesto inicialmente, a la larga te va a salir caro si en tu equipo de trabajo solo tienes jóvenes. Los programadores jóvenes aún no han sufrido las incidencias de todo tipo que puede tener un proyecto software. Simplemente porque aún no ha pasado tiempo suficiente. Y adivina quién va gastarse el dinero en que aprendan? Tú. Piensa cuánto dinero te va a costar no llegar a tiempo a las fechas de entrega y a realizar proyectos con defectos? Piénsalo dos veces.

Si , los programadores mayores tienen salarios más altos que los jóvenes. Pero qué es exactamente por lo que tú pagas?. Con un programador experimentado , estás pagando por toda la experiencia que tiene en sus proyectos pasados tanto exitosos como los que salieron mal. Las lecciones que se aprenden en los proyectos que tienen incidencias son caras , tu decides si quieres pagar por ellos como manager o puedes contratar un programador experimentado, que es como tener un seguro contra los errores más típicos en la gestión de un proyecto y de un desarrollo software y que tú no vas a sufrir. Eso significa que tu cuenta anual de resultados tiene mejor pinta porque has decidido contratar gente que sabe cómo hacer el trabajo correctamente.

MITO 2:  Los programadores “viejos” son menos flexibles y menos capaces de aprender nuevas tecnologías debido a todo el conocimiento que ya acumulan

REALIDAD: Es precisamente por su experiencia pasada, que son más los programadores experimentados que pueden migrar a nuevas tecnologías, frameworks, y sistemas más rápidamente y en más profundidad. Por ejemplo, si aprender a manejar un Framework GUI en C/C++, tienes un modelo mental sobre lo que es el intercambio de mensajes, la gestión de eventos, patrones MVC para diseñar el sistema y separar presentación de la lógica de negocio.

La primera vez que se aprender un Framework GUI, además de las sintaxis, los ejemplos, y las particularidades de la librería, también necesitas aprender términos conceptuales. Y después de dos, tres o más frameworks GUI, te das cuenta que todos tienen muchas similitudes más allá de la sintaxis. Pueden incluso darte cuenta que los frameworks más nuevos han superado limitaciones sustanciales que tú en su día tuviste que sortear con complicadas codificaciones. Estos puntos de vista no los tiene alguien nuevo en el Framework. Y esos puntos pueden realmente incrementar tu productividad de una forma que no puedes directamente medir.

MITO 3Los programadores “viejos” son menos hábiles para realizar tareas duras en desarrollo de software (vease: largas jornadas, horarios intempestivos) por sus compromisos familiares y otras obligaciones que los jóvenes no tienen.

REALIDAD: Creo que sería más exacto afirmar que los programadores experimentados están menos dispuestos a trabajar largas y dolorosas jornadas porque ellos ya se las saben todas en como la empresa intenta ampliar los límites productivos haciendo que trabajes horas extras. A esto se le llama acabar quemado(burnout), apuesto lo que sea que nadie de los que ya ha pasado por esto en el pasado esta dispuesto a pasar por ello otra vez.

Con todo lo dicho anteriormente, el argumento de los “compromisos familiares” es falaz. Los ingenieros-programadores experimentados , de alta calidad son bastante buenos en gestionar el tiempo, y los que tienen familia están incluso más motivados en acabar las tareas en el tiempo justo.Puede que tengan quew recoger al niñodel cole , pero ellos aprovechan el tiempo al máximo y sus 40 horas semanales están enfocados en su trabajo. Los buenos ingenieros de software con familias se deben convertir en grandes gestores de tiempo por las tareas que tienen ya en su vida privada.

MITO 4: Los programadores “viejos” son menos ágiles mentalmente que los jovenes

REALIDAD: La edad afecta al cerebro y eso es algo demostrado que los trabajadores mayores piensan más lentamente que los jovenes.Pero la agilidad mental es solo una parte de la ecuación.Pensar más rápido no es siempre mejor . Que hay que decir en cuanto a su capacidad de enjuiciamiento? Hay un refrán que dice:

Los buenos juicios vienen de la experiencia, la esperiencia viene del mal juicio.

La pérdida de agilidad mental es una pobre excusa para no contratar a un programador “viejo” teniendo en cuenta lo que ellos ya han visto , hecho , y vivido en muchos proyectos de éxito y de fracasos a los largo de su vida. Los programadores experimentados tienen toneladas de proyectos pasados para recordar y ayudar en la toma de decisiones. Los programadores jóvenes tienen nuevas ideas que también es importante, peor a menudo esas ideas no han pasado pruebas y no están demostradas. Tener ambas perspectivas en los equipos de trabajo es el verdadero valor.

MITO 5: Los programadores “viejos” están más hastiados y son más cínicos y por tanto, menos deseables en el lugar de trabajo que los jóvenes. Los jóvenes tienen más entusiasmo que los mayores.

REALIDAD: Este mito probablemente lo ha propagado alguien a quien no le gusta que se les critiquen sus ideas y que está rodeado de gente que ha tenido queaguantar un gran número de decisiones equivocadas una y otra vez. Los programadores experimentados huelen la mierda a distancia. Ellos no se van a crear historias del tipo de que el producto no esta siendo bien recibido por el Mercado , porque ellos han estado tratanto con clients durante años y saben que lo que túquieres es ponerte medallitas a su costa. Ellos no toleran trabajar con gestores que les piden trabajar 80 horas semanales porque el cliente quiera el software el mes próximo cuando ellos te avisaron que para completar el proyecto como se acordó necesitas 2 meses más.

Los programadores jóvenes no se han visto en estas situaciones tan frecuentemente y por lo tanto, tienen menos resistencia a las malas practicas en la gestión de proyectos. Si quieres tener un buen equipo y fabricar buenos productos software, tener gente que pueda decirte cuando estás tomando malas decisiones te ahorrará mucho tiempo y dinero. Pero esto sólo en el caso de que admitas que tú no tienes todo el conocimiento.

Y del entusiasmo ni hablemos. Si el entusiasmo decae con la edad, dime si Donald Knuth , Ward Cunningham, Bill Joy, Bill Gates y cientos de otros que han pasado labarrera de los 40 tienen poco entusiasmo en este campo debido a la edad. Pues no. Pasión es passion. Si la tienes en tus 40 , es que realmente tu amas esta profesión. Y esa clase de amor no va a decaer con la edad. Los programadores jovenes aún están encontrando su lugar en el mundo y pueden tener cortos periodosde passion, y aún pueden dejarla por los obstáculos y los desafios que este campo te pone en el camino.

————-

Concluyendo, pongamos las cosas claras:

Joven no es necesariamente malo y Viejo no es necesariamente bueno.

Y lo más importante , cualquiera que no sepa programar un hola mundo no debe ser contratado como programador , independientemente de la edad que tenga.Intenta mantener tus equipos de trabajo como una mezcla de jovenes y veteranos porque donde hay diversidad, tiene lugar el aprendizaje. Asi que no mires mal al delpelo gris que tienes en tu departamento, liberate de prejuicios y mira si él puede servirte más de lo que crees.

Algún dia el del pelo gris puedes ser tú.


Desarrollo de sistemas software y pruebas

 

El proceso de desarrollo de sistemas de software implica una serie de actividades en las que las posibilidades de que aparezca el fallo humano son enormes. Los errores pueden empezar a darse desde el primer momento del proceso, en el que los objetivos pueden estar especificados de forma errónea o imperfecta, así como en pasos posteriores. Debido a la imposibilidad humana de trabajar y comunicarse de forma perfecta, el desarrollo de software ha de ir acompañado de una actividad que garantice su calidad, las pruebas de software.

Even good programmers make mistakes. The difference between a good programmer and a bad programmer is that the good programmer uses tests to detect his mistakes as soon as possible. The sooner you test for a mistake the greater your chance of finding it and the less it will cost to find and fix. This explains why leaving testing until just before releasing software is so problematic. Most errors do not get caught at all, and the cost of fixing the ones you do catch is so high that you have to perform triage with the errors because you just cannot afford to fix them all.

Android: soportando multiples pantallas

Un vistazo

  • Android se ejecuta en dispositivos que tienen distintos tamaños de pantalla y distintas densidades
  • La pantalla en la que tu app es mostrada puede tener impacto en el interface de usuario de tu app.
  • El sistema maneja la mayoria del trabajo a la hora de adaptar tu app a la pantalla que sea.
  • Debes crear recursos especificos de pantalla para tener un control preciso de tu UI.

Android se ejecuta en una variedad de dispositivos que ofrecen distintos tamaños de pantallas y densidades. Para aplicaciones, el sistema Android proporciona un entorno de desarrollo consistente entre dispositivos y maneja la mayor parte de trabajo a la hora de ajustar el interfaz de usuario de las apps a la pantalla en la cual es está mostrando. Al mismo tiempo, el sistema proporciona APIs que te permiten controlar el UI de tu app para densidades y tamaños de pantallas especificos, para optimizar el diseño de tu UI para distintas configuraciones de pantallas. Por ejemplo, puedes querer un UI para tablets que es distintos del UI para smartphones.

Aunque el sistema realiza escalado y resizado para que tu app funcione en distintas pantallas, debes hacer un esfuerzo en optimizar tu app para distintos tamaños de pantalla y densidades. Haciendo eso, maximizas la experiencia de usuario para todos los dispositivos y tus usuarios creeran que tu app ha sido diseñada para su dispositivo.

Siguiendo las prácticas descritas en este documento, puedes crear una app que muestra el interfaz correctamente y proporciona una experiencia de usuario optimizada en todas las configuraciones de pantalla , utilizando un solo fichero .apk.

Nota: La información de este documento asume que tu app esta diseñada para Android 1.6 (API Level 4) o superior. Si tu app soporta Android 1.5 o más bajo, primero lee Strategies for Android 1.5.

También, ten en cuenta que Android 3.2 ha introducido nuevos APIs que te permiten controlar más precisamente los recursos de layouts que tu app utiliza para distintos tamaños de pantalla. Estas nuevas características son especialmente importantes si estas programando una app que sea optimizada para tablets. Para más info Declaring Tablet Layouts for Android 3.2.

Un vistazo al Screens Support

Esta sección proporciona un vistazo del soporte de Android para múltiples pantallas, incluyendo una introducción a los términos y conceptos utilizados en este documento y en el API, un resumen de las configuraciones de pantalla que el sistema soporta, y un vistazo del API y de las características de compatibilidad de pantallas que tiene implementados.

Términos y conceptos

Támano de pantalla (Screen size)
El támaño físico de la pantalla, medido como la diagonal de la pantalla (como en los televisores).
Por simplicidad, Android agrupa todos los támaños de pantallas actuales en cuatro tamaños generales: small, normal, large, and extra large.
Densidad de pantalla (Screen density)
La cantidad de píxeles dentro de una área física de la pantalla; normalmente referidos como dpi (dots per inch). Por ejemplo, una densidad de pantalla baja tiene menos pixeles ,dentro de una área dada de la pantalla, comparado con densidades de pantallas normales o altas.
Por simplicidad, Android agrupa todas las densidades de pantallas actuales en cuatro grupos: low, medium, high, and extra high.
Orientación
La orientación de la pantalla desde el punto de vista del usuario. Esto es, landscape o portrait, es decir apaisado o en vertical respectivamente. Que quede claro que además de que los distintos dispositivos pueden operar en una u otra orientación, para un mismo dispositivo la orientación puede cambiar en tiempo de ejecución cuando el usuario rote el dispositivo.
Resolución
El número total de pixeles físicos de una pantalla. Cuando añadimos soporte para múltiples pantallas, las aplicaciones no funcionan directamente con resoluciones; las apps deben solo preocuparse del támaño de pantalla y de la densidad, es decir deben preocuparse de los dos grupos dichos antes (el grupo de tamaños y el grupo de densidades).
Pixel independiente de la densidad –> Density-independent pixel (dp)
Una unidad de pixel virtual que debes utilizar cuando se define un layout, para expresar las dimensiones del layout o las posiciones de los elementos de forma que sea independiente de la densidad.
El pixel independiente de la densidad es equivalente a un pixel físico en una pantalla de 160 dpi, lo cual es la densidad base asumida por el sistema para una pantalla de densidad media. En tiempo de ejecución, el sistema , de forma trnasparente, maneja el escalado de las unidades dp, según sea necesario, basándose en la densidad actual de la pantalla en uso. La conversión de unidades dp a pixeles de pantalla es simple:  px = dp * (dpi / 160).Por ejemplo, en una pantalla de 240 dpi, 1dp es igual a 1.5 píxeles físicos. Debes siempre utilizar unidades dp cuando se defina el UI de la app, para asegurar que las pantallas se muestren propiamente en pantallas con distintas densidades.

Rango de pantallas soportados

Empezando con Android 1.6 (API level 4), Android proporciona soporte para múltiples pantallas y densidades, reflejando las muchas configuraciones que un dispositivo puede tener. Puedes utilizar características del sistema Android para optimizar el interfaz de usuario de tu app para configuraciones de pantalla específicas.

Para simplificar la forma en la que diseñas tus interfaces de usuario para múltiples pantallas, Android divide el rango de tamaños de pantallas actuales y densidades en:

  • Un conjunto de cuatro tamaños generalizados:  smallnormallarge, and xlarge. Nota: Desde Android 3.2 (API Level 13), estos grupos de tamaños están deprecados en favor de nuevas técnicas para manejar tamaños de pantallas basados en la anchura disponible de pantalla. Si estás programando para Android 3.2 o superior , ver  Declaring Tablet Layouts for Android 3.2 .
  • Un conjunto de cuatro densidades generalizadasldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)

Los tamaños y densidades generalizados están definidos sobre una configuración base que es el tamaño normal y la densidad mdpi. Esta configuración base esta basada en la configuración de pantalla del primer dispositivo Android , el T-Mobile G1, que tenia una pantalla HVGA (hasta Android 1.6, esta fue la única configuración de pantalla que Android soportaba).

Cada tamaño y densidad generalizados incluye una rango de tamaños y densidades reales. Por ejemplo, dos dispositivos que ambos informen que tiene un tamaño de pantalla normal pueden tener tamaños de pantalla y aspect ratios que sean ligeramente distintos cuando son medidos a mano. Lo mismo puede pasar con dos dispositivos que informen de tener un densidad mdpi. Android hace que estas diferencias sean transparentes al usuario, de forma que tu solo debes preocuparte para programar tus apps de acuerdo a los tamaños y las densidades generalizados y deja que Android maneje los ajustes finales. La figura 1 ilustra como los tamaños y densidades reales se agrupan en categorias:

Figure 1. Gráfico de cómo Android mapea los tamaños y densidades reales a tamaños y densidades generalizados (el gráfico no es exacto pero se aproxima).

Según diseñes tu UI para distintos tamaños de pantallas, descubrirás que cada diseño requiere una mínima cantidad de espacio. Asi, cada tamaño de pantalla generalizado tiene una resolución mínima asociada que está definida por el sistema. Estos tamaños mínimos están en unidades “dp” – las mismas unidades que debes utilizar en tus layouts – que permiten al sistema no preocuparse por cambios en la densidad de la pantalla.

  • xlarge tiene al menos 960dp x 720dp
  • large tiene al menos 640dp x 480dp
  • normal tiene al menos 470dp x 320dp
  • small tiene al menos 426dp x 320dp

Nota: Estos tamaños de pantalla mínimos fueron definidos antes de Android 3.0, por lo que puede haber algunos dispositivos que esten sin clasificar entre normal y large. Estos tamaños también están basados en la resolución física de la pantalla, que puede variar entre dispositivos. por ejemplo una tablet de 1024×768 que utilice una barra de sistema tiene un poco de menos espacio para la aplicación debido al espacio que ocupa la system bar.

Para optimizar el UI de tu app para los distintos tamaños de pantalla y densidades, puedes añadir recursos alternativos para todos los tamaños y densidades. Tipicamente, se hacen layouts alternativos para algunos tamaños diferentes de pantalla asi como imagenes alternativas para distintas densidades. En tiempo de ejecución, el sistema utiliza los recursos apropiados para tu app, basandose en la densidad y tamaño generalizados que trae la pantalla del dispositivo.

No es necesario añadir recursos alternativos para todas las combinaciones de tamaño y densidad. El sistema proporciona características de compatibilidad robustas que gestiona la mayor parte del trabajo de rendering en todas las pantallas , suponiendo que has implementado tu UI utilizando técnicas que permiten cambiar de tamaño de forma fácil(as described in the Best Practices, below).

Nota: Las caracteristicas que definen el tamaño y la densidad generalizadas de dispositivo son independientes unos de otros. Por ejmplo, una pantalla WVGA high-density screen es considerada una pantalla de tamaño normal porque su tamaño físico es el mismo que el  T-Mobile G1 (El primer dispositivo Android y configuración de pantalla base). De otra parte una WVGA medium-density screen se considera una pantalla de tamaño large. Aunque ofrece la misma resolución (el mismo número de pixeles), la WVGA medium-density screen tiene una densidad lower, significando que cada pixel es fisicamente más grande y , asi , la pantalla completa es larger comparada con  la pantalla normal.

Independencia de Densidad

Tu aplicación consigue “independencia de densidad” cuando conserva el tamaño físico (desde el punto de vista del usuario) de los elementos del interfaz del usuario cuando es mostrada en pantallas con distintas densidades.

Mantener la independencia de densidad es importante porque , sin ella, un elemento del UI (tal como un boton) aparece físicamente más grande en una pantalla con baja densidad y más pequeña en pantallas de densidades altas. Tales cambios de tamaño relacionados con la densidad puede hacer que tu layout se vea mal o en que sea tu aplicación poco usable. Las siguientes imagenes muestran las diferencias entre una aplicación cuando no proporciona independencia de densidad y cuando sí lo hace.

Figura 2. Ejemplo de aplicación sin soporte para distintas densidades.

Figure 3. Ejemplo de aplicación con un buen soporte de distintas densidades.

El sistema Android te ayuda a que tu app consiga independencia de densidad en dos maneras:

  • El sistema escala las unidades dp de forma apropiada para la actual densidad de pantalla
  • El sistema escala recursos drawable para el tamaño apropiado, basandose en la densidad actual de pantalla, si es necesario.

En la figura 2, el text view y el bitmap (recurso drawable) tienen dimensiones especificadas en pixeles (unidades px), de forma que las formas son físicamente más grandes en pantallas con densidades bajas y más pequeñas en pantallas con densidades altas. Esto  es porque , aunque los tamaños de las pantallas son las mismas, la densidad alta tiene más pixeles por pulgada (o dicho de otro modo el mismo número de pixeles caben en un área más pequeña).En la figura 3,  las dimensiones del layout son especificadas en unidades dp. Debido a que la configuración base de los pixeles independientes de densidad es para una pantalla de densidad media (medium), el dispositivo que tenga una pantalla de densidad medium aparece el mismo que en la figura 2. Y en las pantallas de baja y de alta densidad, sin embargo, el sistema escala el valor de pixeles independiente de la densidad arriba o abajo, respectivamente , para ajustarse a la pantalla apropiada.

En la mayoria de los casos, puedes asegurar independencia de densidad en tu app simplemente especificando todas las dimensiones de layout con unidades dp o con “wrap_content”, según sea el caso.El sistema entonces escala los bitmap drawables para mostrarlos en el tamaño apropiado, basandose en el factor de escalado apropiado para la densidad actual de la pantalla.

Sin embargo, el escalado de los bitmap puede resultar en bitmaps borrosos o pixelados. Para eliminar estos accidentes, lo mejor es proporcionar recursos bitmap alternativos para distintas densidades. Por ejemplo, debes proporcionar bitmaps de alta resolución para pantallas de densidades altas y el sistema utilizará éstas en vez de cambiar el tamaño del bitmap diseñado para pantallas de densidad media.

En la siguiente sección describimos más sobre cómo proporcionar recursos alternativos para distintas configuraciones de pantalla.

Cómo soportar multiples pantallas

La fundación del soporte de Android para múltiples pantallas tiene como objetivo que el renderizado del layout de la aplicación y de los bitmaps sea apropiado para la configuración de pantalla que toque. El sistema se encarga de la mayoria del trabajo escalando los layouts al tamaño/densidad de la pantalla y escalando los bitmaps a la densidad de la pantalla que se tiene. Pero para que que tu app sea optima en las distintas configuraciones de pantalla además debemos tener en cuenta:

  • Declarar explicitamente en el manifest qué tamaños de pantalla soporta nuestra app.By declaring which screen sizes your application supports, you can ensure that only devices with the screens you support can download your application. Declaring support for different screen sizes can also affect how the system draws your application on larger screens—specifically, whether your application runs in screen compatibility mode.To declare the screen sizes your application supports, you should include the <supports-screens> element in your manifest file.
  • Proporcionar distintos layouts para distintos tamaños de pantallas.By default, Android resizes your application layout to fit the current device screen. In most cases, this works fine. In other cases, your UI might not look as good and might need adjustments for different screen sizes. For example, on a larger screen, you might want to adjust the position and size of some elements to take advantage of the additional screen space, or on a smaller screen, you might need to adjust sizes so that everything can fit on the screen.The configuration qualifiers you can use to provide size-specific resources are smallnormallarge, and xlarge. For example, layouts for an extra large screen should go inlayout-xlarge/.Beginning with Android 3.2 (API level 13), the above size groups are deprecated and you should instead use the sw<N>dp configuration qualifier to define the smallest available width required by your layout resources. For example, if your multi-pane tablet layout requires at least 600dp of screen width, you should place it in layout-sw600dp/. Using the new techniques for declaring layout resources is discussed further in the section about Declaring Tablet Layouts for Android 3.2.
  • Proporcionar bitmaps a distintos tamaños para distintas densidades de pantalla.By default, Android scales your bitmap drawables (.png.jpg, and .gif files) and Nine-Patch drawables (.9.png files) so that they render at the appropriate physical size on each device. For example, if your application provides bitmap drawables only for the baseline, medium screen density (mdpi), then the system scales them up when on a high-density screen, and scales them down when on a low-density screen. This scaling can cause artifacts in the bitmaps. To ensure your bitmaps look their best, you should include alternative versions at different resolutions for different screen densities.The configuration qualifiers you can use for density-specific resources are ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high). For example, bitmaps for high-density screens should go in drawable-hdpi/.

The size and density configuration qualifiers correspond to the generalized sizes and densities described in Range of screens supported, above.

Note: If you’re not familiar with configuration qualifiers and how the system uses them to apply alternative resources, read Providing Alternative Resources for more information.

At runtime, the system ensures the best possible display on the current screen with the following procedure for any given resource:

  1. The system uses the appropriate alternative resourceBased on the size and density of the current screen, the system uses any size- and density-specific resource provided in your application. For example, if the device has a high-density screen and the application requests a drawable resource, the system looks for a drawable resource directory that best matches the device configuration. Depending on the other alternative resources available, a resource directory with the hdpi qualifier (such as drawable-hdpi/) might be the best match, so the system uses the drawable resource from this directory.
  2. If no matching resource is available, the system uses the default resource and scales it up or down as needed to match the current screen size and densityThe “default” resources are those that are not tagged with a configuration qualifier. For example, the resources in drawable/ are the default drawable resources. The system assumes that default resources are designed for the baseline screen size and density, which is a normal screen size and a medium density. As such, the system scales default density resources up for high-density screens and down for low-density screens, as appropriate.However, when the system is looking for a density-specific resource and does not find it in the density-specific directory, it won’t always use the default resources. The system may instead use one of the other density-specific resources in order to provide better results when scaling. For example, when looking for a low-density resource and it is not available, the system prefers to scale-down the high-density version of the resource, because the system can easily scale a high-density resource down to low-density by a factor of 0.5, with fewer artifacts, compared to scaling a medium-density resource by a factor of 0.75.

For more information about how Android selects alternative resources by matching configuration qualifiers to the device configuration, read How Android Finds the Best-matching Resource.

Utilizar cualificadores de configuración

Android supports several configuration qualifiers that allow you to control how the system selects your alternative resources based on the characteristics of the current device screen. A configuration qualifier is a string that you can append to a resource directory in your Android project and specifies the configuration for which the resources inside are designed.

To use a configuration qualifier:

  1. Create a new directory in your project’s res/ directory and name it using the format: <resources_name>-<qualifier>
    • <resources_name> is the standard resource name (such as drawable or layout).
    • <qualifier> is a configuration qualifier from table 1, below, specifying the screen configuration for which these resources are to be used (such as hdpi or xlarge).

    You can use more than one <qualifier> at a time—simply separate each qualifier with a dash.

  2. Save the appropriate configuration-specific resources in this new directory. The resource files must be named exactly the same as the default resource files.

For example, xlarge is a configuration qualifier for extra large screens. When you append this string to a resource directory name (such as layout-xlarge), it indicates to the system that these resources are to be used on devices that have an extra large screen.

Table 1. Configuration qualifiers that allow you to provide special resources for different screen configurations.

Screen characteristic Qualifier Description
Size small Resources for small size screens.
normal Resources for normal size screens. (This is the baseline size.)
large Resources for large size screens.
xlarge Resources for extra large size screens.
Density ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
nodpi Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen’s density.
tvdpi Resources for screens somewhere between mdpi and hdpi; approximately 213dpi. This is not considered a “primary” density group. It is mostly intended for televisions and most apps shouldn’t need it—providing mdpi and hdpi resources is sufficient for most apps and the system will scale them as appropriate. If you find it necessary to provide tvdpi resources, you should size them at a factor of 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi.
Orientation land Resources for screens in the landscape orientation (wide aspect ratio).
port Resources for screens in the portrait orientation (tall aspect ratio).
Aspect ratio long Resources for screens that have a significantly taller or wider aspect ratio (when in portrait or landscape orientation, respectively) than the baseline screen configuration.
notlong Resources for use screens that have an aspect ratio that is similar to the baseline screen configuration.

Note: If you’re developing your application for Android 3.2 and higher, see the section about Declaring Tablet Layouts for Android 3.2 for information about new configuration qualifiers that you should use when declaring layout resources for specific screen sizes (instead of using the size qualifiers in table 1).

For more information about how these qualifiers roughly correspond to real screen sizes and densities, see Range of Screens Supported, earlier in this document.

For example, the following is a list of resource directories in an application that provides different layout designs for different screen sizes and different bitmap drawables for medium, high, and extra high density screens.

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size
res/layout-large/my_layout.xml       // layout for large screen size
res/layout-xlarge/my_layout.xml      // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

res/drawable-mdpi/my_icon.png        // bitmap for medium density
res/drawable-hdpi/my_icon.png        // bitmap for high density
res/drawable-xhdpi/my_icon.png       // bitmap for extra high density

For more information about how to use alternative resources and a complete list of configuration qualifiers (not just for screen configurations), see Providing Alternative Resources.

Be aware that, when the Android system picks which resources to use at runtime, it uses certain logic to determing the “best matching” resources. That is, the qualifiers you use don’t have to exactly match the current screen configuration in all cases in order for the system to use them. Specifically, when selecting resources based on the size qualifiers, the system will use resources designed for a screen smaller than the current screen if there are no resources that better match (for example, a large-size screen will use normal-size screen resources if necessary). However, if the only available resources are larger than the current screen, the system will not use them and your application will crash if no other resources match the device configuration (for example, if all layout resources are tagged with the xlarge qualifier, but the device is a normal-size screen). For more information about how the system selects resources, read How Android Finds the Best-matching Resource.

Tip: If you have some drawable resources that the system should never scale (perhaps because you perform some adjustments to the image yourself at runtime), you should place them in a directory with the nodpi configuration qualifier. Resources with this qualifier are considered density-agnostic and the system will not scale them.

Diseñando layouts y recursos drawables alternativos

Los tipos de recursos alternativos que debes crear depende de las necesidades de tu app. Generalmente, debes utilizar los cualificadores del tamaño y orientación para proporcionar layouts y bitmaps alternativos.

Las siguientes secciones recumen como querrias utilizar los cualificadores de tamaño y densidad para proporcionar layouts y bitmaps alternativos.

Layouts alternativos

Generalmente, tú sabrás si necesitas layouts alternativos para distintos tamaños de pantalla una vez que pruebas tu app en diferentes configuraciones de pantalla. Por ejemplo:

  • Cuando probamos en un pantalla small, puedes descubrir que tu layout no cabe en la pantalla. Por ejemplo, una fila de botones puede no caber a la anchura de la pantalla en una pequela. En este caso debes proporcionar un layout alternativo para pequeñas pantallas que se ajuste al tamaño y posición de los botones.
  • Cuando se prueba en una pantalla extra large , puedes ver que no se hace un eficiente uso del gran espacio que tienes en pantalla. En este caso hacemos un layout alternativo para extra large screens that provides a redesigned UI that is optimized for bigger screens such as tablets.Although your application should work fine without an alternative layout on big screens, it’s quite important to users that your application looks as though it’s designed specifically for their devices. If the UI is obviously stretched, users are more likely to be unsatisfied with the application experience.
  • Y, cuando se prueba en el cambio de orientación landscape-portrait. te puede pasar que los elementos del interfaz colocados al fondo de la pantalla en la orientación portrait deberian estar a la derecha en modo landscape.

Para resumir , cuando haces el layout debes asegurarte que:

  • Cabe en pantallas pequeñas
  • Está optimizado para pantallas grandes que aprovechan bien el espacio adicional.
  • Está optimizado para las orientaciones landscape y portrait.

Si tu interfaz utiliza bitmaps que necesitan ajustarse al tamaño de la vista incluso después de que el sistema escala el layout (como por ejemplo una imagen de fondo en un boton), entonces debes utilizar lo que se llaman Nine-Patch bitmap files. Los ficheros de este tipo son básicamente PNGs en los cuales especificamos un region de dos dimensiones que es estrechable. Asi cuando el sistema escala la vista donde esta este tipo de bitmaps, el sistema estrechará el Nine-Patch bitmap, pero solo en la región especificada.Por tanto , no necesitas proporcionar distintos drawables para distintos tamaños de pantalla, porque el Nine-Patch bitmap se puede ajustar a cualquier tamaño. De bes , sin embargo, proporcionar distintas versiones de Nine-Patch bitmaps en el caso de diferentes densidades.

Recursos Drawables alternativos

Figure 4. Tamaños relativos de los bitmaps drawables en las densidades generalizadas

Casi todas las aplicaciones deben tener recursos bitmap alternativos para distintas densidades de pantalla, porque casi todas las apps tienen un launcher icon y ese icono debe verse bien en todas las densidades.

Nota:Solo necesita proporcionar recursos gráficos especificos para ficheros bitmap (.png.jpg, or .gif) y ficheros Nine-Path (.9.png).Si utilizas ficheros XML para definir formas , colores u otros recursos drawables, basta con una copia en drawable/.

Para crear recursos drawable alternativos para distintas densidades, debes seguir  el 3:4:6:8 scaling ratio que hay entre las cuatro densidades generalizadas. Por ejemplo, si tienes un bitmap de 48×48 pixeles en pantallas de densidad medium (el tamaño del launcher icon), todos los diferentes tamaños deben ser:

  • 36×36 para low-density
  • 48×48 para medium-density
  • 72×72 para high-density
  • 96×96 para extra high-density

Para más información sobre el diseño de iconos, ver las Icon Design Guidelines, que incluye información de tamaño para varios bitmap dibujables, tales como ic0nos launcher, iconos de menu, iconos de barra de estado, tab icons y más

Declaring Tablet Layouts for Android 3.2

-TODO-

Mejores prácticas

El objetivo de soportar múltiples tipos de pantallas es crear una aplicación que pueda funcionar bien y tener buen aspecto en todas las configuraciones de pantalla generalizadas soportadas por Android. Las secciones prévias de este documento proporcionan información sobre como Android adapta tu app a las configuraciones de pantalla y como personalizar el aspecto de tu app en distintas configuraciones de pantalla. Esta sección proporciona trucos adicionales y técnicas que te ayudan a asegurar que tu app escala bien para los distintos tipos de pantalla.

Aqui vemos una rápida lista sobre como asegurar que tu app muestra las pantallas bien en distintos tipos de pantallas:

  1. Utiliza wrap_contentfill_parent, o unidades dp cuando vayas a especificar dimensiones en un fichero XML.
  2. No utilices valores “a capon” en valores de pixeles en el código de tu app
  3. No utilices AbsoluteLayout (esta deprecado)
  4. Proporciona recursos drawable alternativos para distintas densidades de pantalla

En las siguientes secciones proporcionaremos más detalles.

1.Utilizar wrap_content, fill_parent, o las unidades dp para los dimensiones de los layout

Cuando definimos los valores de android:layout_width y de android:layout_height en las Views definidas en los layout XML, utilizar  "wrap_content""fill_parent" o las unidades dp units te garantiza que la vista adquirirá un tamaño apropiado según la configuración de pantalla que le toque.

Por ejemplo, una view con  layout_width="100dp" mide 100 pixeles en una pantalla de densidad media y el sistema escala a 150 pixeles en pantallas de densidad alta, de forma que la view ocupa aproximadamente el mismo espacio físico en la pantalla.

Similarmente, debes preferir las unidades sp (scale-independent pixel) para definir los tamaños de los textos. El factor de escala sp depende de la configuración del usuario y el sistema escala el tamaño de la misma forma que lo hace con los dp.

2. No utilices valores de pixeles a capón en el código de tu app

Por razones de rendimiento y para mantener el código más simple, el sistema Android utiliza pixeles como la unidad estandar para expresar dimensiones y valores de coordenadas. Esto significa que las dimensiones de una view están siempre expresadas en el código utilizando píxeles, aunque siempre basados en la densidad de pantalla actual. Por ejemplo si myView.getWidth() retorna 10, el view es de 10 pixeles de ancho en la pantalla actual, pero en un dispositivo con una densidad de pantalla más alta, el valor retornado podría ser de 15. Si utilizas valores de píxeles en el código de tu app para trabajar con bitmaps que no están pre-escalados para la densidad de pantalla actual, puede que necesites escalar los valores de pixeles que usas en tu código para que se corresponda con un bitmap no  escalado.

Si tu app manipula bitmaps o trata con valores de pixeles en tiempo de ejecución, ver la sección Additional Density Considerations.

3. No utilices AbsoluteLayout

A diferencia de otros patrones de layout,  AbsoluteLayout te obliga a utilizar posiciones fijas para colocar los elementos de la view, lo cual puede fácilmente dirigir a interfaces de usuario que no funcionar en pantallas diferentes. Es por ello que este sistema de layout fue deprecado en  Android 1.5 (API Level 3).

Debes en su vez utilizar  RelativeLayout, que utiliza posicionamiento relativo para colocar los elementos de la view. Por ejemplo,  puedes especificar que un widget de botón debe aparecer a la derecha de un elemento de texto.

4. Utiliza recursos personalizados por tamaño-densidad

Aunque el sistema escala tu layout y recursos drawable basandose en la configuración actual de pantalla, tu puedes querar hacer ajustes del UI en distintos tamaños de pantallas y proporcionar bitmap drawables optimizados para diversas densidades.

If you need to control exactly how your application will look on various screen configurations, adjust your layouts and bitmap drawables in configuration-specific resource directories. For example, consider an icon that you want to display on medium and high density screens. Simply create your icon at two different sizes (for instance 100×100 for medium density and 150×150 for high density) and put the two variations in the appropriate directories, using the proper qualifiers:

res/drawable-mdpi/icon.png   //for medium-density screens
res/drawable-hdpi/icon.png   //for high-density screens

Note: If a density qualifier is not defined in a directory name, the system assumes that the resources in that directory are designed for the baseline medium density and will scale for other densities as appropriate.

For more information about valid configuration qualifiers, see Using configuration qualifiers, earlier in this document.

Additional Density Considerations

This section describes more about how Android performs scaling for bitmap drawables on different screen densities and how you can further control how bitmaps are drawn on different densities. The information in this section shouldn’t be important to most applications, unless you have encountered problems in your application when running on different screen densities or your application manipulates graphics.

To better understand how you can support multiple densities when manipulating graphics at runtime, you should understand that the system helps ensure the proper scale for bitmaps in the following ways:

  1. Pre-scaling of resources (such as bitmap drawables) Based on the density of the current screen, the system uses any size- or density-specific resources from your application and displays them without scaling. If resources are not available in the correct density, the system loads the default resources and scales them up or down as needed to match the current screen’s density. The system assumes that default resources (those from a directory without configuration qualifiers) are designed for the baseline screen density (mdpi), unless they are loaded from a density-specific resource directory. Pre-scaling is, thus, what the system does when resizing a bitmap to the appropriate size for the current screen density.If you request the dimensions of a pre-scaled resource, the system returns values representing the dimensions after scaling. For example, a bitmap designed at 50×50 pixels for an mdpi screen is scaled to 75×75 pixels on an hdpi screen (if there is no alternative resource for hdpi) and the system reports the size as such.There are some situations in which you might not want Android to pre-scale a resource. The easiest way to avoid pre-scaling is to put the resource in a resource directory with thenodpi configuration qualifier. For example:
    res/drawable-nodpi/icon.png

    When the system uses the icon.png bitmap from this folder, it does not scale it based on the current device density.

  2. Auto-scaling of pixel dimensions and coordinates An application can disable pre-scaling by setting android:anyDensity to "false" in the manifest or programmatically for a Bitmap by setting inScaled to "false". In this case, the system auto-scales any absolute pixel coordinates and pixel dimension values at draw time. It does this to ensure that pixel-defined screen elements are still displayed at approximately the same physical size as they would be at the baseline screen density (mdpi). The system handles this scaling transparently to the application and reports the scaled pixel dimensions to the application, rather than physical pixel dimensions.For instance, suppose a device has a WVGA high-density screen, which is 480×800 and about the same size as a traditional HVGA screen, but it’s running an application that has disabled pre-scaling. In this case, the system will “lie” to the application when it queries for screen dimensions, and report 320×533 (the approximate mdpi translation for the screen density). Then, when the application does drawing operations, such as invalidating the rectangle from (10,10) to (100, 100), the system transforms the coordinates by scaling them the appropriate amount, and actually invalidate the region (15,15) to (150, 150). This discrepancy may cause unexpected behavior if your application directly manipulates the scaled bitmap, but this is considered a reasonable trade-off to keep the performance of applications as good as possible. If you encounter this situation, read the following section aboutConverting dp units to pixel units.Usually, you should not disable pre-scaling. The best way to support multiple screens is to follow the basic techniques described above in How to Support Multiple Screens.

If your application manipulates bitmaps or directly interacts with pixels on the screen in some other way, you might need to take additional steps to support different screen densities. For example, if you respond to touch gestures by counting the number of pixels that a finger crosses, you need to use the appropriate density-independent pixel values, instead of actual pixels.

Scaling Bitmap objects created at runtime

Figure 5. Comparison of pre-scaled and auto-scaled bitmaps, from ApiDemos.

If your application creates an in-memory bitmap (a Bitmap object), the system assumes that the bitmap is designed for the baseline medium-density screen, by default, and auto-scales the bitmap at draw time. The system applies “auto-scaling” to aBitmap when the bitmap has unspecified density properties. If you don’t properly account for the current device’s screen density and specify the bitmap’s density properties, the auto-scaling can result in scaling artifacts the same as when you don’t provide alternative resources.

To control whether a Bitmap created at runtime is scaled or not, you can specify the density of the bitmap withsetDensity(), passing a density constant from DisplayMetrics, such as DENSITY_HIGH or DENSITY_LOW.

If you’re creating a Bitmap using BitmapFactory, such as from a file or a stream, you can useBitmapFactory.Options to define properties of the bitmap as it already exists, which determine if or how the system will scale it. For example, you can use the inDensity field to define the density for which the bitmap is designed and theinScaled field to specify whether the bitmap should scale to match the current device’s screen density.

If you set the inScaled field to false, then you disable any pre-scaling that the system may apply to the bitmap and the system will then auto-scale it at draw time. Using auto-scaling instead of pre-scaling can be more CPU expensive, but uses less memory.

Figure 5 demonstrates the results of the pre-scale and auto-scale mechanisms when loading low (120), medium (160) and high (240) density bitmaps on a high-density screen. The differences are subtle, because all of the bitmaps are being scaled to match the current screen density, however the scaled bitmaps have slightly different appearances depending on whether they are pre-scaled or auto-scaled at draw time. You can find the source code for this sample application, which demonstrates using pre-scaled and auto-scaled bitmaps, in ApiDemos.

Note: In Android 3.0 and above, there should be no perceivable difference between pre-scaled and auto-scaled bitmaps, due to improvements in the graphics framework.

Converting dp units to pixel units

In some cases, you will need to express dimensions in dp and then convert them to pixels. Imagine an application in which a scroll or fling gesture is recognized after the user’s finger has moved by at least 16 pixels. On a baseline screen, a user’s must move by 16 pixels / 160 dpi, which equals 1/10th of an inch (or 2.5 mm) before the gesture is recognized. On a device with a high density display (240dpi), the user’s must move by 16 pixels / 240 dpi, which equals 1/15th of an inch (or 1.7 mm). The distance is much shorter and the application thus appears more sensitive to the user.

To fix this issue, the gesture threshold must be expressed in code in dp and then converted to actual pixels. For example:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

The DisplayMetrics.density field specifies the scale factor you must use to convert dp units to pixels, according to the current screen density. On a medium-density screen,DisplayMetrics.density equals 1.0; on a high-density screen it equals 1.5; on an extra high-density screen, it equals 2.0; and on a low-density screen, it equals 0.75. This figure is the factor by which you should multiply the dp units on order to get the actual pixel count for the current screen. (Then add 0.5f to round the figure up to the nearest whole number, when converting to an integer.) For more information, refer to the DisplayMetrics class.

However, instead of defining an arbitrary threshold for this kind of event, you should use pre-scaled configuration values that are available from ViewConfiguration.

Using pre-scaled configuration values

You can use the ViewConfiguration class to access common distances, speeds, and times used by the Android system. For instance, the distance in pixels used by the framework as the scroll threshold can be obtained with getScaledTouchSlop():

private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

Methods in ViewConfiguration starting with the getScaled prefix are guaranteed to return a value in pixels that will display properly regardless of the current screen density.

Cómo probar tu aplicación en pantallas diferentes

Figure 6. Varias tipos de dispositivos A set of AVDs for testing screens support.

Antes de publicar tu app, debes probarla en todas las densidades y tamaños de pantallas soportados. El Android SDK incluye varios skins de emuladores que puedes usar, que replican los tamaños y densidades de las configuraciones de pantalla comunes en las cuales tu app va a ejecutarse. Puedes modificar el tamño por defecto, densidad, y la resolución de las skins de los emuladores para replicar las caracteristicas de cualquier pantalla especifica.

To set up an environment for testing your application’s screen support, you should create a series of AVDs (Android Virtual Devices), using emulator skins and screen configurations that emulate the screen sizes and densities you want your application to support. To do so, you can use the AVD Manager to create the AVDs and launch them with a graphical interface.

To launch the Android SDK Manager, execute the SDK Manager.exe from your Android SDK directory (on Windows only) or execute android from the <sdk>/tools/ directory (on all platforms). Figure 6 shows the AVD Manager with a selection of AVDs, for testing various screen configurations.

Table 3 shows the various emulator skins that are available in the Android SDK, which you can use to emulate some of the most common screen configurations.

For more information about creating and using AVDs to test your application, see Managing AVDs with AVD Manager.

Table 3. Various screen configurations available from emulator skins in the Android SDK (indicated in bold) and other representative resolutions.

Low density (120), ldpi Medium density (160), mdpi High density (240), hdpi Extra high density (320), xhdpi
Small screen QVGA (240×320) 480×640
Normal screen WQVGA400 (240×400)
WQVGA432 (240×432)
HVGA (320×480) WVGA800 (480×800)
WVGA854 (480×854)
600×1024
640×960
Large screen WVGA800** (480×800)
WVGA854** (480×854)
WVGA800* (480×800)
WVGA854* (480×854)
600×1024
Extra Large screen 1024×600 WXGA (1280×800)
1024×768
1280×768
1536×1152
1920×1152
1920×1200
2048×1536
2560×1536
2560×1600
* To emulate this configuration, specify a custom density of 160 when creating an AVD that uses a WVGA800 or WVGA854 skin.
** To emulate this configuration, specify a custom density of 120 when creating an AVD that uses a WVGA800 or WVGA854 skin.
† This skin is available with the Android 3.0 platform

To see the relative numbers of active devices that support any given screen configuration, see the Screen Sizes and Densities dashboard.

Figure 7. Size and density options you can set, when starting an AVD from the AVD Manager.

We also recommend that you test your application in an emulator that is set up to run at a physical size that closely matches an actual device. This makes it a lot easier to compare the results at various sizes and densities. To do so you need to know the approximate density, in dpi, of your computer monitor (for instance, a 30″ Dell monitor has a density of about 96 dpi). When you launch an AVD from the AVD Manager, you can specify the screen size for the emulator and your monitor dpi in the Launch Options, as shown in figure 7.

If you would like to test your application on a screen that uses a resolution or density not supported by the built-in skins, you can create an AVD that uses a custom resolution or density. When creating the AVD from the AVD Manager, specify the Resolution, instead of selecting a Built-in Skin.

If you are launching your AVD from the command line, you can specify the scale for the emulator with the -scale option. For example:

emulator -avd <avd_name> -scale 96dpi

To refine the size of the emulator, you can instead pass the -scale option a number between 0.1 and 3 that represents the desired scaling factor.

For more information about creating AVDs from the command line, see Managing AVDs from the Command Line

Android: Guia de diseño de Widgets de App

Los widgets de las apps (usualmente llamados solo “widgets”) son una característica introducida con Android 1.5 y mejorada en las versiones 3.0 y 3.1. Un widget puede mostrar información reducida procedente de una aplicación en el pantalla principal del usuario. El sistema standard de Android incluye varios widgets, incluyendo un widget para el reloj, la reproducción de música en ese momento y otras aplicaciones.

Example app widgets in Android 4.0

Figure 1. Example app widgets in Android 4.0.

This document describes how to design a widget so that it fits graphically with other widgets and with the other elements of the Android Home screen such as launcher icons and shortcuts. It also describes some standards for widget artwork and some widget graphics tips and tricks.

 

For information about developing widgets, see the App Widgets section of the Developer’s Guide.

Standard Widget Anatomy

Typical Android app widgets have three main components: A bounding box, a frame, and the widget’s graphical controls and other elements. App widgets can contain a subset of the View widgets in Android; supported controls include text labels, buttons, and images. For a full list of available Views, see the Creating the App Widget Layout section in the Developer’s Guide. Well-designed widgets leave some margins between the edges of the bounding box and the frame, and padding between the inner edges of the frame and the widget’s controls.

Widgets generally have margins and padding between bounding box, frame, and controls

Figure 2. Widgets generally have margins between the bounding box and frame, and padding between the frame and widget controls.

Note: As of Android 4.0, app widgets are automatically given margins between the widget frame and the app widget’s bounding box to provide better alignment with other widgets and icons on the user’s home screen. To take advantage of this strongly recommended behavior, set your application’s targetSdkVersion to 14 or greater.

Widgets designed to fit visually with other widgets on the Home screen take cues from the other elements on the Home screen for alignment; they also use standard shading effects. All of these details are described in this document.

Determining a size for your widget

Each widget must define a minWidth and minHeight, indicating the minimum amount of space it should consume by default. When users add a widget to their Home screen, it will generally occupy more than the minimum width and height you specify. Android Home screens offer users a grid of available spaces into which they can place widgets and icons. This grid can vary by device; for example, many handsets offer a 4×4 grid, and tablets can offer a larger, 8×7 grid. When your widget is added, it will be stretched to occupy the minimum number of cells, horizontally and vertically, required to satisfy its minWidth and minHeight constraints. As we discuss in Designing Widget Layouts and Background Graphics below, using nine-patch backgrounds and flexible layouts for app widgets will allow your widget to gracefully adapt to the device’s Home screen grid and remain usable and aesthetically awesome.

While the width and height of a cell—as well as the amount of automatic margins applied to widgets—may vary across devices, you can use the table below to roughly estimate your widget’s minimum dimensions, given the desired number of occupied grid cells:

# of Cells
(Columns or Rows)
Available Size (dp)
(minWidth or minHeight)
1 40dp
2 110dp
3 180dp
4 250dp
n 70 × n − 30

It is a good practice to be conservative with minWidth and minHeight, specifying the minimum size that renders the widget in a good default state. For an example of how to provide aminWidth and minHeight, suppose you have a music player widget that shows the currently playing song artist and title (vertically stacked), a Play button, and a Next button:

An example music player widget

Figure 3. An example music player widget.

Your minimum height should be the height of your two TextViews for the artist and title, plus some text margins. Your minimum width should be the minimum usable widths of the Playand Next buttons, plus the minimum text width (say, the width of 10 characters), plus any horizontal text margins.

Example sizes and margins for minimum width/height calculations

Figure 4. Example sizes and margins for minWidth/minHeight calculations. We chose 144dp as an example good minimum width for the text labels.

Example calculations are below:

  • minWidth = 144dp + (2 × 8dp) + (2 × 56dp) = 272dp
  • minHeight = 48dp + (2 × 4dp) = 56dp

If there is any inherent content padding in your widget background nine-patch, you should add to minWidth and minHeight accordingly.

Resizable widgets

Widgets can be resized horizontally and/or vertically as of Android 3.1, meaning that minWidth and minHeight effectively become the default size for the widget. You can specify the minimum widget size using minResizeWidth and minResizeHeight; these values should specify the size below which the widget would be illegible or otherwise unusable.

This is generally a preferred feature for collection widgets such as those based on ListView or GridView.

Adding margins to your app widget

As previously mentioned, Android 4.0 will automatically add small, standard margins to each edge of widgets on the Home screen, for applications that specify a targetSdkVersionof 14 or greater. This helps to visually balance the Home screen, and thus we recommend that you do not add any extra margins outside of your app widget’s background shape in Android 4.0.

It’s easy to write a single layout that has custom margins applied for earlier versions of the platform, and has no extra margins for Android 4.0 and greater. See Adding Margins to App Widgets in the Developer’s Guide for information on how to achieve this with layout XML.

Designing Widget Layouts and Background Graphics

Most widgets will have a solid background rectangle or rounded rectangle shape. It is a best practice to define this shape using nine patches; one for each screen density (seeSupporting Multiple Screens for details). Nine-patches can be created with the draw9patch tool, or simply with a graphics editing program such as Adobe® Photoshop. This will allow the widget background shape to take up the entire available space. The nine-patch should be edge-to-edge with no transparent pixels providing extra margins, save for perhaps a few border pixels for subtle drop shadows or other subtle effects.

Note: Just like with controls in activities, you should ensure that interactive controls have distinct visual focused and pressed states using state list drawables.

Nine-patch border pixels

Figure 5. Nine-patch border pixels indicating stretchable regions and content padding.

Some app widgets, such as those using a StackView, have a transparent background. For this case, each individual item in the StackView should use a nine-patch background that is edge-to-edge with little or no border transparent pixels for margins.

For the contents of the widget, you should use flexible layouts such as RelativeLayoutLinearLayout, or FrameLayout. Just as your activity layouts must adapt to different physical screen sizes, widget layouts must adapt to different Home screen grid cell sizes.

Below is an example layout that a music widget showing text information and two buttons can use. It builds upon the previous discussion of adding margins depending on OS version. Note that the most robust and resilient way to add margins to the widget is to wrap the widget frame and contents in a padded FrameLayout.

<FrameLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:padding="@dimen/widget_margin">

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="@drawable/my_widget_background">

    <TextView
      android:id="@+id/song_info"
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:layout_weight="1" />

    <Button
      android:id="@+id/play_button"
      android:layout_width="@dimen/my_button_width"
      android:layout_height="match_parent" />

    <Button
      android:id="@+id/skip_button"
      android:layout_width="@dimen/my_button_width"
      android:layout_height="match_parent" />
  </LinearLayout>
</FrameLayout>

If you now take a look at the example music widget from the previous section, you can begin to use flexible layouts attributes like so:

Excerpt flexible layouts and attributes for an example music widget

Figure 6. Excerpt flexible layouts and attributes.

When a user adds the widget to their home screen, on an example Android 4.0 device where each grid cell is 80dp × 100dp in size and 8dp of margins are automatically applied on all sizes, the widget will be stretched, like so:

Music widget sitting on an example 80dp x 100dp grid with 8dp of automatic margins   added by the system

Figure 7. Music widget sitting on an example 80dp x 100dp grid with 8dp of automatic margins added by the system.

Using the App Widget Templates Pack

When starting to design a new widget, or updating an existing widget, it’s a good idea to first look at the widget design templates below. The downloadable package below includes nine-patch background graphics, XML, and source Adobe® Photoshop files for multiple screen densities, OS version widget styles, and widget colors. The template package also contains graphics useful for making your entire widget or parts of your widget (e.g. buttons) interactive.

Widget template excerpts

Figure 8. Excerpts from the App Widget Templates Pack (medium-density, dark, Android 4.0/previous styles, default/focused/pressed states).

You can obtain the latest App Widget Templates Pack archive using the link below:

Download the App Widget Templates Pack for Android 4.0 »