Saludos internautas, Me tope con un requerimiento donde en una pantalla ocupaba mostrar diferentes items de manera horizontal. La idea es que el usuario pueda pasar entre esos items de manera similar al “Home” de Android, esto es, que usted pasa entre escritorios, haciendo “swap”. En Android, no existe tal widget que simule este comportamiento. Ni siquiera tenemos un ListView horizontal (así como lo oye, el ListView es solo vertical). Solamente ofrece algo llamado como ViewFlipper, pero ocupa que usted conozca de antemano la cantidad de items a desplegar (tanto así que por lo general se llena a nivel del archivo XML de layout). Luego vi al Gallery, que en esencia hace lo que ocupo, excepto por un detalle: Al hacer swap (scroll horizontal), si se hace muy “fuerte” puede que pasen más de un item. Cuando el item ocupa toda la pantalla (como en el caso del mi proyecto) ver varios items pasar horizontalmente no es una buena experiencia de usuario. El ViewFlipper fue mi primera opción, pero fue bastante dolorosa, ya que al ocupar conocer de antemano los items a desplegar, cuando se tienen datos dinámicos, tratar de “compensar” esto a nivel de código es una pesadilla. En nuestro caso usamos un ViewFlipper con solo 3 items. Al pasar a la derecha o izquierda, era necesario reacomodar todo internamente para que se llenaran los items de los lados de acuerdo a la nueva posición. Esto implica que uno es el que debe controlar los items, la posición, y hasta la animación al pasar de items. Otra gran desventaja, es que a diferencia de un ListView o un GridView, no tiene un adapter (y por eso ocupa saber que items va a contener desde el layout), por lo que se puede llegar a tener problemas de memoria. Al retomar la idea del Gallery, me encontré por ahí este post, que describe una manera para “modificar” el comportamiento del Gallery y hacer que sin importar la fuerza con la que se realice el scroll o swap, solo un se moverá al siguiente item. Dicha solución explica que simplemente hay que crear una clase en el proyecto, que herede de Gallery, y que sobreescriba el método onFling devolviendo false.

public class MyGallery extends Gallery{

  public MyGallery(Context context, AttributeSet attrs, int defStyle){
    super(context, attrs, defStyle);
  }

  public MyGallery(Context context, AttributeSet attrs){
    super(context, attrs);
  }

  public MyGallery(Context context){
    super(context);
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
      float velocityY){
    return true;
  }

}

Para que obtengamos el siguiente comportamiento: Fuentes:

  1. http://stackoverflow.com/questions/4968426/android-gallery-horrizontal-scroll-rate
  2. http://developer.android.com/reference/android/widget/Gallery.html