Menú Navegación Páginas

El blog de Antonio Leiva sobre diseño y desarrollo de interfaces en Android

Desmontando Bandhook (I): Foreground en cualquier Layout

Desmontando Bandhook (I): Foreground en cualquier Layout
  • Twitter
  • Facebook
  • Google Plus
  • LinkedIn

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.

Bandhook - Discover new music

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:

foreground android

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:

layout foreground

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

8 Comentarios

  1. Muchas Graciassss :-)

    • Un placer!

  2. Muy útil, llevo tiempo trabajando con Android pero nunca me había puesto a utilizar foreground. Impaciente al resto de artículos xD.

  3. Muchas gracias, el diseño se ve espectacular :)

  4. Me ha encantado. Claro y conciso. Voy a probarlo, gracias!!!

  5. Qué fácil! Gracias por el tutorial. Estamos esperando más entregas.

  6. Esta página está genial!!!!

  7. Y esto para que apareciese en dos columnas como en BandHook, habría que meterlo en un GridView ¿no?