Android工具栏溢出菜单视图id

Android工具栏溢出菜单视图id,android,Android,我想做的是在工具栏上显示一个指向溢出图标(三个点)的弹出窗口。所以我需要得到一个带有图标id的视图对象的引用。但是身份证是什么 PopupWindow用于告诉用户溢出菜单中添加了新条目。并建议用户查看。是否要创建自定义的下拉菜单 或者在菜单中使用android:showAsAction=“never”。showAsAction属性的文档。当其中一个MenuItems设置了never值时,您将自动获得溢出三点图标,这些MenuItems将隐藏在那里 如果确实需要,您也可以尝试使用来调查此id您可能

我想做的是在工具栏上显示一个指向溢出图标(三个点)的弹出窗口。所以我需要得到一个带有图标id的视图对象的引用。但是身份证是什么


PopupWindow用于告诉用户溢出菜单中添加了新条目。并建议用户查看。

是否要创建自定义的
下拉菜单

或者在
菜单中使用
android:showAsAction=“never”
showAsAction
属性的文档。当其中一个
MenuItem
s设置了
never
值时,您将自动获得溢出三点图标,这些
MenuItem
s将隐藏在那里


如果确实需要,您也可以尝试使用来调查此id

您可能在菜单资源中创建了一个菜单项xml,以具有一个溢出按钮,因此,您必须使用在菜单xml中指定的溢出按钮项的id。溢出菜单项没有资源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;
}

我找到了一个名为TapTarget的库和一个函数TapTarget.forToolbarOverflow()。它提出了一个解决方案:


它查找溢出视图的方式并不整洁,但应该是稳定的。

我没有使用昂贵而复杂的布局遍历来查找溢出菜单,而是通过使用工具栏视图作为锚点并将重力设置为重力,实现了在溢出菜单下显示弹出窗口。结束:

 /**
  * 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();
 }

您应该创建按钮id


然后创建按钮样式


@id/溢出操作按钮
并在主题中添加此样式


@style/Widget.ActionButton.Overflow

最后,您应该通过id找到按钮视图

activity.findViewById(R.id.overflowActionButton)

然后做你想做的事

否菜单项已经存在。我试图显示一个弹出窗口,告诉用户有几个新的选项添加到溢出菜单。弹出窗口将使溢出菜单中的新条目更容易被发现。可能尝试使用此idIt来调查此idIt是一个黑客解决方案,可能无法在较新的android版本上工作。只要您使用
androidx.appcompat.widget.Toolbar
而不是本机
android.widget.Toolbar
,它只取决于支持库版本,而不是Android版本。每次更新支持库时,都可以轻松测试这一点。
 /**
  * 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();
 }