Desmontando Bandhook (I): Foreground en cualquier Layout

Tras las salida de Bandhook en la Play Store, he recibido muchas preguntas sobre la forma de implementar algunas de las partes de la interfaz, por lo que he decidido crear una serie de artículos en los que explicaré paso a paso todo lo que me preguntéis al respecto. Como siempre tenéis todos los medios de contacto disponibles para lanzarme vuestras ideas.
Links: → Visit Store → Search Google
Objetivo
En esta ocasión, voy a explicar cómo conseguir aplicar un foreground a cualquier layout. En particular lo haremos con LinearLayout muy similar al de las tarjetas que aparecen por toda la aplicación:
Implementación
Lo primero que vamos a hacer es el código XML de la actividad que va a contener el layout al que queremos añadir el foreground. Algo así será suficiente:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_gravity="center" android:background="#FFFFFF" android:padding="10dp" > <ImageView android:layout_width="200dp" android:layout_height="200dp" android:layout_marginBottom="10dp" android:src="@drawable/cat" android:scaleType="centerCrop" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="Foreground"/> </LinearLayout>
El siguiente paso es crear el selector que permitirá el cambio de color cuando se pulse el elemento. El selector no es más que un drawable en el que se indica el aspecto del componente en función su estado. Hay unos cuantos estados, pero en este caso sólo necesitamos dos: normal y pulsado:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/holo_dark_green_semitransp" android:state_pressed="true"/> <item android:drawable="@android:color/transparent"/> </selector>
Ponemos el selector transparente en estado normal y un verde con algo de transparencia en el estado pulsado. Con esto podría ser suficiente. Si asignas este selector al background del LinearLayout, tendrás un efecto muy similar al que estamos buscando, sólo que aparecerá como fondo en lugar de estar por encima.
Pero no es eso lo que buscamos. Necesitamos asignarle la propiedad Foreground al layout. Sin embargo, el único layout que la tiene por defecto es el FrameLayout. Así que la forma más simple de conseguir el efecto buscado es rodear el anterior layout por un FrameLayout:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/selectableItem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:foreground="@drawable/foreground_selector" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#FFFFFF" android:padding="10dp"> <ImageView android:layout_width="200dp" android:layout_height="200dp" android:layout_marginBottom="10dp" android:src="@drawable/cat" android:scaleType="centerCrop" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="Foreground"/> </LinearLayout> </FrameLayout>
Y ahora sólo nos queda asignarle el onClick al FrameLayout. Si no lo haces, el selector no activará el estado pressed:
public class ForegroundLayoutActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_foreground); FrameLayout item = (FrameLayout) findViewById(R.id.selectableItem); item.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(ForegroundLayoutActivity.this, R.string.item_pressed, Toast.LENGTH_LONG).show(); } }); } }
Aquí tienes el resultado:
Puedes ver todo el código en Github y en breve podrás probar el ejemplo en la aplicación.
¿Te ha gustado? Compártelo
Muchas Graciassss
Un placer!
Muy útil, llevo tiempo trabajando con Android pero nunca me había puesto a utilizar foreground. Impaciente al resto de artículos xD.
Muchas gracias, el diseño se ve espectacular
Me ha encantado. Claro y conciso. Voy a probarlo, gracias!!!
Qué fácil! Gracias por el tutorial. Estamos esperando más entregas.
Esta página está genial!!!!
Y esto para que apareciese en dos columnas como en BandHook, habría que meterlo en un GridView ¿no?