Diferencia entre revisiones de «Menús»
Línea 158: | Línea 158: | ||
</menu> | </menu> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | '''IMPORTANTE:''' Se estades a empregar unha AppCompactActivity asegurádevos de que estea definido o espazo de nomes app no arquivo xml, da forma: xmlns:app="http://schemas.android.com/apk/res-auto" | ||
Revisión del 08:55 23 oct 2019
Sumario
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:
Menús e submenús básicos
- Imos ver como personalizar a ActionBar (chámase ToolBar e forma parte da AppBar, a partires da versión API 21) e que aparezan opcións de menú:
- Nota:
- Indicar que podemos consultar o tamaño recomendado das iconas que van na AppBar neste enlace.
- Podemos obter iconas no sitio web: http://www.iconarchive.com/ (intentar utilizar os que teñan licenza free).
- Imos realizar unha aplicación con 3 opcións de menú (un deles con submenús e outro cunha icona na Barra de Acción).
- Se queremos que a ActionBar (ToolBar dentro da AppBar a partires da versión API 21):
- Teña o mesmo aspecto en todas as versións de Android.
- Posibilidade de facer uso da interface de usuario Material Design (introducido a partires da API 21).
- Teremos que facer uso das bibliotecas de compatibilidade e facer que a nosa activity derive de AppCompactActivity.
- Ao facelo teremos que cambiar o deseño por un de tipo AppCompact.
- Podedes consultar como facelo neste enlace: http://wiki.cifprodolfoucha.es/index.php?title=PDM_UD1_Bibliotecas_de_compatibilidade
Empregando AppCompactActivity
- Se estades a desenvolver un proxecto e as vosos activities derivan de dita clase para ter compatibilidade con versións de Android anteriores, podemos facer que a AppBar apareza de dúas formas:
- Empregando un theme (estilo) que incorpore a AppBar.
- Empregando un theme que non incorpore' o AppBar e engadindo ao Layout da Activity o View que vai representar a AppBar.
- A opción recomendada é a segunda, xa que temos un control completo sobre o aspecto e posición da AppBar.
Aínda que non apareza nas propiedades gráficas podemos asinarlle unha 'elevación' segundo o Material Design, para que pareza que está por enriba do contido da Activity. Fixarse que o prefixo que se ten que poñer é app: para indicar que empregue a propiedade elevation da biblioteca de compatibilidade. Se cambiades por android: estares empregando a propiedade que está definida na API do S.O. Esta propiedade apareceu a partires da API 21, polo que vos dará un aviso de que non se empregará en API´s inferiores.
- O código que hai que engadir na activity no método 'onCreate' é:
1 Toolbar myToolbar = findViewById(R.id.toolbar_UD04_01_Menus);
2 setSupportActionBar(myToolbar);
- Nota: Indicar que myToolbar representa a ToolBar e podemos aplicarlle diferentes métodos coma hide() para ocultala.
- A nivel do asistente de Android Studio podemos crear unha AppBar (que inclúe ToolBar) con efectos coma facerse invisible automaticamente cando hai un scroll, poñer imaxes de fondo,...o único que tedes que facer é arrastrar o compoñentes AppBarLayout en vez do ToolBar de antes.
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>
IMPORTANTE: Se estades a empregar unha AppCompactActivity asegurádevos de que estea definido o espazo de nomes app no arquivo xml, da forma: xmlns:app="http://schemas.android.com/apk/res-auto"
- Agora comentaremos algúns dos atributos que podemos cambiar.
- Lembrar que o podemos facer graficamente ou directamente no editor na vista XML.
- Atributo android:icon: Icona asociada a esta opción de menú. Lembrade que xa vimos anteriormente como facer uso do Image Asset Store. Agora deberemos escoller a categoría 'Action bar and Tab Icons'.
- Atributo android:showAsAction (se a activity deriva da clase Activity):
- Atributo app:showAsAction (se a activity deriva da clase AppCompactActivity)
- IMPORTANTE: Se temos importada a librería de compatibilidade AppCompactActivity no build.gradle nos vai a obrigar a empregar esta opción (app:) e polo tanto teremos que facer que a activity derive de 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. Exemplo de uso neste enlace.
- 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).
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: activity_ud04_01__menus
(Nota: Neste exemplo estamos a empregar un theme que xa amosa a ToolBar. No voso caso pode aparecer ademais o View ToolBar)
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="str_mniItem1_UD04_01_Menus">Opción 1</string>
4 <string name="str_mniItem2_UD04_01_Menus">Opción 2</string>
5 <string name="str_mnuItem3_UD04_01_Menus">Opción 3- Submenús</string>
6 <string name="str_mniItem3_1_UD04_01_Menus">Opción 3- Submenú 1 - Calculadora</string>
7 <string name="str_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/...): mnu_ud04_01_menus.xml
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/str_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/str_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/str_mnuItem3_UD04_01_Menus">
21 <menu>
22 <item
23 android:id="@+id/mniItem3_1_04_01_Menus"
24 android:title="@string/str_mniItem3_1_UD04_01_Menus"/>
25 <item
26 android:id="@+id/mniItem3_2_04_01_Menus"
27 android:title="@string/str_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.mnu_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
65
66 }
- 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.
- Fixarse que un dos parámetros é o view sobre o que queremos amosar o menú contextual. Se temos varios rexistrados (registerForContextMenu) serviranos para saber de cal vimos.
- 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); Lanzaríamos unha activity obtendo o texto do elemento da lista a partires do seu id ou coa súa posicición (info.position)
7 return true;
8 case R.id.delete:
9 // deleteNote(info.id); Borraríamos o elemento da lista en base ao seu id ou coa súa posicición (info.position)
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 aplicado a un RecyclerView
Menú contextual: Caso Práctico aplicado a unha ListView e un TextView
- 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'. 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 (deberedes de aplicalo ao voso caso).
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, ContextMenu.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.tvTexto_UD04_02_Menus) {
9 menu.setHeaderTitle("Etiqueta de texto");
10 inflater.inflate(R.menu.menu_ud04_02_context_etiqueta, menu);
11 }
12 else if (v.getId() == R.id.lvFroitas_UD04_02_Menus) {
13 AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
14
15 ListView lv = findViewById(R.id.lvFroitas_UD04_02_Menus);
16 menu.setHeaderTitle(lv.getAdapter().getItem(info.position).toString());
17 inflater.inflate(R.menu.menu_ud04_02_context_lista, menu);
18 }
19 }
- Liñas 9,16: establecemos o título para o menú contextual.
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).