If you did not find a solution based on a custom action, perhaps you want to use the Custom Toolbar and PopupWindow , which means:
1) create a custom Toolbar using ImageButton as a menu button and replace the ActionBar with it (for example, which was published by Machado );
2) create a PopupWindow with a custom arrangement of menu items with vertical text;
3) add onClickListener to ImageButton from p.1, which show PopupWindow from p.2.
The layout of the custom Toolbar ( action_bar.xml ) might look something like this:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_gravity="fill_horizontal" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:background="@color/colorPrimary" android:elevation="4dp" android:layout_height="?attr/actionBarSize"> </android.support.v7.widget.Toolbar> </RelativeLayout>
The MainActivity layout ( activity_main.xml ) that uses it:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/activity_main" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="0dp" tools:context="<your_package_name>.MainActivity"> <include android:id="@+id/tool_bar" layout="@layout/action_bar"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:layout_marginStart="31dp" android:layout_below="@+id/tool_bar" android:layout_alignParentStart="true" android:layout_marginTop="31dp"/> </RelativeLayout>
ImageButton as the "main popup menu" button described in the main_menu.xml file main_menu.xml this way (more details in this ASH article):
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_button" android:icon="@drawable/ic_more_vert" android:title="" app:showAsAction="always" app:actionViewClass="android.widget.ImageButton"/> </menu>
For vertical text of menu items, you can use, for example, a custom View as VerticalLabelView from this kostmo :
public class VerticalLabelView extends View { private TextPaint mTextPaint; private String mText; private int mAscent; private Rect text_bounds = new Rect(); final static int DEFAULT_TEXT_SIZE = 15; public VerticalLabelView(Context context) { super(context); initLabelView(); } public VerticalLabelView(Context context, AttributeSet attrs) { super(context, attrs); initLabelView(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalLabelView); CharSequence s = a.getString(R.styleable.VerticalLabelView_text); if (s != null) setText(s.toString()); setTextColor(a.getColor(R.styleable.VerticalLabelView_textColor, 0xFF000000)); int textSize = a.getDimensionPixelOffset(R.styleable.VerticalLabelView_textSize, 0); if (textSize > 0) setTextSize(textSize); a.recycle(); } private final void initLabelView() { mTextPaint = new TextPaint(); mTextPaint.setAntiAlias(true); mTextPaint.setTextSize(DEFAULT_TEXT_SIZE); mTextPaint.setColor(0xFF000000); mTextPaint.setTextAlign(Align.CENTER); setPadding(3, 3, 3, 3); } public void setText(String text) { mText = text; requestLayout(); invalidate(); } public void setTextSize(int size) { mTextPaint.setTextSize(size); requestLayout(); invalidate(); } public void setTextColor(int color) { mTextPaint.setColor(color); invalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mTextPaint.getTextBounds(mText, 0, mText.length(), text_bounds); setMeasuredDimension( measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); } private int measureWidth(int measureSpec) { int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) {
(NB: maybe you need to set up paddings VerticalLabelView : on line result = text_bounds.height() + getPaddingLeft() + getPaddingRight() + 16; add "+16" for better filling)
and attrs.xml for the VerticalLabelView class:
<resources> <declare-styleable name="VerticalLabelView"> <attr name="text" format="string" /> <attr name="textColor" format="color" /> <attr name="textSize" format="dimension" /> </declare-styleable> </resources>
The layout for PopupWindow ( menu_layout.xml ) in this case may be as follows:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/menu_root" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="@dimen/activity_horizontal_margin"> <<your_package_name>.VerticalLabelView android:id="@+id/menu_item1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="18sp" android:layout_margin="16dp" android:padding="4dp" android:text="Vertical menu item 1"/> <<your_package_name>.VerticalLabelView android:id="@+id/menu_item2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="18sp" android:layout_margin="16dp" android:padding="4dp" android:text="Vertical menu item 2"/> <<your_package_name>.VerticalLabelView android:id="@+id/menu_item3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="18sp" android:layout_margin="16dp" android:padding="4dp" android:text="Vertical menu item 3"/> <<your_package_name>.VerticalLabelView android:id="@+id/menu_item4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@android:color/white" android:textSize="18sp" android:layout_margin="16dp" android:padding="4dp" android:text="Vertical menu item 4"/> </LinearLayout>
And the MainActivity class can be as follows:
public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private Toolbar mToolbar; private int mToolbarTitleColor; private ImageButton mMainMenuButton; private int mActionBarSize; private PopupWindow mPopupMenu; private int mTextSize = 48; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TypedValue tv = new TypedValue(); if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { mActionBarSize = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics()); } mToolbarTitleColor = Color.WHITE; mToolbar = (Toolbar) findViewById(R.id.toolbar); mToolbar.setTitleTextColor(mToolbarTitleColor); setSupportActionBar(mToolbar); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); Drawable menuIcon = ContextCompat.getDrawable(this, R.drawable.ic_more_vert); menuIcon.setColorFilter(mToolbarTitleColor, PorterDuff.Mode.SRC_ATOP); getMenuInflater().inflate(R.menu.main_menu, menu); mMainMenuButton = (ImageButton) menu.findItem(R.id.menu_button).getActionView(); mMainMenuButton.setBackground(null); mMainMenuButton.setImageDrawable(menuIcon); mMainMenuButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mPopupMenu != null && mPopupMenu.isShowing()) { mPopupMenu.dismiss(); } mPopupMenu = createPopupMenu(); mPopupMenu.showAtLocation(v, Gravity.TOP | Gravity.RIGHT, 0, mActionBarSize); } }); return true; } public PopupWindow createPopupMenu() { final PopupWindow popupWindow = new PopupWindow(this); LayoutInflater inflater = getLayoutInflater(); View popupView = inflater.inflate(R.layout.menu_layout, null); VerticalLabelView menuItem1 = (VerticalLabelView)popupView.findViewById(R.id.menu_item1); menuItem1.setOnClickListener(mOnMenuItemClickListener); menuItem1.setText("Vertical menu item 1"); menuItem1.setTextColor(Color.WHITE); menuItem1.setTextSize(mTextSize); VerticalLabelView menuItem2 = (VerticalLabelView)popupView.findViewById(R.id.menu_item2); menuItem2.setOnClickListener(mOnMenuItemClickListener); menuItem2.setText("Vertical menu item 2"); menuItem2.setTextColor(Color.WHITE); menuItem2.setTextSize(mTextSize); VerticalLabelView menuItem3 = (VerticalLabelView)popupView.findViewById(R.id.menu_item3); menuItem3.setOnClickListener(mOnMenuItemClickListener); menuItem3.setText("Vertical menu item 3"); menuItem3.setTextColor(Color.WHITE); menuItem3.setTextSize(mTextSize); VerticalLabelView menuItem4 = (VerticalLabelView)popupView.findViewById(R.id.menu_item4); menuItem4.setOnClickListener(mOnMenuItemClickListener); menuItem4.setText("Vertical menu item 4"); menuItem4.setTextColor(Color.WHITE); menuItem4.setTextSize(mTextSize); popupWindow.setFocusable(true); popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setContentView(popupView); return popupWindow; } private View.OnClickListener mOnMenuItemClickListener = new View.OnClickListener() { @Override public void onClick(View view) { switch (view.getId()) { case R.id.menu_item1: { Log.d(TAG, "menu_item1"); } break; case R.id.menu_item2: { Log.d(TAG, "menu_item2"); } break; case R.id.menu_item3: { Log.d(TAG, "menu_item3"); } case R.id.menu_item4: { Log.d(TAG, "menu_item4"); } break; default: { } } if (mPopupMenu != null && mPopupMenu.isShowing()) { mPopupMenu.dismiss(); } } }; }
Ultimately, you should end up with something like this:

PS Of course, you need a more elegant solution for createPopupMenu() .