英文:
How to get height and width of a popup menu in android?
问题
我有一个弹出菜单,我只想获取它的尺寸以在我的引导游览ShowCaseView中使用。我找不到任何地方可以确定这些尺寸(高度和宽度)的方法。
private void initPopUpMenu() {
PopupMenu popupMenu = new PopupMenu(TimelineActivity.this, menuIcon);
popupMenu.getMenuInflater().inflate(R.menu.menu_timeline, popupMenu.getMenu());
}
如何从这个结构中检索宽度和高度?这是一个简单的菜单资源,包含5个项目。
英文:
I have a popup menu and I just want to get dimensions of it to use in my showCaseView for my guided tour. I could not find anywhere the way to determine these dimensions (height and width).
private void initPopUpMenu() {
PopupMenu popupMenu = new PopupMenu(TimelineActivity.this, menuIcon);
popupMenu.getMenuInflater().inflate(R.menu.menu_timeline, popupMenu.getMenu());
}
How to retrieve width and height from this structure? It's a simple menu resource with 5 items
答案1
得分: 2
最佳解决方案是使用ListPopupWindow,而不是PopupMenu,它具有getWidth()和getHeight()方法来获取其尺寸。但是,如果您真的想使用PopupMenu,可能的棘手方法是使用Reflection来访问其内部的ListView,因为PopupMenu中没有可用于访问内容视图的方法。
用法:
PopupMenu popupMenu = initPopUpMenu();
popupMenu.show();
ListView listView = getPopupMenuListView(popupMenu);
androidx.core.view.ViewKt.doOnLayout(listView, view -> {
System.out.println("PopupMenu尺寸: " + view.getWidth() + " x " + view.getHeight());
return null;
});
方法:
private PopupMenu initPopUpMenu() {
PopupMenu popupMenu = new PopupMenu(TimelineActivity.this, menuIcon);
popupMenu.getMenuInflater().inflate(R.menu.menu_timeline, popupMenu.getMenu());
return popupMenu;
}
private ListView getPopupMenuListView(PopupMenu popupMenu) {
Method getMenuListViewMethod = null;
try {
getMenuListViewMethod = PopupMenu.class.getDeclaredMethod("getMenuListView");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
ListView listView = null;
if (getMenuListViewMethod != null) {
getMenuListViewMethod.setAccessible(true);
try {
listView = (ListView) getMenuListViewMethod.invoke(popupMenu);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return listView;
}
build.gradle:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.3.0'
}
结果:
I/System.out: PopupMenu尺寸: 539 x 660
英文:
The best solution is to use ListPopupWindow instead of PopupMenu which has getWidth() and getHeight() methods to get its dimensions. However, if you really want to use PopupMenu, the possible tricky way is to use Reflection to access its internal ListView, because there is no method available in PopupMenu to access the content view.
Usage:
PopupMenu popupMenu = initPopUpMenu();
popupMenu.show();
ListView listView = getPopupMenuListView(popupMenu);
androidx.core.view.ViewKt.doOnLayout(listView, view -> {
System.out.println("PopupMenu Size: " + view.getWidth() + " x " + view.getHeight());
return null;
});
Methods:
private PopupMenu initPopUpMenu() {
PopupMenu popupMenu = new PopupMenu(TimelineActivity.this, menuIcon);
popupMenu.getMenuInflater().inflate(R.menu.menu_timeline, popupMenu.getMenu());
return popupMenu;
}
private ListView getPopupMenuListView(PopupMenu popupMenu) {
Method getMenuListViewMethod = null;
try {
getMenuListViewMethod = PopupMenu.class.getDeclaredMethod("getMenuListView");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
ListView listView = null;
if (getMenuListViewMethod != null) {
getMenuListViewMethod.setAccessible(true);
try {
listView = (ListView) getMenuListViewMethod.invoke(popupMenu);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return listView;
}
build.gradle:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.3.0'
}
Result:
> I/System.out: PopupMenu Size: 539 x 660
答案2
得分: 0
你可以使用自定义布局与 PopupWindow,然后进行测量
val popupWindow = PopupWindow(context)
popupWindow.contentView = View.inflate(context, R.layout.my_popup, null).apply {
measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
)
measuredWidth// <-- 这里是宽度
measuredHeight// <-- 这里是高度
}
英文:
You can use custom layout with PopupWindow and then measure it
val popupWindow = PopupWindow(context)
popupWindow.contentView = View.inflate(context, R.layout.my_popup, null).apply {
measure(
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
)
measuredWidth// <-- here is width
measuredHeight// <-- here is height
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论