Cómo configurar el ID para los elementos del menú emergente, que se encuentra como id de la vista?

Fondo

Las pruebas automáticas utilizan las identificaciones de las vistas para poder hacer clic en ellas, por lo que agregamos IDs siempre que sea posible.

El problema

Para los menús emergentes, a veces es necesario rellenarlos dinámicamente, pero como he encontrado, incluso cuando agrego id para cada elemento, el id no se encuentra y no se puede usar. Incluso con la función de DDMS "Jerarquía de vista de volcado para UI automator" muestra que ninguna vista en el menú emergente tiene un id.

Lo que he intentado

Este es un ejemplo de código de lo que uso, para tratar de establecer un id para el elemento de un solo menú.

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); View v=findViewById(R.id.button); v.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { PopupMenu popupMenu = new PopupMenu(MainActivity.this, v); final Menu menu = popupMenu.getMenu(); menu.add(0, R.id.myMenuItem, 0, R.string.app_name).setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(final MenuItem item) { return false; } }) ; popupMenu.show(); } }); } 

Tenga en cuenta que el ID se declara en el archivo "ids.xml", como tal:

 <item name="myMenuItem" type="id"/> 

Y esto es lo que me muestra la herramienta DDMS:

Introduzca aquí la descripción de la imagen

La pregunta

¿Cómo es que este código no funciona como se esperaba (significa que tiene un ID para la vista del elemento de menú)? ¿Qué puedo hacer para que las vistas en ella tengan IDs? ¿Cuál es la forma correcta de agregar ids para elementos de menú que se crean dinámicamente?

Bien, esto no es de ninguna manera una respuesta al problema descrito en la pregunta. Mírelo como una alternativa para reemplazar PopupMenu con el fin de lograr lo que se le pidió.

No PopupMenu

Después de excavar los documentos para PopupMenu y su código fuente, finalmente llegué a entender que PopupMenu no es una implementación que permita la personalización (mi disculpa a la OP por la idea errónea en los comentarios).

Una alternativa

Como alternativa, ListPopupWindow es una opción preferida para crear un menú emergente con las siguientes razones:

  1. Comparte el mismo padre con PopupMenuListView .
  2. Es flexible, permitiendo que el Adapter personalizado sea definido con la disposición de encargo.
  3. También permite la creación en tiempo de ejecución como hace PopupMenu , y permite adjuntar el identificador de recurso a la vista del elemento.

Implementación

En primer lugar, vamos a definir un diseño personalizado para el elemento emergente ( popup_item_view.xml ).

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <TextView android:id="@+id/popup_text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 

A continuación, defina una clase Adapter personalizada para manipular el diseño.

 package com.example.popupmenu; import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class PopupAdapter extends BaseAdapter { public static class Item { public final int id; public final String title; public Item(int id, @NonNull String title) { this.id = id; this.title = title; } } private List<Item> mItemList = new ArrayList<>(); public PopupAdapter(@NonNull Item[] items) { mItemList.addAll(Arrays.asList(items)); } @Override public int getCount() { return mItemList.size(); } @Override public Item getItem(int position) { return mItemList.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { final Item item = getItem(position); if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); convertView = inflater.inflate(R.layout.popup_item_view, parent, false); } convertView.setId(item.id); TextView titleView = (TextView) convertView.findViewById(R.id.popup_text); titleView.setText(item.title); return convertView; } } 

Finalmente, reemplace el código de PopupMenu con esto.

 PopupAdapter.Item[] items = { new PopupAdapter.Item(R.id.popup_item_1, "item 1"), new PopupAdapter.Item(R.id.popup_item_2, "item 2") }; ListPopupWindow popup = new ListPopupWindow(MainActivity.this); popup.setAnchorView(view); popup.setAdapter(new PopupAdapter(items)); popup.setModal(true); popup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // do something } @Override public void onNothingSelected(AdapterView<?> parent) { // do something } }); popup.show(); 

Espero que esto ayude.

  • Mostrar menú emergente en el elemento `ActionBar` haga clic en
  • Cómo cambiar el color de texto y el tamaño de un menú emergente en android?
  • Estilo PopupMenu Android
  • Ancla el menú emergente sobre el botón de desbordamiento
  • Problema de menú emergente en Android ListView
  • AppCompat PopUp menu RuntimeException
  • Rellenar popupmenu sin archivo XML en android
  • Creación de un menú de opciones emergentes en una barra de acción contextual
  • Color de texto del menú emergente de Android (AppCompat)
  • ¿Cómo puedo reemplazar mi código popupmenu con la lista popupwindow?
  • Implementar menú emergente con margen
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.