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.
- Android cómo mostrar PopupMenu en webview como GMail
- Se ha intentado finalizar un evento de entrada pero el receptor de eventos de entrada ya se ha eliminado
- Cómo evitar que el menú emergente se cierre en la casilla de verificación haga clic
- Menú emergente personalizado de Android con conmutador
- Cómo cambiar la anchura de Android PopupMenu
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:
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?
- Yo uso ShareActionProvider en PopupMenu, pero mostrar dos PopupMenu?
- Android PopupWindow se oculta detrás de los botones de navegación en Nexus 5
- Detectar que un PopupMenu está cerrado en el nivel 11 de API
- ¿Cómo puedo arreglar NoClassDefFoundError en Android para android.widget.PopupMenu?
- La mejor manera de crear menú desplegable en android 2.x como en ICS
- Android: Uso de PopupMenu en el nivel 9 de API
- Cambiar el color del texto de un solo elemento en un PopupMenu
- Manejo de elementos del menú emergente
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:
- Comparte el mismo padre con
PopupMenu
–ListView
. - Es flexible, permitiendo que el
Adapter
personalizado sea definido con la disposición de encargo. - 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.
- Cómo conectar Android a PC
- ¿Puede un apóstrofe sin escáner en un literal definido en strings.xml hacer que mi aplicación se bloquee?