Menús
Revisión del 16:18 20 oct 2018 de Wiki (discusión | contribuciones) (→Menú contextual: o código Java da aplicación)
Introducción
- Nesta unidade imos ver como xestionar menús, submenús e menú contextuais.
- A seguinte imaxe amosa os menús na Action Bar da aplicación
- 1: Icona da App e nome
- 2: Dúas iconas de menús da aplicación
- 3: Menú OverFlow que equivale ao botón Menú da Botonera.
- Os menús poden poñerse na Action Bar dende a versión 3.0 de Android.
- Esta barra pasa a chamarse AppBar a partires da versión Android 5 (API 21).
- Para versións anteriores á 3.0 os menús víanse como na parte inferior da seguinte imaxe:
- A seguinte imaxe amosa 3 botóns de menú na Barra de Acción e o menú Overflow
- Nesta imaxe vese como un dos menús da action bar ten submenús:
- Finalmente as seguintes imaxes amosan Menús Contextuais
- Flotantes (esquerda)
- ou na barra de accións (dereita)
- Referencias:
Menus e submenús básicos
- Indicar que podemos consultar o tamaño recomendado das iconas que van na AppBar neste enlace.
- Imos realizar unha aplicación con 3 menús (un deles con submenús e outro cunha icona na Barra de Acción).
- Antes imos ver distintas casuísticas:
- Como os menús van ir na ActionBar e queremos que esta:
- Teña o mesmo aspecto en todas as versións de Android.
- Posibilidade de facer uso da interface de usuario Material Design.
Recursos Implicados
- Os menús defínense nun recurso xml en res/menu/nome_ficheiro.xml
- Dito recurso terá coma elementos:
- <menu>: elemento raíz. Contén <item> e <group>
- <item>: representa un elemento de menú.
- Tería que ter un elemento <menu> dentro de <item> para crear un submenú.
- Arrastrade dous 'menuitem' e cambiade as súas propiedades:
- id: mniPrimeiro
- Texto: Primeiro
- id:mniSegundo
- Texto: Segundo
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:app="http://schemas.android.com/apk/res-auto"
3 xmlns:android="http://schemas.android.com/apk/res/android">
4
5 <item
6 android:id="@+id/mniPrimeiro"
7 android:title="Primeiro"
8 />
9 <item
10 android:id="@+id/mniSegundo"
11 android:title="Segundo"></item>
12 </menu>
- Agora comentaremos algúns dos atributos que podemos cambiar.
- Lembrar que o podemos facer graficamente ou directamente no editor na vista XML.
- Atributo android:showAsAction (se a activity deriva da clase Activity):
- Atributo app:showAsAction (se a activity deriva da clase AppCompactActivity):
- Pode ter os seguintes valores:
- never: nunca amosa o item de menú na barra de acción.
- ifRoom: se hai espazo na barra de acción o amosa.
- always: amosa sempre na barra de acción.
- withText: se temos unha icona, por defecto non amosa o texto. Se queremos que amose os dúos poñeremos este valor.
- collapseActionView: cando a acción dun elemento de menú (declarada coma android:actionLayout ou android:actionViewClass) é plegable. Dispoñible apartires da versión API 14.
- Atributo android:orderInCategory="Nº Enteiro":
- Despois de premer no deseñador de Android Studio na opción 'View all attributes':
- Se hai varios ítems indica cal aparecerá primeiro, segundo, etc. Se todos teñen o mesmo valor ou non se pon valor ningún, entón aparecen na orde na que son creados, de esquerda a dereita e de arriba-abaixo.
- Os elementos de menú que aparecen na barra, xa non aparecen no menú o premer o botón Menú ou "OverFlow", aínda que estean nun group, como se pode apreciar nas imaxes de abaixo.
- Os valores pódense combinar có caracter ‘|’.
- O atributo android:onClick funciona igual que nas vistas do recurso xml do Layout.
- EXEMPLO DE MENÚ NA BARRA DE ACCIÓN CON SUBMENUS
- A seguinte imaxe, obtense co seguinte recurso xml.
- Podedes descargar as imaxes neste arquivo: Media:PDM_icons_menu_exemplo.zip
- Lembra que xa vimos como engadir novos recursos gráficos cando vimos o ImageView.
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <item
5 android:id="@+id/itemAbrir"
6 android:icon="@drawable/open32"
7 android:showAsAction="ifRoom"
8 android:title="Abrir"
9 android:titleCondensed="Abrir">
10 <menu>
11 <item
12 android:id="@+id/itemDoc"
13 android:title="Documento"
14 android:titleCondensed="Doc."/>
15 <item
16 android:id="@+id/itemIma"
17 android:title="Imaxes"
18 android:titleCondensed="Imax."/>
19 <item
20 android:id="@+id/itemAudio"
21 android:title="Audio"
22 android:titleCondensed="Audio"/>
23 </menu>
24 </item>
25 <item
26 android:id="@+id/itemNovo"
27 android:icon="@drawable/close32"
28 android:showAsAction="ifRoom"
29 android:title="Novo documento"
30 android:titleCondensed="N.Doc.">
31 </item>
32 <item
33 android:id="@+id/itemSair"
34 android:icon="@drawable/exit32"
35 android:showAsAction="ifRoom"
36 android:title="Saír"
37 android:titleCondensed="Saír">
38 </item>
39
40 </menu>
- Liñas 6,27,34: Indican o recurso drawable que deben amosar. Estas imaxes deben estar na carpeta /res/drawableXXXXX correspondentes.
- Liñas 7,28,35: Indican que se hai espazo na barra de acción que amosen eses ítems que teñen ese atributo.
- Liñas 9,30,37: O atributo android:titleCondensed usarase cando o valor de android:title sexa demasiado longo.
- Liñas 10-23: Para crear submenús dentro dun menú, volvemos a crear a entrada <menu> dentro de <item>
Agrupamentos
- Outro elemento que pode ir dentro do elemento <menu>:
- <group>: un grupo é un conxunto de elementos que teñen certas características.
- Amosar ou ocultar todos os elementos: setGroupVisible()
- Habilitar ou deshabilitar todos os elementos: setGroupEnabled()
- Facer que todos os ítems do group poidan ser presentados en forma de checkbox: setGroupCheckable()
- Podemos facer que un elemento sexa chequeable usando o atributo android:checkable no elemento <item> ou o
- group enteiro con 'android:checkableBehavior no elemento <group>.
- O atributo android:checkableBehavior pode ter as seguintes opcións:
- single: só un elemento do grupo pode ser checkeado (radiobuttons).
- all: todos os elementos poden ser checkeados (checkboxs).
- none: ningún elemento é seleccionable.
- Se non poñemos nada, os elementos do <group> aparecen como os demais.
- <group>: un grupo é un conxunto de elementos que teñen certas características.
- A seguinte imaxe, ten asociado o seguinte XML.
- Observar que na barra de acción non collen todos os menús.
- Observar que hai dous menús (Modo Lectura e Modo Gravación) que poden ser marcados os dous.
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <item
5 android:id="@+id/itemAbrir"
6 android:icon="@drawable/open32"
7 android:showAsAction="always"
8 android:title="Abrir"
9 android:titleCondensed="Abrir">
10 <menu>
11 <item
12 android:id="@+id/itemDoc"
13 android:title="Documento"
14 android:titleCondensed="Doc."/>
15 <item
16 android:id="@+id/itemIma"
17 android:title="Imaxes"
18 android:titleCondensed="Imax."/>
19 <item
20 android:id="@+id/itemAudio"
21 android:title="Audio"
22 android:titleCondensed="Audio"/>
23 </menu>
24 </item>
25 <item
26 android:id="@+id/itemNovo"
27 android:icon="@drawable/close32"
28 android:showAsAction="ifRoom"
29 android:title="Novo documento"
30 android:titleCondensed="N.Doc.">
31 </item>
32 <item
33 android:id="@+id/itemSair"
34 android:icon="@drawable/exit32"
35 android:showAsAction="ifRoom"
36 android:title="Saír"
37 android:titleCondensed="Saír">
38 </item>
39
40 <group
41 android:id="@+id/mgrpModos"
42 android:checkableBehavior="all" >
43 <item
44 android:id="@+id/ModoLect"
45 android:showAsAction="ifRoom"
46 android:title="Modo Lectura"
47 android:titleCondensed="M.Lect.">
48 </item>
49 <item
50 android:id="@+id/ModoRecord"
51 android:showAsAction="ifRoom"
52 android:title="Modo Grabación"
53 android:titleCondensed="M.Grab">
54 </item>
55 </group>
56
57 </menu>
- Liñas 35,45,51: Observar como estes ítems non se amosan na barra de acción porque non teñen espazo.
- Liñas 40-55: Observar como hai un agrupamento de ítems e na liña 42 indícase que todos eles son "chequeables".
Lanzar e procesar o menú
- Para lanzar o menú debemos cambiar o menú que ten asinada unha determinada Activity e para iso temos que sobrescribir o método onCreateOptionsMenu().
- O que facemos en "inflar" o xml asociado ao menú (Liña 4) do mesmo xeito que se fai cando se
1 @Override
2 public boolean onCreateOptionsMenu(Menu menu) {
3 // Inflate the menu; this adds items to the action bar if it is present.
4 getMenuInflater().inflate(R.menu.menu_ud04_01_menus, menu);
5 return true;
6 }
- Cando se preme un ítem dun menú lánzase o evento onOptionsItemSelected e para procesar ese ítem sobrescribir o método onOptionsItemSelected(MenuItem item).
- Este método tamén se crea por defecto ao crear o proxecto.
1 @Override
2 public boolean onOptionsItemSelected(MenuItem item) {
3 // Handle action bar item clicks here. The action bar will
4 // automatically handle clicks on the Home/Up button, so long
5 // as you specify a parent activity in AndroidManifest.xml.
6
7 int id = item.getItemId();
8 if (id == R.id.itemAbrir) {
9 return true;
10 }
11 return super.onOptionsItemSelected(item);
12 }
- Este método devolve un boolean:
- true: se procesamos un elemento do menú (return true).
- false: se queremos que o evento siga 'propagándose' polo resto da xerarquía de views do Activity.
Caso práctico
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- Se non o temos creado antes, crearemos un novo paquete de nome: Menus como un subpaquete do teu paquete principal.
- Dentro do paquete Menus crear unha nova 'Empty Activity' de nome: UD04_01_Menus de tipo Launcher e sen compatibilidade.
- Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.
Nota: Nas imaxes aparece como label da activity: 'U5_01_XXXX'. Non fagades caso e a vos debería saír: UD04_01_Menus.
As imaxes dos menús
- Neste caso colocouse en cada recurso res/drawable a imaxe da cara:
- Esta imaxe pode obterse do seguinte zip: media:Res.zip e unha vez descomprimido pódese copiar tal cal ao proxecto a "res"
- Estas imaxes e outras poden obterse de:
Recursos XML
- O xml do Layout:
1 <?xml version="1.0" encoding="utf-8"?>
2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 tools:context=".Menus.UD04_01_Menus">
8
9 <TextView
10 android:id="@+id/tvTexto_UD04_01_Menus"
11 android:layout_width="wrap_content"
12 android:layout_height="wrap_content"
13 android:layout_marginBottom="8dp"
14 android:layout_marginEnd="8dp"
15 android:layout_marginStart="8dp"
16 android:layout_marginTop="8dp"
17 android:text="TextView"
18 android:textSize="24sp"
19 app:layout_constraintBottom_toBottomOf="parent"
20 app:layout_constraintEnd_toEndOf="parent"
21 app:layout_constraintStart_toStartOf="parent"
22 app:layout_constraintTop_toTopOf="parent" />
23 </android.support.constraint.ConstraintLayout>
- Creamos un XML có texto das opcións de menú en /res/values/ de nome strings_mnu_UD04_01_Menus:
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <string name="mniItem1_UD04_01_Menus">Opción 1</string>
4 <string name="mniItem2_UD04_01_Menus">Opción 2</string>
5 <string name="mnuItem3_UD04_01_Menus">Opción 3- Submenús</string>
6 <string name="mniItem3_1_UD04_01_Menus">Opción 3- Submenú 1 - Calculadora</string>
7 <string name="mniItem3_2_UD04_01_Menus">Opción 3- Submenú 2 - Saír</string>
8
9 </resources>
- O xml do menú (modificamos o recurso XML creado por defecto en /res/menu/...)
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:app="http://schemas.android.com/apk/res-auto"
3 xmlns:android="http://schemas.android.com/apk/res/android">
4
5 <item
6 android:id="@+id/mniItem1_04_01_Menus"
7 android:icon="@drawable/ic_action_emo_basic"
8 android:orderInCategory="100"
9 app:showAsAction="always"
10 android:title="@string/mniItem1_UD04_01_Menus"/>
11 <item
12 android:id="@+id/mniItem2_04_01_Menus"
13 android:orderInCategory="100"
14 app:showAsAction="never"
15 android:title="@string/mniItem2_UD04_01_Menus"/>
16 <item
17 android:id="@+id/mnuItem_3_04_01_Menus"
18 android:orderInCategory="100"
19 app:showAsAction="never"
20 android:title="@string/mnuItem3_UD04_01_Menus">
21 <menu>
22 <item
23 android:id="@+id/mniItem3_1_04_01_Menus"
24 android:title="@string/mnuItem3_1_UD04_01_Menus"/>
25 <item
26 android:id="@+id/mniItem3_2_04_01_Menus"
27 android:title="@string/mniItem3_2_UD04_01_Menus"/>
28 </menu>
29 </item>
30 </menu>
- Liñas 8,13,18: Observar como todos os ítems teñen o mesmo valor para a ser ordenados.
- Que o participante no curso probe a cambiar o terceiro ítem a un valor de 99.
- Liñas 9,14,19: Observar como o primeiro ítem indica always e os demais never á hora de amosar o menú na barra de acción.
O código da Activity
1 package es.cursoandroid.cifprodolfoucha.aprendiendo.Menus;
2
3 import android.content.Intent;
4 import android.os.Bundle;
5 import android.support.v7.app.AppCompatActivity;
6 import android.view.Menu;
7 import android.view.MenuItem;
8 import android.widget.TextView;
9 import android.widget.Toast;
10
11 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
12
13 public class UD04_01_Menus extends AppCompatActivity {
14
15 @Override
16 protected void onCreate(Bundle savedInstanceState) {
17 super.onCreate(savedInstanceState);
18 setContentView(R.layout.activity_ud04_01__menus);
19 }
20
21
22 @Override
23 public boolean onCreateOptionsMenu(Menu menu) {
24 // Inflate the menu; this adds items to the action bar if it is present.
25 getMenuInflater().inflate(R.menu.menu_ud04_01_menus, menu);
26 return true;
27 }
28
29
30 @Override
31 public boolean onOptionsItemSelected(MenuItem item) {
32 // Handle action bar item clicks here. The action bar will
33 // automatically handle clicks on the Home/Up button, so long
34 // as you specify a parent activity in AndroidManifest.xml.
35
36 TextView tv = (TextView) findViewById(R.id.tvTexto_UD04_01_Menus);
37 Toast.makeText(getApplicationContext(), "Pulsado elemento: " + item.getTitle().toString(), Toast.LENGTH_SHORT).show();
38
39 switch (item.getItemId()) {
40 case R.id.mniItem1_04_01_Menus:
41 tv.setText("Quedarei con esta cara de sorriso cando remate esta tarefa");
42 return true;
43
44 case R.id.mniItem2_04_01_Menus:
45 tv.setText("A opción 2 non ten nada asignado");
46 return true;
47
48 case R.id.mniItem3_1_04_01_Menus:
49 Intent intent = new Intent();
50 intent.setClassName("com.android.calculator2", "com.android.calculator2.Calculator");
51 startActivity(intent);
52 return true;
53
54 case R.id.mniItem3_2_04_01_Menus:
55 finish();
56 return true;
57 default:
58 return super.onOptionsItemSelected(item);
59
60 }
61 }
62
63 /**
64 * Método que se chama cando a activity se pecha.
65 */
66 public void finish() {
67 super.finish();
68 }
69
70
71 }
- Liña 37: Recollemos o título do ítem pulsado.
- Liñas 42,46,52,56: devolver true no caso de procesar cada un dos ítems.
- Liña 58: Se non se procesou o ítem chamar ao pai, que vai devolver false por defecto.
- Se na definición de cada ítem se houbera usado o atributo android:onClick entón teríamos que crear en java os métodos correspondentes do mesmo xeito que se fai cando se usa ese atributo nun Layout.
Menús contextuais
- Pódense crear sobre calquera elemento View, pero normalmente vanse usar con ListView e GridView.*
- Existen dúas formas de implantar este tipo de menús:
- Menú contextual flotante:
- O menú aparece cando o usuario prema durante un tempo longo un elemento e aparece unha lista.
Para crear este tipo de menú:
- O View que queira usalo ten que ser asociado ao mesmo chamando o método registerForContextMenu pasando o obxecto View.
- Se todos os elementos do ListView / GridView teñen o mesmo menú contextual, se pode pasar como parámetro o ListView / GridView.
- Por exemplo (isto se fai no método onCreate): registerForContextMenu(lista);
- Sendo lista a referencia a unha ListView.
- Implantar o método onCreateContextMenu() na Activity / Fragment.
- Este método será chamado de forma automática cando o usuario preme durante un tempo o elemento (View) asociado o ContextMenu.
- O que fai este método é amosar o menú contextual creado por nós previamente.
1 @Override
2 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
3 super.onCreateContextMenu(menu, v, menuInfo);
4 MenuInflater inflater = getMenuInflater();
5 inflater.inflate(R.menu.context_menu, menu);
6 }
- Lembrar que o MenuInflater serve para pasar dun arquivo XML (o menú contextual definido por nós) a obxectos MenuItems.
- Implantar o método onContextItemSelected() ao que se chama de forma automática cando se selecciona algo do menú contextual
1 @Override
2 public boolean onContextItemSelected(MenuItem item) {
3 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
4 switch (item.getItemId()) {
5 case R.id.edit:
6 editNote(info.id);
7 return true;
8 case R.id.delete:
9 deleteNote(info.id);
10 return true;
11 default:
12 return super.onContextItemSelected(item);
13 }
14 }
- Liña 3. Do ítem pulsado recibimos información extra, entre outras, o "id" e a "posición" do ítem do adaptador sobre o que se pulsou durante un tempo para crear o menú contextual.
- Ese "id" e "posición" son recollidos na variable info de tipo AdapterContextMenuInfo.
- Liña 4: fixarse que é item.getItemId() para obter referencia ao id do menú contextual que foi seleccionado. Non confundir co id do elemento do adaptador sobre o que foi creado ese menú contextual.
- O resto funciona igual que non menú básico.
- Menú de modo acción contextual:
- Neste caso, o menú aparece nunha barra de acción contextual na parte superior da pantalla (só dispoñible a partires da versión 3.0 API11).
- O funcionamento é semellante ao anterior e deixamos para o participante no curso o seguinte enlace para que afonde no seu funcionamento:
Menú contextual: Caso Práctico
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- Se non o temos creado antes, crearemos un novo paquete de nome: Menus como un subpaquete do teu paquete principal.
- Dentro do paquete Menus crear unha nova 'Empty Activity' de nome: UD04_02_Menus de tipo Launcher e sen compatibilidade.
- Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.
- Neste caso vanse crear dous menús contextuais distintos:
- un para unha etiqueta (TextView)
- e outro para unha lista (ListView).
Menú contextual: O XML do Layout
1 <?xml version="1.0" encoding="utf-8"?>
2 <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 tools:context=".Menus.UD04_02_Menus">
8
9 <TextView
10 android:id="@+id/tvTexto_UD04_02_Menus"
11 android:layout_width="wrap_content"
12 android:layout_height="wrap_content"
13 android:layout_marginEnd="8dp"
14 android:layout_marginStart="8dp"
15 android:layout_marginTop="8dp"
16 android:text="Hello World"
17 android:textSize="18sp"
18 app:layout_constraintEnd_toEndOf="parent"
19 app:layout_constraintStart_toStartOf="parent"
20 app:layout_constraintTop_toTopOf="parent" />
21
22 <ListView
23 android:id="@+id/lvFroitas_UD04_02_Menus"
24 android:layout_width="0dp"
25 android:layout_height="169dp"
26 android:layout_marginEnd="8dp"
27 android:layout_marginStart="8dp"
28 android:layout_marginTop="16dp"
29 app:layout_constraintEnd_toEndOf="parent"
30 app:layout_constraintHorizontal_bias="1.0"
31 app:layout_constraintStart_toStartOf="parent"
32 app:layout_constraintTop_toBottomOf="@+id/tvTexto_UD04_02_Menus" />
33 </android.support.constraint.ConstraintLayout>
Menú contextual: O XML dos menús contextuais
- Imos crear dous recursos xml para cada un dos menús contextuais distintos que temos segundo premamos sobre un TextView ou sobre un ListView.
- Poderían ser o mesmo menú contextual, pero así aprendemos que estes poden ser distintos en función da View ao que se asocien.
- O xml de /res/menu/menu_ud04_02_context_etiqueta.xml
- Nota: O Android Studio seguramente vos dirá que existe un erro na liña android:showAsAction e que deberedes cambialo por 'app:showAsAction'. Non lle fagades caso Ese aviso aparece debido a que tedes importado a librería de compatibilidade v7 nalgunha outra práctica. Soamente sería necesario se a activity derivase da clase AppCompactActivity como fixemos na práctica anterior.
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <item
5 android:id="@+id/mniItem1_04_02_context_etiq"
6 android:showAsAction="withText"
7 android:title="TextView opción 1">
8 </item>
9 <item
10 android:id="@+id/mniItem2_04_02_context_etiq"
11 android:showAsAction="withText"
12 android:title="TextView opción 2">
13 </item>
14
15 </menu>
- O xml de /res/menu/menu_ud04_02_context_lista.xml
- Nota: O Android Studio seguramente vos dirá que existe un erro na liña android:showAsAction e que deberedes cambialo por 'app:showAsAction'. Non lle fagades caso Ese aviso aparece debido a que tedes importado a librería de compatibilidade v7 nalgunha outra práctica. Soamente sería necesario se a activity derivase da clase AppCompactActivity como fixemos na práctica anterior.
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:android="http://schemas.android.com/apk/res/android" >
3
4 <item
5 android:id="@+id/mniItemBorrar_ud04_02_context_lista"
6 android:showAsAction="withText"
7 android:title="Borrar">
8 </item>
9 <item
10 android:id="@+id/mniItemDuplicar_ud04_02_context_lista"
11 android:showAsAction="withText"
12 android:title="Duplicar">
13 </item>
14 </menu>
- Observar que nos dous ficheiros xml cada item ten asociado un "id", para logo ser identificado o ítem cando sexa procesado no código.
Menú contextual: o código Java da aplicación
1 package es.cursoandroid.cifprodolfoucha.aprendiendo.Menus;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.view.ContextMenu;
6 import android.view.MenuInflater;
7 import android.view.MenuItem;
8 import android.view.View;
9 import android.widget.AdapterView;
10 import android.widget.ArrayAdapter;
11 import android.widget.ListView;
12 import android.widget.TextView;
13 import android.widget.Toast;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17
18 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
19
20 public class UD04_02_Menus extends Activity {
21
22
23 private void rexistarMenusEmerxentes(){
24
25 TextView tv = findViewById(R.id.tvTexto_UD04_02_Menus);
26 registerForContextMenu(tv);
27
28 ListView lv = findViewById(R.id.lvFroitas_UD04_02_Menus);
29 registerForContextMenu(lv);
30 }
31
32 private void engadirDatosLista(){
33 String[] froitas = new String[] { "Laranxa", "Mango", "Ameixa" };
34 ArrayList<String> alFroitas = new ArrayList<String>();
35
36 alFroitas.addAll(Arrays.asList(froitas));
37
38 ArrayAdapter<String> adaptador = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, alFroitas);
39 adaptador.setDropDownViewResource(android.R.layout.simple_list_item_1);
40
41 ListView lv = findViewById(R.id.lvFroitas_UD04_02_Menus);
42 lv.setAdapter(adaptador);
43
44 }
45
46 @Override
47 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
48 super.onCreateContextMenu(menu, v, menuInfo);
49 MenuInflater inflater = getMenuInflater();
50
51 // Comprobamos se o menú contextual se lanzou sobre a etiqueta ou sobre
52 // a lista
53 if (v.getId() == R.id.tvTexto_UD04_02_Menus) {
54 inflater.inflate(R.menu.menu_ud04_02_context_etiqueta, menu);
55 }
56
57 else if (v.getId() == R.id.lvFroitas_UD04_02_Menus) {
58 inflater.inflate(R.menu.menu_ud04_02_context_lista, menu);
59 }
60 }
61
62 @Override
63 public boolean onContextItemSelected(MenuItem item) {
64 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
65
66 ListView lv = findViewById(R.id.lvFroitas_UD04_02_Menus);
67 ArrayAdapter<String> adaptador = (ArrayAdapter<String>) lv.getAdapter();
68
69 switch (item.getItemId()) {
70
71 // Ítems premidos sobre o TextView
72 // Lanza un Toast coa opción do menú contextual que se seleccinou
73 case R.id.mniItem1_04_02_context_etiq:
74 Toast.makeText(this, "Menú contextual TextView:\n"+item.getTitle(), Toast.LENGTH_SHORT).show();
75 return true;
76
77 case R.id.mniItem2_04_02_context_etiq:
78 Toast.makeText(this, "Menú contextual TextView:\n"+item.getTitle(), Toast.LENGTH_SHORT).show();
79 return true;
80
81 // Ítems premidos sobre o ListView
82 case R.id.mniItemBorrar_ud04_02_context_lista:
83 adaptador.remove(adaptador.getItem(info.position));
84 adaptador.setNotifyOnChange(true);
85 return true;
86
87 case R.id.mniItemDuplicar_ud04_02_context_lista:
88 adaptador.add(adaptador.getItem(info.position));
89 adaptador.setNotifyOnChange(true);
90
91 return true;
92 default:
93 return super.onContextItemSelected(item);
94 }
95 }
96
97 @Override
98 protected void onCreate(Bundle savedInstanceState) {
99 super.onCreate(savedInstanceState);
100 setContentView(R.layout.activity_ud04_02__menus);
101
102 rexistarMenusEmerxentes();
103 engadirDatosLista();
104 }
105
106
107 }
- Liña 26: indicamos que TextView vai ter un menú contextual asociado.
- Liña 29: indica que o ListView de froitas vai ter un menú contextual asociado.
- Liñas 33,34: Creamos un Array estático que logo asignamos a un dinámico.
- Liña 36: usamos o array dinámico para logo en tempo de execución poder engadir/borrar elementos do adaptador e por tanto do ListView.
- Nota: Se poñemos un array como parámetro no ArrayAdapter, non poderíamos facer operacións de borrado e engadir novos elementos.
- Liñas 46-60: onCreateContexMenu() vai ser chamado cando se prema durante un anaco sobre unha view, neste caso comprobamos sobre que view se premeu e lánzase ("inflase") o correspondente menú contextual, cada un deles definido nun ficheiro xml distinto.
- Liñas 62-95: En función do id do ítem premido realizamos unhas accións ou outras como no caso dos menús básicos. Só que neste caso os ids proveñen de ítems de menús declarados en 2 ficheiros distintos.
Personalizar título do menú contextual
- Se queremos que o menú contextual teña un título debemos usar o método: setHeaderTitle()
- As seguintes imaxes amosan un exemplo para o caso do TextView e o ListView:
- Os cambios a realizar no código Java son os seguintes:
- No memento no que hai que crear o menú contextual:
1 @Override
2 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
3 super.onCreateContextMenu(menu, v, menuInfo);
4 MenuInflater inflater = getMenuInflater();
5
6 // Comprobamos se o menú contextual se lanzou sobre a etiqueta ou sobre
7 // a lista
8 if (v.getId() == R.id.tv){
9 menu.setHeaderTitle("Etiqueta de texto");
10 inflater.inflate(R.menu.menu_contextual_etiqueta, menu);
11 }
12 else if (v.getId() == R.id.lvFroitas) {
13 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
14 menu.setHeaderTitle(lv.getAdapter().getItem(info.position).toString());
15 inflater.inflate(R.menu.menu_contextual_lista, menu);
16 }
17 }
- Liñas 9,14: establecemos o título para o menú contextual.
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).