III Semana del Emprendedor Tecnológico Rionegrino 2015

La semana que viene voy a estar en la III Semana del Emprendedor Tecnológico Rionegrino 2015 presentando un proyecto en el que venimos trabajando hace unos meses con mi primo y unos amigos.

Lo que más me divierte de este proyecto es que no es software, sino un producto tangible, que por una vez en la vida se lo puedo tirar por la cabeza a quién lo critique 🙂 (con los DVDs podía hacerlo pero si justo tienen algo de filo puede ser mortal y no es la idea).

Luego del encuentro la idea es publicar la experiencia en este tipo de eventos, comentar que cosas interesantes vimos y que será del futuro de este producto que estamos desarrollando.

Por el momento, solo les dejo un montón de incógnitas 😛

Anuncios

Mejorando el “Doble panel” en Android

Siguendo con la serie de casos en mejorar las interfaces en Android, esta vez le toca al doble panel que solemos ver en las aplicaciones cuando las usamos en una tablet. No voy a entrar en detalle de cómo implementar un doble panel con Fragments ya que en la web hay más que suficiente información para hacerlo.

De lo que si vamos a hablar es de cómo mejorar el aspecto y darle al usuario una mejor experiencia. Para lograr esto lo que vamos a hacer es copiar lo que hacen Google con sus aplicaciones, com Gmail o la misma aplicación de Contactos que viene en IceCream Sandwich y que se ve algo así :

ics_effects

El simple agregado de un gradiente a modo de “dropshadow” entre los paneles y el indicador de selección cambian radicalmente la experiencia de usuario, por más simple que parezca el cambio, pueden verlo al final del post donde dejo el antes y el después. Ahora bien, lo simple no siempre es fácil :), por lo que para lograr este efecto tuve que trabajar un poco. Empecemos por la sombra.

Existen varias formas de lograrla, desde las más simples como usar un FrameLayour con un bitmap como overlay hasta backgrounds complicados. Sin embargo se pueden obtener efectos raros en versiones nuevas de Android, ya que la ActionBar también tiene un dropshadow. Estas técnicas además pueden hacer complicado la segunda parte que es mostrar el selector.

La forma más prolija que encontré es meterse en el ciclo de render y aprovechar el método “dispatchDraw(Canvas canvas)”. Este método es el encargado de dibujar un View, por lo que si lo sobreescribimos podemos dibujar cosas antes o despues del render original (que lo llamaremos con “super.dispatchDraw(canvas)”). Como es un método protegido, lo que debemos hacer entonces es nuestra propia View, en este caso basta con hacer nuestra propia ListView :

;
public class ShadowListView extends ListView {
  public ShadowListView(Context context) {
    super(context);
  }

  private void prepareShadow() {
    // Load drawables and initialize stuff
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    // Draw the children
    super.dispatchDraw(canvas);

    if (!initializes)
      prepareShadow();

    drawShadow(canvas);
  }

  private void drawShadow(Canvas canvas) {
    canvas.save();
    canvas.translate(getWidth() - 20, 0);
    drawable.setBounds(0, 0, 20, getHeight());
    drawable.draw(canvas);
    canvas.restore();
  }
}

Lo siguientes es utilizarla en nuestro layout directamente en lugar de usar <ListView> usar <ShadowListView>. Con esto lo que hacemos es dibujar en el borde derecho, desde arriba hasta abajo con un ancho de “20” la sombra, haciendo parecer que el panel derecho está por arriba y que le hace “sombra” a la lista, cool :), no?.

Lo siguiente a lograr es dibujar el triángulo y queremos tener en cuanta varias cosas : debe estar dibujado por encima de la sombra (así el efecto queda bien) y debe coincidir en la posición del elemento seleccionado en la lista, si hay alguno.

El primer problema con el que me encontré es que quise utilizar “getSelectedView” para obtener la View seleccionada. Lamentablemente no pude entender por qué no funciona como parecería indicar el nombre :D. Por lo que fui por un camino diferente : como ya tengo mi clase de ListView, puedo sobreescribir otros métodos, como por ejemplo “performItemClick” para saber cuando un item fue “clickeado” (ya sea via touch o via teclado). Cuando eso pasa me guardo esa posición para futuro :

@Override
public boolean performItemClick(View view, int position, long id) {
  selectedPosition = position;
  return super.performItemClick(view, position, id);
}

Y luego puedo definir el método que dibuja la flecha :

private void drawArrow(Canvas canvas) {
  View selectedView = getChildAt(selectedPosition - getFirstVisiblePosition());
  if (selectedView != null) {
    selectedView.getDrawingRect(rect);

    offsetDescendantRectToMyCoords(selectedView, rect);

    int h = selectedView.getHeight();

    canvas.save();
    canvas.translate(getWidth() - h, rect.top);
    arrow.setBounds(0, 0, h, h);
    arrow.draw(canvas);
    canvas.restore();
  }
}

Lo primero que hago es ver que vista está seleccionada. Para eso, como ListView puede reutilizar un View para optimizar el render, debo tener en cuenta el View que se está mostrando. Si tengo una vista obtengo su recta de de dibujado. Esta recta está en coordenadas de la vista, por lo que tengo que trasladar esas coordenadas a mi espacio de coordenadas, y eso android me permite hacerlo fácil llamando a “offsetDescendantRectToMyCoords”.

Por último dibujo la flecha que es un PNG cuadrado que tiene la flecha con su propio dropshadow. El paso final es llamar a drawArrow despues de drawShadow en el dispatchDraw, de manera que si dibujo la flecha, esta se dibuja por arriba.

El resultado final, antes y después :

table_sin_efectos tablet_conf_efectos

Mejorando las UI en Android

En los últimos días me puse a ver varios de los videos de Google I/O del año pasado referidos al diseño de interfaces y diseño gráfico de android. La verdad es que con muy poco se puede cambiar el aspecto radicalmente, y la experiencia termina siendo muy superior (y si tenemos suerte podemos tener una mayor user base lo que significa más ingresos :D).

Para probar diferentes consejos decidí mejorar la interfaz de mi lector del diario Río Negro, el cual era bastante feo y se puede ver al final del post lado a lado con la imagen luego de mejorar el diseño.
La idea era resaltar un poco más los títulos y acomodar el layout. Lo primero que hice fue agregar “paddings”, de manera de descomprimir los diferentes elementos de la lista. Luego de un par de pruebas y error el valor de “10dp” fue el ganador.Una vez hecho eso tire los LinearLayout que usaba y converti a RelativeLayout lo que además hizo que quede más natural al rotar o usar la aplicación en otra resolución, ya que los “floats” se adapan mucho mejor una vez que uno entiende bien que opción va en cada caso :D.Lo último fue mejorar el render de la imagen. Como primer paso decidí cropear las imágenes a un tamaño único, para que tenga todo más sentido : da la sensación de uniformidad y distrae mucho menos si queremos ignorar las imágenes.El último punto fue hacer mas “fancy” la imagen poniéndole bordes redondeados. Para eso hice un custom View que cache la imagen usando una versión modificada de esta técnica.La imagen original y el resultado final a continuación :

Todavía no está subida a Google Play esta modificación pero lo estará en los próximos días. Mientras si pueden bajar la versión actual desde el market ;).


Get it on Google Play