<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
样式OverflowMenuStyle
将被定义为:
<style name="OverflowMenuStyle" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="android:dropDownHorizontalOffset">-16dp</item>
<item name="android:dropDownVerticalOffset">16dp</item>
</style>
结果:
未样式化的:
样式化:
附加说明(对您可能微不足道,但它们可能有助于他人):
典型的应用程序主题设置如下:
/res/values/styles.xml:
<!-- Values defined here apply to all supported API versions unless overridden in children -->
<BaseTheme />
<!-- Defined values apply to all supported API versions unless overridden in res/values-vXX/styles.xml -->
<AppTheme extends BaseTheme />
/res/values-vXX/styles.xml:
<!-- Values defined here apply to all API versions >= XX unless overridden in res/values-vYY/styles.xml where YY > XX -->
<AppTheme extends BaseTheme />
actionOverflowMenuStyle
将在BaseTheme
下定义。请注意缺少android:
前缀 - 我们正在覆盖由appcompat库提供的actionOverflowMenuStyle
,而不是Android系统。你在截图中看到的并不是一个普通的Menu
,而是带有阴影背景的FrameLayout
。它只是一个自定义视图。
你可以使用UI Automator Viewer进行检查。
因此,你也可以使用同样的技巧,而不是充气弹出式菜单PopupMenu
,创建一个自定义的View
,并将其放置在任何你想要的地方。
Menu
相同的行为首先,通过使用Android Action Bar Style Generator(或自己创建一个9patch背景)为弹出菜单生成背景。
然后,获取menu_dropdown_panel.9文件:
并在其中添加间距(我使用Paint.NET:调整画布大小,重新插入旧图像并将黑线移动到画布的两侧):
在样式中将新背景设置为android:popupBackground
:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="popupMenuStyle">@style/PopupMenu.Example</item>
</style>
<style name="PopupMenu.Example" parent="@style/Widget.AppCompat.Light.PopupMenu">
<item name="android:popupBackground">@drawable/menu_dropdown_panel_background</item>
</style>
结果看起来像这样:
使用以下代码显示此PopupMenu
:
PopupMenu popup = new PopupMenu(MainActivity.this, fab);
popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
popup.show();
I hope, it helps
PopupMenu
与Toolbar
重叠的情况。运行得非常好 :-) - Konstantin Loginov <style name="OverflowMenu" parent="Widget.AppCompat.PopupMenu.Overflow" tools:targetApi="21">
<item name="overlapAnchor">false</item>
<!--<item name="dropDownVerticalOffset">?attr/actionBarSize</item>-->
<item name="android:overlapAnchor">false</item>
</style>
<item name="actionOverflowMenuStyle">@style/OverflowMenu</item>
没有直接的方法。但是有一种方法可以模拟这种行为或者创造一种它发生的幻觉。
类似的问题已经在this post中得到了回答。虽然问题略有不同,但答案可能也适用于您的目的。
与其拥有一个实际的溢出菜单,你可以“欺骗”一下。在你的操作栏中放置一个看起来像溢出图标的图标。你应该将
showAsAction
设置为始终在这个MenuItem
上显示。在溢出图标的OnClick事件中,你可以显示一个锚定在MenuItem
视图上的ListPopupWindow
。如果ListPopupWindow
没有出现在您想要的位置,您可以调用ListPopupWindow.setHorizontalOffset()
和ListPopupWindow.setVerticalOffset()
我认为这正是你所需要的,你需要自定义视图。
public void onClick(View v) {
// code from above
// ...
popupMenu.show();
// Try to force some horizontal offset
try {
Field fListPopup = menuHelper.getClass().getDeclaredField("mPopup");
fListPopup.setAccessible(true);
Object listPopup = fListPopup.get(menuHelper);
argTypes = new Class[] { int.class };
Class listPopupClass = listPopup.getClass();
// Get the width of the popup window
int width = (Integer) listPopupClass.getDeclaredMethod("getWidth").invoke(listPopup);
// Invoke setHorizontalOffset() with the negative width to move left by that distance
listPopupClass.getDeclaredMethod("setHorizontalOffset", argTypes).invoke(listPopup, -width);
// Invoke show() to update the window's position
listPopupClass.getDeclaredMethod("show").invoke(listPopup);
} catch (Exception e) {
// Again, an exception here indicates a programming error rather than an exceptional condition
// at runtime
Log.w(TAG, "Unable to force offset", e);
}
}
更多信息请查看this
使用默认的溢出菜单实现这个功能并不是很容易。我猜他们添加了一个自定义的溢出按钮来打开一个自定义的Activity(覆盖ActionBar),该Activity具有透明的根视图,以及一个大小和位置合适的CardView用于显示部分。CardView负责边框和高程效果,但可能还有自定义的打开动画。这是定制工作。