I have the following Android menu XML file:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/programma"
android:icon="@android:drawable/ic_menu_agenda"
android:title="@string/programma" />
<item android:id="@+id/settings"
android:icon="@android:drawable/ic_menu_preferences"
android:title="@string/settings" />
<item android:id="@+id/help"
android:icon="@android:drawable/ic_menu_help"
android:title="@string/help" />
</menu>
That gives me three menu buttons on one line. However, I want to divide them in two lines, with 2 buttons on the first row, and the help button on the entire bottom row. I already tried grouping the first two, but that didn't do the trick.
How can I force a line break in the XML?
As far as I know there is no way to force line break in menu. This actually makes sense if you consider some scenarios.
For example, imagine you have tablet (for example, Galaxy Tab) in landscape orientation. It has quite a lot of horizontal space and relatively small height. So, it would be a waste of space if you force line break in such case.
I've done more investigation on this. There is a class called MenuBuilder
which is used to manage options menu. It uses icon_menu_layout
layout resource to draw menus. Here is this resource:
<com.android.internal.view.menu.IconMenuView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+android:id/icon_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rowHeight="66dip"
android:maxItems="6"
android:maxRows="2"
android:maxItemsPerRow="6" />
And if you follow to IconMenuView
implementation, you'll find one interesting function called layoutItems
which is used to calculate layout for menu items. You can only influence this function's logic by artificially increasing width of menu items. No line breaks are available.
private void layoutItems(int width) {
int numItems = getChildCount();
if (numItems == 0) {
mLayoutNumRows = 0;
return;
}
// Start with the least possible number of rows
int curNumRows =
Math.min((int) Math.ceil(numItems / (float) mMaxItemsPerRow), mMaxRows);
/*
* Increase the number of rows until we find a configuration that fits
* all of the items' titles. Worst case, we use mMaxRows.
*/
for (; curNumRows <= mMaxRows; curNumRows++) {
layoutItemsUsingGravity(curNumRows, numItems);
if (curNumRows >= numItems) {
// Can't have more rows than items
break;
}
if (doItemsFit()) {
// All the items fit, so this is a good configuration
break;
}
}
}
So, for example, if you increase width of first item, you'll get two lines in menu. But this is probably undesirable, because you can't predict text style, size and font that will be used on different devices.