Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the margin of the overflow menu in Android

Tags:

android

Here's the default position of the contextual menu in Android:

default position

However, the app Inbox has it farther from the top and the right edges of the screen:

inbox

Is there a relatively straight-forward way to achieve this?

like image 462
espinchi Avatar asked Jan 15 '16 04:01

espinchi


2 Answers

Is there a relatively straight-forward way to achieve this?

Yes, of course. And, it only requires 5 lines of code.

Konstantin Loginov takes a bottom-up approach where you literally handle everything in code/design. As much as I appreciate the said approach, it adds complexity to your source. Its always better to check whether a top-down approach is available before resorting to a custom solution.

Here's the top-down version:

Following line will go inside your activity's base theme definition:

<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>

The style OverflowMenuStyle will be defined as:

<style name="OverflowMenuStyle" parent="Widget.AppCompat.PopupMenu.Overflow">
    <item name="android:dropDownHorizontalOffset">-16dp</item>
    <item name="android:dropDownVerticalOffset">16dp</item>
</style>

Results:

Unstyled:

enter image description here

Styled:

enter image description here

Additional notes (possibly trivial to you, but they may help others):

A typical app-theme setup is:

/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 />

In this kind of setup, actionOverflowMenuStyle will be defined under BaseTheme. Note the absence of android: prefix - we are overriding actionOverflowMenuStyle provided by appcompat library, not the android system.

like image 83
Vikram Avatar answered Sep 24 '22 19:09

Vikram


About Inbox app

What you see on the screenshot, is not exactly a Menu, but a FrameLayout with background with shadows. It's just a custom View.

enter image description here
You can check it with UI Automator Viewer

So you can do same trick and instead of inflating PopupMenu, create a custom View and place it wherever you want.

How to archive same behaviour as a Menu

First, generate background for the popup menu by using Android Action Bar Style Generator(or create a 9patch background by your own).

Then, take menu_dropdown_panel.9 file:

enter image description here

and add paddings there (I used Paint.NET to do it: resize the canvas, insert old image back and move black lines to the sides of the canvas):

enter image description here

Set new background as android:popupBackground in styles:

<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>

Result looks like this:

enter image description hereenter image description here
(vertical position depends on the anchor you passes to PopupMenu's constructor)

To show this PopupMenu, I use this code:

PopupMenu popup = new PopupMenu(MainActivity.this, fab);
popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
popup.show();

I hope, it helps

like image 31
Konstantin Loginov Avatar answered Sep 22 '22 19:09

Konstantin Loginov