Developing Frogtek

El blog del Departamento de Tecnología

Categoría: android (página 2 de 4)

Android y sus Layouts

Imaginad que al realizar una aplicación web compleja, en vez de hacerla para que se vea bien en todos los navegadores, la hacéis solo para una resolución de pantalla concreta y un navegador específico. Sería un infierno tener que repasarla entera, una vez acabada, para que se adapte a cualquier navegador y resolución, ¿verdad?.

Android Layout

Pues algo así nos pasó a nosotros, pero en Android. Parte de culpa tuvimos, he de reconocer, por no ser previsores y tirarnos por el camino fácil. Aunque diré en nuestra defensa que cuando se empezó nuestro producto Android estaba en pañales y no existía tanta tablet y teléfono en el cual ejecutar tu aplicación.

Aquí van pues una serie de recomendaciones. Para que no cometáis los mismos errores que nosotros.

  • Entended cómo funciona el tema de las pantallas en Android, no es lo mismo una densidad que otra, el tamaño de pantalla, etc.
  • No uséis la unidad de medida px. Mejor dp, o sp si son tamaños de texto.
  • Tened claro como elige Android los recursos que ponéis a su disponibilidad.
  • Evitad en toda medida posible usar layouts con medidas absolutas, hacedlos adaptables (fill_parent, wrap_content). Os ahorrareis muchos quebraderos de cabeza.
  • Si no podéis evitarlo y tenéis que usar valores en vuestros layouts. Extraedlos a un xml y definidlos como Dimensions. Así os será más fácil adaptar la aplicación a las distintas configuraciones que queráis soportar, pues con definir el archivo de dimensiones para cada modalidad de recursos os valdrá.
  • Usad el atributo android:drawableTop, android:drawableLeft…, para introducir imágenes en botones. No os pase como a nosotros que o pedíamos el fondo ya con la imagen o introducíamos un elemento adicional, recargando el layout.
  • No os dejéis enamorar por las bondades de los RelativeLayout. No son malos. Pero a veces un LinearLayout con sus pesos puede ser más fácilmente adaptado a varias pantallas.

Y nada más. Si se os ocurre alguna más que nosotros no hemos nombrado, compartidlo con todos!

 

Cambiar de entorno de programación

Es común encontrarse con equipos “Java”, “.Net” o “Cobol”, los cuales trabajan solo y para un entorno. Está claro que si te sientes cómodo programando en Java, te dará algo de respeto meterte a programar en .Net, o lo mismo el jefe no quiere que pierdas tu tiempo programando en Java, si ya lo haces bien en .Net.

“Es una pérdida de tiempo y el cliente quiere el proyecto para ayer”.

Como programador, valoro mucho el poder trabajar en diferentes entornos de desarrollo, por varios motivos:

  • A veces trabajar sobre una tecnología demasiado tiempo (en mi caso, Android) me ofusca sobremanera. Hacer alguna Historia de Usuario en Python me relaja y ayuda a recuperarme un poco de la ofuscación.
  • Sacarme de la comodidad habitual de un entorno muy conocido puede ayudar a la motivación, a pensar nuevas estrategias y nuevas formas de desarrollar. Llevando esta analogía al mundo friki… ¿Es lo mismo jugar con los Marines Espaciales que con los Eldar en el Warhammer 40.000? Seguro que no, cada uno tiene sus estrategias, sus ventajas e inconvenientes.
  • Aprender nuevas tecnologías. ¿Hay algo más hermoso para un developer?

– “Hala, venga, trabajad en Python,”

– “¡Pero si no tengo ni idea!”

Esto pasa, si no tienes ni idea de un lenguaje, como decía antes,  te da algo de respeto cambiarte. Es posible que la primera vez no seas 100% productivo (siéntete afortunado si lo eres un 20%)  y no hagas las cosas bien del todo, pero lo mismo la segunda ya lo haces mejor y a la tercera vez que te cambias ya lo dominas mucho más. Es recomendable que las primeras veces haya algún “experto” en la materia que pueda guiarte por esos momentos de incertidumbre y confusión.

“¿Qué carajo es jQuery?”

¿Merece la pena bajar un poco la productividad por que haya más gente que sepa un poco de todo? Si tienes en tu equipo a un hacker en Cobol y solo él sabe del proyecto… ¿Qué probabilidad hay de que se vaya todo al carajo si a este hacker se lo lleva un autobús por delante? Bueno, quien dice un autobús….  dice que se va de vacaciones y se jode algo del proyecto… o algo más dramático (pero no tanto como lo del bus), que se vaya a otra empresa. Reducir ese factor de riesgo es positivo para la empresa (para una empresa que se preocupe de sus proyectos, la calidad de los mismos y la salud mental de los developers).

“No estoy programando en Python, sino que estoy programando en Python como si fuera Java”

Esto pasa… Cuando no conoces un lenguaje, sueles agarrarte a lo que conoces, si conoces Java tenderás a desarrollar código Python como si fuese Java… Luego, cuando vayas cogiendo más experiencia, conociendo la API y la sintaxis te darás cuenta de la diferencia, del cambio de chip y de crear código Python en sintonía con Python (luego corres el riesgo de volver a Java y escribir código Java como si fuera Python….).

A pesar de las pequeñas incomodidades (que en el fondo deberían ser alicientes para romperse la cabeza), recomiendo cambiar de entorno de vez en cuando y siempre y cuando la empresa te lo permita, claro.

De hecho, estoy bastante cansado de Android… me voy a poner a hacer algo en Python.

PD. Donde pone “Python” en este artículo, cambiar por el lenguaje que os gustaría aprender/practicar. He personalizado el post a mi caso, podría haber puesto “.NET”… pero entonces no habría sido yo el que hubiese escrito el artículo. 😛

Botones en Android mediante programación

El pasado jueves 7 de abril, la troupe de Frogtek acudimos en comandita al taller organizado por el GTUG Zaragoza e impartido por Francho Joven. La convocatoria fue un éxito y salimos todos muy contentos con lo aprendido y orgullosos de la aplicación que desarrollamos y subimos al market de Android.

Una de las lecciones que vimos fue la de asignar formas (o shapes) creadas mediante programación a elementos como botones. Y yo pensé: ¿por qué no podemos hacer eso mismo con los botones de nuestra aplicación?

Como ejemplo, pongamos que tenemos que añadir un botón de “regresar” típico, que al ser pulsado, vuelva a la pantalla anterior.

Lo primero es conseguir un Button con fondo rojo. Para ello, creamos un layout con un shape (en un fichero shape_red_background.xml) dentro de la carpeta layouts, que nos definirá un tipo de fondo que podremos aplicar a elementos rojos de nuestra aplicación. Le incluiremos un degradado para que quede más molón.



	
	
	
	

Después, queremos asignarle este fondo a nuestro botón, pero como queremos hacerlo reutilizable, vamos a definirlo en un estilo. Para ello, nos creamos un archivo style.xml dentro de nuestra carpeta values (el nombre es lo de menos, lo importante es que esté en values) y añadimos lo siguiente:




Notad que el parámetro android:drawableLeft es para que aparezca una flechica a la izquierda de este botón. Y ahora solo queda añadir este botón a nuestro layout. Para ello basta con:

Bastante limpio, ¿no? Y lo mejor de todo es que si mañana nos piden el mismo botón, pero en color verde, como hemos utilizado herencia de estilos, con hacer un nuevo shape de color verde y crear su style es suficiente:


Pensad ahora la cantidad de espacio que podemos ahorrarnos en nuestras aplicaciones si sustituimos los archivos de imagen por formas creadas mediante programación…

EDIT: de momento, lo único que no he conseguido es darle sombra mediante programación. Existen parámetros shadow_color en Android, pero solo funcionan para elementos de tipo texto.

Tres días con Biko2

Hace tres semanas  volví muy contento y con muchas cosas que contar de mis tres días por tierras pamplonicas en compañía de mis colegas de biko2. Tras unas semanas caóticas me voy a relatar lo bien que me lo pasé.

Os dejo una preciosa foto del Moncayo que hice al ir por la autovía


Llegue a sus oficinas, después de que Jon me recogiera en la estación y lo primero que hicimos fue ver al gran equipo anteriormente conocido como “Equipo de Movilidad” ;). Iván, Miguel, Susana y Patricia, peazo equipo con el que he tenido la oportunidad de trabajar estos días. Yo iba con bastante miedo y pensando en si realmente podría atender las necesidades del equipo. Tras unos correos con Jon intentando organizar un poco, pensamos que sería mejor no organizar nada y hacerlo lo más ágil posible, así fue.

Los temas que tratar fueron saliendo fácilmente sobre la marcha. Por una lado el equipo tenia sus propias inquietudes y por otro fuimos estudiando las aplicaciones que ya habían desarrollado y viendo qué posibles temas mejorar. De este modo pudimos crear una agenda que hicimos open al resto de la empresa. Así cualquier empleado podría venir a las sesiones que le resultasen más interesantes. Salieron temas como testing, eficiencia, persistencia de datos… todo ello en torno a Android.

Por otro lado, con el equipo trabajamos las notificaciones push en Android, que para mí también era novedad. No fue fácil, al final y tras algunas horas conseguimos hacerlo funcionar. 😉

Mientras tanto, yo me intentaba empapar lo máximo posible de su metodología, acudí a algún stand-up meeting y me apunte muchas ideas/mejoras que luego conté al equipo de Frogtek en nuestra retrospectiva. Grandes conversaciones con Jon, Rubén, Mario… en las que aprendí mucho y también comí muy bien.

Y por supuesto, también nuestra pizarra con las tareas.

Al final de los tres días en biko también hicimos retrospectiva con Rubén e hicimos balance de los tres días. Como resultado negativo salieron todos los cabezazos que nos dimos con las notificaciones push… lo más importante es que al final lo conseguimos.

En resumen: confío mucho en este tipo de colaboraciones y me encantó no tener una agenda definida ni tener temas a tratar de antemano. Teníamos dos misiones : Aprender lo máximo y ayudar lo máximo. Creo que cumplimos con la misión.

Desde aquí mi agradecimiento al equipo de biko2 que me recibió extraordinariamente y me trato mejor aún. Esta semana tenemos a Rubén por frogtek, vamos a trabajar para que se lleve un buen recuerdo.

Hints en los EditText de Android

Esto va a ser un mini-post, pero me ha parecido interesante comentarlo ya que es algo de lo que hasta ahora, no me había dado cuenta.

Si estás programando en Android, seguramente te hayas encontrado con la siguiente situación:

Tienes un EditText vacío, que el usuario ha de completar, pero para darle más información sobre lo que debería ir en ese campo de texto, desearías poner un “hint”, una ayuda en forma de texto gris sobre el EditText.

Pero quieres que cuando se pinche sobre el campo editable, este texto desaparezca.

Se podría hacer todo por código, pero queda mucho más bonito y limpio un:

android:hint=”Introduzca Texto Aquí”

Simple y elegante.

Robolectric: TDD en Android

Llevábamos ya desde nuestros inicios buscando herramientas que nos permitieran practicar TDD para desarrollar las clases de nuestro proyectos en Android. El problema era que las Activity (clase fundamental de las aplicaciones Android) solo podían ser testeadas a través del propio entorno Android, nunca como clase independiente. Por lo tanto, los únicos tests que habíamos realizado sobre esas clases eran tests de integración, que podían tardar del orden de 4 minutos en ejecutarse por completo, lo que nos imposibilitaba el realizar un diseño guiado por tests.

Robolectric (http://pivotal.github.com/robolectric) es una herramienta que nos va a permitir lanzar tests unitarios en Android.

Su uso nos aporta varias ventajas:

  • Ejecuta tests en Android que duran segundos y no minutos, como en el caso de un Android jUnit test.
  • Su velocidad nos permite practicar TDD al crear clases en Android.
  • Podemos usar Mockito o PowerMock en conjunción con los tests de Robolectric.
  • Nos permite utilizar clases de librerías Android, como JSONObjects o JSONArrays, que en otros entornos no podríamos usar.

Como algunas clases de Android no tienen métodos para acceder al estado o las variables que contienen, la gente de Robolectric se ha sacado de la manga los Shadows (ShadowImageView, ShadowRelativeLayout, ShadowActivity, etc.), los cuales nos van a permitir realizar pruebas como esta:

@Test
public void testImagenEsCorrecta() throws Exception {
    ImageView imagenBanner = (ImageView) activity.findViewById(R.id.banner);
    ShadowImageView shadowBanner = Robolectric.shadowOf(imagenBanner);
    assertThat(shadowBanner.resourceId, equalTo(R.drawable.img_banner_grande));
}

Cómo configurar Robolectric para Eclipse:

Estos son los pasos básicos para configurar Robolectric en Eclipse. Recomiendo seguir el quick-start de la web oficial para más detalles:

  1. Crear una nueva carpeta en la raíz de nuestro proyecto que vamos a testear, llamada test.
  2. Crear un nuevo proyecto (u obtenerlo del SVN) llamada MyProjectTest.
  3. Queremos meter el código dentro de la carpeta test antes creada, así que en MyProjectTest haremos clic en propiedades y en Build Path/Source/Link Source seleccionaremos la carpeta test.
  4. Añadir al proyecto el .jar de Android.
  5. Añadir al proyecto el .jar de Robolectric (¡con dependencias!).
  6. Añadir una nueva run configuration en Run/Run configurations, de forma que elijamos Eclipse JUnit launcher y en la pestaña Arguments seleccionaremos Other/Workspace y elegiremos la carpeta raíz del proyecto que queremos testear.

Ejemplo de uso para testear una Activity:

@RunWith(RobolectricTestRunner.class)
public class MyActivityTest {
    private Activity activity;
    private Button pressMeButton;
    private TextView results;

    @Before
    public void setUp() throws Exception {
        activity = new MyActivity();
        activity.onCreate(null);
        pressMeButton = (Button) activity.findViewById(R.id.press_me_button);
        results = (TextView) activity.findViewById(R.id.results_text_view);
    }

    @Test
    public void shouldUpdateResultsWhenButtonIsClicked() throws Exception {
        pressMeButton.performClick();
        String resultsText = results.getText().toString();
        assertEquals("Testing Android Rocks!", resultsText);
    }
}

De momento, Robolectric es un proyecto joven (surgió en noviembre de 2010). Esperamos que esta herramienta mantenga una cierta continuidad, para que podamos obtener el máximo rendimiento a las prestaciones que nos ofrece.

Por ahora estamos experimentando las posibilidades que nos otorga, todavía nos queda por descubrir como crear nuestros propios objetos Cursor dentro de este entorno. Seguiremos informando…

Aquí huele a cuco (IV)

Bueno, un poco de autocrítica nunca viene mal y en este caso yo soy uno de los culpables de este desaguisado….

public int getVendorsCount() {
	if (this.mDm.openDBConnection()) {
		this.mDbHelper = new VendorsDbAdapter();
		Cursor cursor = this.mDbHelper.getVendorsCount();
		if (cursor != null) {
			cursor.close();
			return cursor.getCount();
		}
		this.mDm.closeDBConnection();
	}
	return 0;
}

Fijaos bien: estamos intentando acceder a un cursor después de cerrarlo….. además solo cerramos la base de datos si el cursor es null… vamos, una joya de código. Gracias a que tenemos test funcionales en Android hemos encontrado semejante esperpento. Ya vamos recuperando poco a poco lo invertido en ellos 🙂 .

Así he dejado el código después del pertinente refactor.

public int getVendorsCount() {
	int vendorsCount = 0;
	if (this.mDm.openDBConnection()) {
		this.mDbHelper = new VendorsDbAdapter();
		Cursor cursor = this.mDbHelper.getVendorsCount();
		if (cursor != null) {
			vendorsCount = cursor.getCount();
			cursor.close();
		}
		this.mDm.closeDBConnection();
	}
	return vendorsCount;
}

¿Bastante mejor no? ¿Alguna sugerencia para mejorarlo todavía más?

Efecto marquesina en Android

Cuando queremos mostrar un texto muy largo en una pequeña pantalla como la del móvil podemos crear un efecto de marquesina facilmente, podemos ponerlo a nivel de xml con esta propiedad.

android:ellipsize="marquee"

Sólo se activara cuando el objeto tenga el foco. Podemos forzarlo por código usando el método

 requestFocus() 

Al parecer no hace falta que el elemento tenga el foco para que active la marquesina, pero si debe tener el singleLine activado. Gracias a Maestro Linares por las correcciones.

Aquí la info oficial con el resto de valores.

Gracias a Gerardo sabemos algo más del comportamiento del efecto marquesina. Actualizo la entrada del post con sus comentario.

El TextView empezara a ser scrollable cuando tenga el foco y/o haya sido seteada como selected. Esto ultimo no puede hacerse desde el xml, por lo que sera necesario hacerlo desde el codigo.
El requestFocus puede funcionar, aunque es peligroso, ya que programaticamente estariamos dando el foco a ese objeto. Que sucede por ejemplo si queremos tener varios TextView con marquesina?.
Yo recomiendo hacerlo selected desde el codigo, por ejemplo en el onCreate:
mTextView.setSelected(true)

Y desde el xml indicar:

 android:singleLine=”true”
android:ellipsize=”marquee”

Si el TextView pertenece a un ListView este rotara el texto de forma automatica cuando el elemento tenga el foco.

¿Qué IDE usas?

Hoy en frogtek vamos a tener nuestra primera kata organizada por Jose. Ayer mientras nos enviaba información acerca de las webs que había visitado para prepararla, pensé en el IDE y de qué manera un developer se siente cómodo al usarlo.

Yo desde hace un tiempo llevo usando NetBeans para desarrollar en Android y GAE, me cansé de la inestabilidad y lentitud de Eclipse cuando tratas con varios proyectos grandes.

Esto también me hizo pensar acerca de la ayudas que un IDE proporciona a un programador, como por ejemplo:

  • Completar métodos.
  • Compilación inmediata.
  • Sugerencias de corrección de errores.

Todas estas ayudas que en principio están diseñadas para hacernos la vida más fácil y aumentar la rapidez de desarrollo, pueden convertirse en un lastre en cuanto a eficiencia se refiere y una frustración diaria. Todo esto relacionado con que debemos tender a “Go Mouseless”, para aumentar nuestra productividad, me hace pensar que cada día deberíamos bajar un escalón en la abstracción e intentar obviar las ayudas en busca de más rendimiento. También creo que estas ayudas a la larga hacen perder un poco la visión global de proyectos grandes.

Me gustaría saber cuáles son vuestros IDE’s mas usados y vuestras configuraciones.

Aquí huele a cuco (III)

Cuando entras en una empresa nueva, descubres partes del código en cierto modo inexplicables. Muchas de ellas las achacas a tu poca experiencia con los entresijos de las aplicaciones que acabas de conocer. Otras, en cambio…

public void makeAppCrash() {
	DataAccessManager.getDbHelper().execSQL("select * form mamamam");
}

De este fragmento se extraen varias dudas:

  • ¿Por qué queremos que en producción se rompa la aplicación?
  • ¿Qué llevó a alguien a escribir “mamamam“?
  • ¿Por qué pone “form” en vez de “from“?

Muchos de estos misterios seguirán sin tener una respuesta. Mientras tanto, el código todavía sigue intacto en busca de alguien que descubra sus más profundos secretos

Antiguas entradas Recientes entradas