web-dev-qa-db-ja.com

ListPopupWindowがWRAP_CONTENT幅仕様に従っていない

ListPopupWindowを使用して、ArrayAdapterを介して文字列のリストを表示しようとしています(最終的には、これはより複雑なカスタムアダプターになります)。コードは以下のとおりです。スクリーンショットに示すように、結果のListPopupWindowは、コンテンツの幅がゼロであるかのように動作するようです。適切な数のアイテムが表示され、アイテムは引き続きクリック可能であり、クリックするとToastが正常に生成されるため、少なくともそれだけが適切に機能しています。

興味深いメモ:_ListPopupWindow.WRAP_CONTENT_の代わりにpopup.setWidth(...)にピクセル単位の幅を指定すると、コンテンツの一部が表示されますが、これは柔軟性に欠けるようです。

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

38
Karakuri

問題は、ListPopupWindowの実装にあります。ソースコードを確認し、setContentWidth(ListPopupWindow.WRAP_CONTENT)またはsetWidth(ListPopupWindow.WRAP_CONTENT)を使用すると、ポップアップウィンドウのアンカービューの幅が代わりに使用されます。

26
Karakuri

アダプターコンテンツの幅を測定できます。

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

使用するのに最適なのは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();
7

Dimen.xmlファイルのディメンションを160dp程度に設定します。

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

次に、getDimensionPixelSizeメソッドを使用してポップアップの幅を設定し、ピクセルに変換します。

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

これにより、サイズ密度を独立させることができます。

4
JaredBanyard

実際にanchorViewの親を取得し(実際のanchorViewは通常ボタンであるため)、そこから幅をベースにすることができます。例えば:

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

これにより、幅を柔軟に設定できます。

3
Caio L.

あなたの問題は、simple_list_item_1を使用するArrayAdapterにあると思います。その要素のソースコードを見ると、次のプロパティがあります。

Android:layout_width="match_parent"

ソースを見ると here 同じ情報で独自のnew_list_item_1.xmlを作成できますが、それをAndroid:layout_width="wrap_content"に変更してから、ArrayAdapterで使用できます。

3
Mike

別の解決策は、レイアウトxmlで0dp高さビューを設定してアンカーとして使用することです。

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

次に、show()メソッドを呼び出す前に、アンカービューを設定します。

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

以下が役立ちます。

listPopupWindow.setWidth(400);
listPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);
0
Pankaj Sharma