如何在安卓中获取弹出菜单的高度和宽度?

huangapple go评论73阅读模式
英文:

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
}

huangapple
  • 本文由 发表于 2020年9月7日 11:13:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63770845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定