Android工具栏溢出菜单视图ID

5
我要做的是显示一个指向工具栏溢出图标(三个点)的 PopupWindow。因此,我需要获取具有该图标 id 的 View 对象的引用。但是这个 id 是什么呢?
PopupWindow 用于告诉用户溢出菜单中添加了新条目,并建议用户检查它。
5个回答

7

你应该创建按钮的id

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="id" name="overflowActionButton"/>
</resources>

然后创建按钮样式。
<style name="Widget.ActionButton.Overflow" parent="Widget.AppCompat.ActionButton.Overflow">
    <item name="android:id">@id/overflowActionButton</item>
</style>

并在主题中添加此样式
<style name="Theme.App" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
</style>

enter image description here

最后,您应该通过ID找到按钮视图。
activity.findViewById(R.id.overflowActionButton)

并且做你想做的事


5

溢出菜单项没有资源ID。我通过遍历工具栏找到了溢出视图。调试器显示ID为-1,层次结构查看器未显示任何资源ID。

以下是我找到没有资源ID的溢出视图的方法:

/**
 * Get the OverflowMenuButton.
 *
 * @param activity
 *     the Activity
 * @return the OverflowMenuButton or {@code null} if it doesn't exist.
 */
public static ImageView getOverflowMenuButton(Activity activity) {
  return findOverflowMenuButton(activity, findActionBar(activity));
}

static ImageView findOverflowMenuButton(Activity activity, ViewGroup viewGroup) {
  if (viewGroup == null) {
    return null;
  }
  ImageView overflow = null;
  for (int i = 0, count = viewGroup.getChildCount(); i < count; i++) {
    View v = viewGroup.getChildAt(i);
    if (v instanceof ImageView && (v.getClass().getSimpleName().equals("OverflowMenuButton") ||
        v instanceof ActionMenuView.ActionMenuChildView)) {
      overflow = (ImageView) v;
    } else if (v instanceof ViewGroup) {
      overflow = findOverflowMenuButton(activity, (ViewGroup) v);
    }
    if (overflow != null) {
      break;
    }
  }
  return overflow;
}

static ViewGroup findActionBar(Activity activity) {
  try {
    int id = activity.getResources().getIdentifier("action_bar", "id", "android");
    ViewGroup actionBar = null;
    if (id != 0) {
      actionBar = (ViewGroup) activity.findViewById(id);
    }
    if (actionBar == null) {
      return findToolbar((ViewGroup) activity.findViewById(android.R.id.content).getRootView());
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
  return null;
}

static ViewGroup findToolbar(ViewGroup viewGroup) {
  ViewGroup toolbar = null;
  for (int i = 0, len = viewGroup.getChildCount(); i < len; i++) {
    View view = viewGroup.getChildAt(i);
    if (view.getClass() == android.support.v7.widget.Toolbar.class ||
        view.getClass().getName().equals("android.widget.Toolbar")) {
      toolbar = (ViewGroup) view;
    } else if (view instanceof ViewGroup) {
      toolbar = findToolbar((ViewGroup) view);
    }
    if (toolbar != null) {
      break;
    }
  }
  return toolbar;
}

onCreate调用getOverflowMenuButton(activity)会返回null,因为溢出菜单还没有被布局。为了在onCreate中获取溢出菜单,可以按照以下步骤进行操作:

findViewById(android.R.id.content).post(new Runnable() {
  @Override public void run() {
    ImageView overflow = getOverflowMenuButton(MainActivity.this);
  }
});

1

这是一种不太靠谱的解决方案,可能在新版本的安卓系统上无法使用。 - android_dev
只要使用 androidx.appcompat.widget.Toolbar 而不是原生的 android.widget.Toolbar,它仅取决于支持库版本,而不是 Android 版本。这是每次更新支持库时都可以轻松测试的内容。 - devconsole

0

不必使用昂贵且复杂的布局遍历来查找溢出菜单,我已经通过使用工具栏视图作为锚点并将重力设置为Gravity.END来实现在溢出菜单下方显示PopupWindow:

 /**
  * Sets the anchor view and shows the popup. In case of narrow display the menu items may be hidden in an overflow
  * menu, in that case anchorView may be null and the popup will be anchored to the end of the toolbar.
  */
 public void show(@Nullable View anchorView, @NonNull View toolbarView) {
     if (anchorView == null) {
         setDropDownGravity(Gravity.END);
         setAnchorView(toolbarView);
     } else {
         setAnchorView(anchorView);
     }
     show();
 }

0

你想要创建自定义的DropDown菜单吗?考虑使用这种“本地”的方式

或者在你的menu.xml中使用android:showAsAction="never"。关于showAsAction属性的文档在这里。当其中一个MenuItem设置了never值时,你将自动获得溢出的三个点图标,并且这些MenuItem将被隐藏在那里。

此外,如果确实需要,你也可以尝试使用Hierarchy Viewer来调查这个id。


没有菜单项需要添加。我正在尝试显示一个弹出窗口,告诉用户溢出菜单中添加了几个新选项。弹出窗口将使溢出菜单中的新条目更易于发现。 - darklord
也许可以尝试使用Hierarchy Viewer来调查此ID。 - snachmsm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接