ListPopupWindow не подчиняется спецификации ширины WRAP_CONTENT
Я пытаюсь использовать ListPopupWindow для отображения списка строк через ArrayAdapter
(в конечном итоге это будет более сложный пользовательский адаптер). Код ниже. Как показано на скриншоте, результат ListPopupWindow
, похоже, действует так, как будто ширина содержимого равна нулю. Он показывает правильное количество элементов, элементы по-прежнему доступны для клика, а нажатие успешно создает Toast
, поэтому, по крайней мере, это работает правильно.
Интересное замечание: я могу предоставить ширину в пикселях до popup.setWidth(...)
вместо ListPopupWindow.WRAP_CONTENT
, и она покажет часть содержимого, но это кажется очень негибким.
Как сделать ListPopupWindow
завершение его содержимого?
Тестовая активность:
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();
}
}
скриншот:
![enter image description here]()
Ответы
Ответ 1
Проблема заключается в реализации ListPopupWindow
. Я проверил исходный код, и используя setContentWidth(ListPopupWindow.WRAP_CONTENT)
или setWidth(ListPopupWindow.WRAP_CONTENT)
, вместо всплывающего окна используется ширина его якорного вида.
Ответ 2
Вы можете измерить ширину содержимого адаптера:
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;
}
и в вашей функции 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));
Ответ 3
Я думаю, что лучше всего использовать PopupMenu. Пример:
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();
Ответ 4
Я бы просто установил измерение в файле dimen.xml на 160dp или около того:
<dimen name="overflow_width">160dp</dimen>
Затем установите ширину всплывающего окна, используя метод getDimensionPixelSize для преобразования в пиксели:
int width = mContext.getResources().getDimensionPixelSize(R.dimen.overflow_width);
mListPopupWindow.setWidth(width);
Это должно поддерживать независимость от плотности размера.
Ответ 5
Я считаю, что ваша проблема связана с вашим ArrayAdapter, используя simple_list_item_1. Если вы посмотрите на исходный код этого элемента, он имеет свойство
android:layout_width="match_parent"
Если вы посмотрите на источник здесь, вы можете создать свой собственный new_list_item_1.xml с той же информацией, но изменив его на android:layout_width="wrap_content"
, а затем используйте это в своем ArrayAdapter
Ответ 6
Фактически вы можете получить родительский элемент anchorView (поскольку фактическое anchorView обычно является кнопкой) и основывать свою ширину. Например:
popup.setWidth(((View)anchor.getParent()).getWidth()/2);
Таким образом, вы можете получить гибкую ширину.
Ответ 7
listPopupWindow.setWidth(400);
listPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);
Ответ 8
Другим решением является установка вида высоты 0dp в вашем макете xml для использования в качестве привязки.
<View
android:id="@+id/popup_anchor"
android:layout_width="140dp"
android:layout_height="0dp"/>
затем установите якорный вид когда-нибудь перед вызовом метода show().
listPopupWindow.setAnchorView(popupAnchor);
listPopupWindow.show();