ListPopupWindow not obeying WRAP_CONTENT width spec

依然范特西╮ 提交于 2019-12-02 20:06:29
alerant

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));

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.

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();

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.

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

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.

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();
Pankaj Sharma

The following can help;

listPopupWindow.setWidth(400);
listPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!