可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to use ListPopupWindow to show a list of strings via an ArrayAdapter
(eventually this will be a more complex custom adapter). Code is below. As shown in the screenshot, the resulting ListPopupWindow
seems to act as if the content width is zero. It shows the proper number of items, the items are still clickable, and clicking successfully produce a Toast
, so at least that much is working properly.
An interesting note: I could supply a width in pixels to popup.setWidth(...)
instead of ListPopupWindow.WRAP_CONTENT
and it will show some of the content, but this seems very inflexible.
How do I make the ListPopupWindow
wrap its content?
Test activity:
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();
}
}
screenshot:
回答1:
You could measure the width of the adapter content:
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;
}
and in your showPopup() function:
ArrayAdapter arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, STRINGS);
popup.setAdapter(arrayAdapter);
popup.setAnchorView(anchorView);
popup.setContentWidth(measureContentWidth(arrayAdapter));
回答2:
The problem is with the implementation of ListPopupWindow
. I checked the source code, and using setContentWidth(ListPopupWindow.WRAP_CONTENT)
or setWidth(ListPopupWindow.WRAP_CONTENT)
makes the popup window use the width of its anchor view instead.
回答3:
I think the best thing to use is the PopupMenu . example:
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:
I would just set a dimension in your dimen.xml file at 160dp or so:
<dimen name="overflow_width">160dp</dimen>
Then set your popup width using the getDimensionPixelSize method to convert into pixels:
int width = mContext.getResources().getDimensionPixelSize(R.dimen.overflow_width);
mListPopupWindow.setWidth(width);
That should keep the size density independent.
回答5:
I believe that your issue lies with your ArrayAdapter using simple_list_item_1. If you look at the source code for that element it has the property of
android:layout_width="match_parent"
If you look at the source here you can create your own new_list_item_1.xml with the same info but changing it to android:layout_width="wrap_content"
and then use that in your ArrayAdapter
回答6:
You can actually get the anchorView's parent (since the actual anchorView is generally a button) and base your width from there. For example:
popup.setWidth(((View)anchor.getParent()).getWidth()/2);
That way you can get a flexible width.
回答7:
Another solution is to set a 0dp height view in your layout xml to use as an anchor.
<View
android:id="@+id/popup_anchor"
android:layout_width="140dp"
android:layout_height="0dp"/>
then set the anchor view sometime before calling the show() method.
listPopupWindow.setAnchorView(popupAnchor);
listPopupWindow.show();
回答8:
The following can help;
listPopupWindow.setWidth(400);
listPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);