Você está na página 1de 7

Ejercicio 16 Menus Principal y Submenus con Opciones

NOTA USE UN EMULADOR PARA API 10 (Nexus One)


NOTA EN ANDROID MANIFEST USE SOLO MIN-SDK 10
OJO a LOS INDICES DE LAS OPCIONES
Variables
private TextView labelResultado;
private ListView listadoPrincipal;
// Definimos el adaptador que va a usar el ListView
private ArrayAdapter<String> adaptador;
// Matriz con los datos del adaptador
private String[] datos = new String[]{"Opcin 0 listado","Opcin 1
listado","Opcin 2 listado","Opcin 3 listado","Opcin 4 listado"};

Los mens contextuales siempre estn asociados a un componente en


concreto de la pantalla y se muestra cuando el usuario lo pulsa un
rato. Normalmente, se suele mostrar opciones especficas para el
elemento pulsado.

Por ejemplo, en un componente de tipo lista podramos tener un men


contextual que aparezca al pulsar sobre un elemento en concreto de la
lista y que permita editar su texto o eliminarlo de la lista.

La creacin y utilizacin de este tipo de mens contextuales son muy


parecidas a las de los mens y submens bsicos que hemos visto
anteriormente, aunque presentan algunas particularidades que vamos a
tratar a continuacin.

Vamos a partir del ejemplo anterior de esta Unidad, al que vamos a


aadir un men contextual que aparece al pulsar sobre la etiqueta de
texto donde mostramos la opcin seleccionada y un ListView con
elementos sobre los que pulsar seguidamente y mostrar opciones de
edicin.

Lo primero que debemos hacer es indicar en el mtodo onCreate() de la


Actividad que la etiqueta y el listado tienen asociado un men
contextual. Esto se hace usando la funcin registerForContextMenu():

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Obtenemos las referencias a los componentes
labelResultado = (TextView)findViewById(R.id.labelResultado);
listadoPrincipal =
(ListView)findViewById(R.id.ListadoPrincipal);
//Rellenamos la lista con datos de ejemplo
adaptador = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, datos);
listadoPrincipal.setAdapter(adaptador);
//Asociamos los mens contextuales a los componentes
registerForContextMenu(labelResultado);
registerForContextMenu(listadoPrincipal);
} // end onCreate

A continuacin, de igual forma que hicimos con los mens bsicos para
crear las opciones disponibles con el mtodo onCreateOptionsMenu(),
vamos a construir los mens contextuales asociados a los diferentes
componentes de la aplicacin con el mtodo onCreateContextMenu().

A diferencia del mtodo onCreateOptionsMenu() Android invoca este


mtodo cada vez que es necesario mostrar un men contextual. Este
mtodo lo implementaremos de misma forma que los mens bsicos,
inflndolo con un archivo de diseo XML o crendolo con sentencias
Java. En este ejemplo hemos decidido disear los mens en XML. El men
contextual que aparece en la etiqueta se define en el fichero
menu_context_etiqueta.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/ContextLabelOp1" android:title="Opcin 1 de
etiqueta"></item>
<item android:id="@+id/ContextLabelOp2" android:title="Opcin 2 de
etiqueta"></item>
</menu>

El men contextual que aparece en el ListView se define en el fichero


menu_context_lista.xml:

<?xml version="1.0" encoding="utf-8"?>


<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/EditTextOp" android:title="Editar texto
opcin"></item>
<item android:id="@+id/ReiniciaTextOp" android:title="Reiniciar texto
opcin"></item>
</menu>

Para implementar el mtodo onCreateContextMenu() hay que tener en


cuenta que definimos varios mens contextuales en la misma Actividad,
por lo que hay que construir un men distinto dependiendo del
componente asociado.
Para hacerlo, obtenemos el ID del componente al que se va a ir
asociado el men contextual, que se recibe en el parmetro (View v)
del mtodo onCreateContextMenu() utilizando el mtodo getId() de dicho
parmetro:

@Override
// Mtodo donde definimos el men contextual cuando se despliega
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
//Inflador del men contextual
MenuInflater inflater = getMenuInflater();
// Si el componente que vamos a dibujar es la etiqueta usamos
// el fichero XML correspondiente
if(v.getId() == R.id.labelResultado)
inflater.inflate(R.menu.menu_context_etiqueta, menu);
// Si el componente que vamos a dibujar es el ListView usamos
// el fichero XML correspondiente
else if(v.getId() == R.id.ListadoPrincipal)
{
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo)menuInfo;
// Definimos la cabecera del men contextual
menu.setHeaderTitle(
listadoPrincipal.getAdapter().getItem(info.position).toString());
// Inflamos el men contextual
inflater.inflate(R.menu.menu_context_lista, menu);
}
}

En el caso del men contextual para el listado hemos personalizado el ttulo


del men contextual mediante el mtodo setHeaderTitle(), para que muestre el
texto del elemento seleccionado en el listado.

Para hacer esto es necesario conocer la posicin del elemento seleccionado en


el listado mediante el ltimo parmetro menuInfo. Este parmetro contiene
informacin adicional del componente sobre el que el usuario ha pulsado para
mostrar el men contextual.

En este caso en particular del componente ListView contiene la posicin del


elemento pulsado. Para obtenerlo, hacemos un cambio de formato (typecasting)
del parmetro menuInfo a un objeto del tipo AdapterContextMenuInfo y
accedemos a su propiedad position.
Por ltimo, para implementar las acciones que hay que ejecutar cuando el
usuario selecciona una opcin determinada del men contextual vamos a
implementar el mtodo onContextItemSelected() de manera similar a cmo
hacamos con onOptionsItemSelected() para los mens bsicos:

@Override
// Si el usuario selecciona una opcin del men contextual mostramos
// la opcin seleccionada en la etiqueta
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info =
(AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
// Se selecciona la opcin 1 de men contextual de la etiqueta
case R.id.ContextLabelOp1:
labelResultado.setText("Etiqueta: Opcin 1");
return true;
// Se selecciona la opcin 2 de men contextual de la etiqueta
case R.id.ContextLabelOp2:
labelResultado.setText("Etiqueta: Opcin 2");
return true;
// Se selecciona la opcin "Editar texto opcin" de men
contextual de la etiqueta
case R.id.EditTextOp:
labelResultado.setText("Opcin " + info.position + "
listado: Cambio de texto");
// Cambiamos el contenido de la matriz de datos
datos[info.position]="Opcin "+info.position+" listado
modificado";
// Reiniciamos el adaptador para que recargue los datos y
actualice el ListBox
adaptador.notifyDataSetChanged();
return true;

// Se selecciona la opcin "Reiniciar texto opcin" de men


contextual de la etiqueta
case R.id.ReiniciaTextOp:
labelResultado.setText("Opcin " + info.position + "
listado: Reinicio texto");
datos[info.position]="Opcin "+info.position+" listado";
adaptador.notifyDataSetChanged();
return true;
default:
return super.onContextItemSelected(item);
}
}

Fjate en el cdigo anterior que se puede mantener pulsado el dedo sobre la


etiqueta azul o sobre una opcin del listado y seleccionar una de las
opciones del men contextual.

En el cdigo anterior tambin hemos utilizado la informacin del


objeto AdapterContextMenuInfo para saber qu elemento de la lista se
ha pulsado aunque, en esta ocasin, lo obtenemos llamando al mtodo
getMenuInfo() de la opcin de men MenuItem recibida como parmetro.

Adems, para modificar la opcin del listado hemos usado el mtodo


notifyDataSetChanged() del adaptador para que se recarguen los
elementos del listado una vez hemos modificado el texto de uno de
ellos.
SI NECESITAIS EL MAIN.XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content" android:id="@+id/textView1"
android:text="Mantn pulsado un elemento del listado o la
etiqueta azul."
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_marginLeft="3dip"
android:layout_marginTop="14dip"></TextView>
<!-- Esta Vista dibuja una lnea en el UI -->
<View android:layout_height="2dip" android:layout_width="wrap_content"
android:background="#FF909090" />
<TextView android:layout_height="wrap_content"

android:layout_width="fill_parent" android:text="Opcin
seleccionada:"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_marginLeft="3dip"
android:layout_marginTop="20dip"></TextView>
<TextView android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="@+id/labelResultado"
android:text="Ninguna"
android:textAppearance="?android:attr/textAppearanceLarge"
android:background="#0000FF" android:layout_marginLeft="3dip"
android:layout_marginRight="3dip"
android:layout_marginTop="3dip"
android:layout_gravity="center_horizontal"></TextView>
<!-- Esta Vista dibuja una lnea en el UI -->
<View android:layout_height="4dip" android:layout_width="wrap_content"
android:background="#FF909090" android:layout_marginTop="2dip"/>
<ListView android:id="@+id/ListadoPrincipal"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
</LinearLayout>

Você também pode gostar