studio modal example activity android user-interface popupwindow

modal - popup android studio



ListPopupWindow no obedece WRAP_CONTENT especificación de ancho (8)

Creo que lo mejor es usar PopupMenu. ejemplo:

final PopupMenu popupMenu = new PopupMenu(mActivity, v); popupMenu.getMenu().add("test"); popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(final MenuItem item) { return true; } }); popupMenu.show();

Estoy tratando de usar ListPopupWindow para mostrar una lista de cadenas a través de un ArrayAdapter (eventualmente este será un adaptador personalizado más complejo). El código está abajo. Como se muestra en la captura de pantalla, el ListPopupWindow resultante parece actuar como si el ancho del contenido fuera cero. Muestra la cantidad adecuada de elementos, los elementos aún se pueden hacer clic, y al hacer clic con éxito produce un Toast , por lo que al menos eso está funcionando correctamente.

Una nota interesante: podría proporcionar un ancho en píxeles a popup.setWidth(...) lugar de ListPopupWindow.WRAP_CONTENT y mostrará algo del contenido, pero esto parece muy inflexible.

¿Cómo hago que ListPopupWindow envuelva su contenido?

Actividad de prueba:

public class MainActivity extends Activity { private static final String[] STRINGS = {"Option1","Option2","Option3","Option4"}; private View anchorView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getActionBar().setHomeButtonEnabled(true); setContentView(R.layout.activity_main); anchorView = findViewById(android.R.id.home); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: showPopup(); return true; } return super.onOptionsItemSelected(item); } private void showPopup() { ListPopupWindow popup = new ListPopupWindow(this); popup.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, STRINGS)); popup.setAnchorView(anchorView); popup.setWidth(ListPopupWindow.WRAP_CONTENT); popup.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, "Clicked item " + position, Toast.LENGTH_SHORT).show(); } }); popup.show(); } }

captura de pantalla:


Creo que su problema radica en su ArrayAdapter que usa simple_list_item_1. Si observa el código fuente de ese elemento, tiene la propiedad de

android:layout_width="match_parent"

Si miras la fuente here , puedes crear tu propia new_list_item_1.xml con la misma información pero cambiándola a android:layout_width="wrap_content" y luego usar eso en tu ArrayAdapter


El problema es con la implementación de ListPopupWindow . Comprobé el código fuente, y el uso de setContentWidth(ListPopupWindow.WRAP_CONTENT) o setWidth(ListPopupWindow.WRAP_CONTENT) hace que la ventana emergente use el ancho de su vista ancla.


En realidad, puede obtener el elemento primario del anclaje (ya que el anclaje real es generalmente un botón) y basar su ancho desde allí. Por ejemplo:

popup.setWidth(((View)anchor.getParent()).getWidth()/2);

De esta forma puede obtener un ancho flexible.


Otra solución es establecer una vista de altura de 0dp en su diseño xml para usar como ancla.

<View android:id="@+id/popup_anchor" android:layout_width="140dp" android:layout_height="0dp"/>

luego configure la vista de anclaje en algún momento antes de llamar al método show ().

listPopupWindow.setAnchorView(popupAnchor); listPopupWindow.show();


Puede medir el ancho del contenido del adaptador:

private int measureContentWidth(ListAdapter listAdapter) { ViewGroup mMeasureParent = null; int maxWidth = 0; View itemView = null; int itemType = 0; final ListAdapter adapter = listAdapter; final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); final int count = adapter.getCount(); for (int i = 0; i < count; i++) { final int positionType = adapter.getItemViewType(i); if (positionType != itemType) { itemType = positionType; itemView = null; } if (mMeasureParent == null) { mMeasureParent = new FrameLayout(mContext); } itemView = adapter.getView(i, itemView, mMeasureParent); itemView.measure(widthMeasureSpec, heightMeasureSpec); final int itemWidth = itemView.getMeasuredWidth(); if (itemWidth > maxWidth) { maxWidth = itemWidth; } } return maxWidth; }

y en su función showPopup ():

ArrayAdapter arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, STRINGS); popup.setAdapter(arrayAdapter); popup.setAnchorView(anchorView); popup.setContentWidth(measureContentWidth(arrayAdapter));


Solo establecería una dimensión en tu archivo dimen.xml a 160dp o menos:

<dimen name="overflow_width">160dp</dimen>

Luego configure su ancho emergente usando el método getDimensionPixelSize para convertir a píxeles:

int width = mContext.getResources().getDimensionPixelSize(R.dimen.overflow_width); mListPopupWindow.setWidth(width);

Eso debería mantener la densidad de tamaño independiente.


listPopupWindow.setWidth (400);

listPopupWindow.setHeight (ListPopupWindow.WRAP_CONTENT);