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();
}
}
_
スクリーンショット:
問題は、ListPopupWindow
の実装にあります。ソースコードを確認し、setContentWidth(ListPopupWindow.WRAP_CONTENT)
またはsetWidth(ListPopupWindow.WRAP_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;
}
そしてあなたの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));
使用するのに最適なのは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();
Dimen.xmlファイルのディメンションを160dp程度に設定します。
<dimen name="overflow_width">160dp</dimen>
次に、getDimensionPixelSizeメソッドを使用してポップアップの幅を設定し、ピクセルに変換します。
int width = mContext.getResources().getDimensionPixelSize(R.dimen.overflow_width);
mListPopupWindow.setWidth(width);
これにより、サイズ密度を独立させることができます。
実際にanchorViewの親を取得し(実際のanchorViewは通常ボタンであるため)、そこから幅をベースにすることができます。例えば:
popup.setWidth(((View)anchor.getParent()).getWidth()/2);
これにより、幅を柔軟に設定できます。
あなたの問題は、simple_list_item_1を使用するArrayAdapterにあると思います。その要素のソースコードを見ると、次のプロパティがあります。
Android:layout_width="match_parent"
ソースを見ると here 同じ情報で独自のnew_list_item_1.xmlを作成できますが、それをAndroid:layout_width="wrap_content"
に変更してから、ArrayAdapterで使用できます。
別の解決策は、レイアウトxmlで0dp高さビューを設定してアンカーとして使用することです。
<View
Android:id="@+id/popup_anchor"
Android:layout_width="140dp"
Android:layout_height="0dp"/>
次に、show()メソッドを呼び出す前に、アンカービューを設定します。
listPopupWindow.setAnchorView(popupAnchor);
listPopupWindow.show();
以下が役立ちます。
listPopupWindow.setWidth(400);
listPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);