Programación Android, menú contextual (registerForContextMenu)

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0

En la publicación de la semana pasada hablamos sobre cómo crear y manejar menús en Android, pero existen también otro tipo de menús, el menú contextual. A diferencia del menú normal, el menú contextual se mostrará en función del elemento seleccionado de la pantalla, cuando, sobre éste elemento, se realice una pulsación larga.

Este tipo de menú nos ofrece, como veremos más adelante, la posibilidad de mostrar un menú específico para cada elemento al que hayamos registrado un menú.

Como siempre, vamos a realizar un sencillo ejemplo para que resulte más fácil entender cómo manejar este elemento. Esta vez vamos a crear una interfaz con 1 TextView y 2 botones, y cambiaremos el texto a mostrar en el TextView en función de si hacemos una pulsación normal sobre el botón, o si seleccionamos alguna de las opciones del menú contextual asignado a cada botón:

Activity RegisterForContextMenu
Activity

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".RegisterForContextMenu" >

    <TextView
        android:id="@+id/tvRegisterText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="@string/tvRegisterText" />

    <Button
        android:id="@+id/btCtxMenu1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/tvRegisterText"
        android:layout_marginTop="74dp"
        android:onClick="onClick"
        android:text="@string/btCtxMenu1" />

    <Button
        android:id="@+id/btCtxMenu2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/btCtxMenu1"
        android:layout_alignParentRight="true"
        android:onClick="onClick"
        android:text="@string/btCtxMenu2" />

</RelativeLayout>

Crear el menú contextual

Una vez hecho esto, vamos a crear dos menús diferentes, cada uno para uno de los botones de la pantalla, esto lo haremos igual que creamos los xml de los menús en la anterior publicación:

    • ctx_menu_button1.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/button1_menu_opt1" android:title="@string/buton1_menu_opt1"/>
    <item android:id="@+id/button1_menu_opt2" android:title="@string/buton1_menu_opt2"/>

</menu>
    • ctx_menu_button2.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/button2_menu_opt1" android:title="@string/buton2_menu_opt1"/>
    <item android:id="@+id/button2_menu_opt2" android:title="@string/buton2_menu_opt2"/>
    <item android:id="@+id/button2_menu_opt3" android:title="@string/buton2_menu_opt3"/>

</menu>

Registrar el elemento de la vista al menú contextual

Una vez que tenemos los archivos que representan cada menú contextual creados procederemos a registrar nuestros controles de la interfaz al menú contextual, para ello en el código Java de nuestra Activity tenemos que instanciar dos objetos de tipo Button, e inicializarlos asignando los botones de la interfaz gráfica. Después de esto utilizaremos el método registerForContextMenu(View view), y pasaremos como parámetro el control al que queremos asociar el menú contextual, en este caso los botones:

public class RegisterForContextMenu extends Activity {
	private Button btCtxMenu1, btCtxMenu2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.register_for_context_menu);

		btCtxMenu1 = (Button)findViewById(R.id.btCtxMenu1);
		btCtxMenu2 = (Button)findViewById(R.id.btCtxMenu2);

		registerForContextMenu(btCtxMenu1);

		registerForContextMenu(btCtxMenu2);
	}
}

Mostrar el menú contextual

Con esto habremos registrado nuestros controles para que muestren el menú contextual, sin embargo, todavía no hemos creado el código que debe seleccionar el menú y mostrarlo en pantalla. Para hacer esto debemos sobreescribir el método onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo), y dentro del método comprobaremos qué vista está llamando al método y así inflaremos el menú indicado:

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
		ContextMenuInfo menuInfo) {
	super.onCreateContextMenu(menu, v, menuInfo);
	// Creamos el objeto que debe inflar la vista del menú en la pantalla.
	MenuInflater inflater = new MenuInflater(this);

	switch (v.getId()) {
	case R.id.btCtxMenu1:
		// Se ha realizado pulsación larga sobre el botón 1.
		// Inflamos el menú pasando la referencia al menú que queremos
		// mostrar y el objeto ContextMenu que recibimos como parámetro.
		inflater.inflate(R.menu.ctx_menu_button1, menu);
		break;
	case R.id.btCtxMenu2:
		// Se ha realizado pulsación larga sobre el botón 2.
		// Inflamos el menú pasando la referencia al menú que queremos
		// mostrar y el objeto ContextMenu que recibimos como parámetro.
		inflater.inflate(R.menu.ctx_menu_button2, menu);
		break;
	}

}

En este punto ya podremos ver en pantalla el menú que corresponde a cada botón cuando se realice la pulsación larga sobre él, con la siguiente apariencia:

Menú contextual
Menú contextual

Gestionar las opciones del menú contextual

Tan sólo nos falta asignarle una función a cada elemento del menú seleccionado, y esto lo haremos sobreescribiendo el método public boolean onContextItemSelected(MenuItem item), que es el que se lanza cuando pulsemos una de las opciones. Como se ve en la firma del método, devuelve un objeto boolean, que indicará al sistema si se ha manejado la el item seleccionado o no, por lo tanto devolveremos true con todos los casos que nosotros manejemos, y en los casos por defecto devolveremos la acción del super (que hará llamada al método original que estamos sobreescribiendo). Para comprobar qué opción es la seleccionada, haremos un switch en función del ID del objeto item que recibimos, y así le asignaremos la tarea a realizar a cada una de las opciones, e incluiremos el caso por defecto:

@Override
public boolean onContextItemSelected(MenuItem item) {
	// Previamente creamos el objeto TextView y lo inicializamos para poder
	// asignarle aquí el texto en función de la opción seleccionada.
	switch (item.getItemId()) {
	case R.id.button1_menu_opt1:
		tvRegisterText
				.setText("Se ha pulsado la opción 1 del menú contextual del botón 1.");
		return true;
	case R.id.button1_menu_opt2:
		tvRegisterText
				.setText("Se ha pulsado la opción 2 del menú contextual del botón 1.");
		return true;
	case R.id.button2_menu_opt1:
		tvRegisterText
				.setText("Se ha pulsado la opción 1 del menú contextual del botón 2.");
		return true;
	case R.id.button2_menu_opt2:
		tvRegisterText
				.setText("Se ha pulsado la opción 2 del menú contextual del botón 2.");
		return true;
	case R.id.button2_menu_opt3:
		tvRegisterText
				.setText("Se ha pulsado la opción 3 del menú contextual del botón 2.");
		return true;
	default:
		return super.onContextItemSelected(item);
	}
}

Por último vamos a escribir el método onClick de cada botón, para poder modificar el texto del TextView indicando que se ha hecho una pulsación corta sobre el botón:

public void onClick(View v) {
	switch (v.getId()) {
	case R.id.btCtxMenu1:
		// Se ha realizado pulsación corta sobre el botón 1.
		tvRegisterText.setText("Se ha pulsado el botón 1.");
		break;
	case R.id.btCtxMenu2:
		// Se ha realizado pulsación corta sobre el botón 2.
		tvRegisterText.setText("Se ha pulsado el botón 2.");
		break;
	}
}

Y con esto ya hemos creado un menú contextual para cada elemento de nuestra vista, y le hemos asignado una funcionalidad a cada opción seleccionada.

Descargas

Puedes descargar el proyecto completo aquí.

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0
The following two tabs change content below.
Reborn as IT Developer. Desarrollador Android y fundador de Proyecto Simio. "En realidad, yo no puedo enseñar nada a nadie, sólo puedo hacerles pensar." - Sócrates.

3 thoughts on “Programación Android, menú contextual (registerForContextMenu)

Deja un comentario