Fix bug 5191728 - Specialized formatting in the split action bar
Visually center a single text menu item in the split action bar even
when an overflow button is present.
Fix a bug in allocating space in the split action bar.
Change-Id: I54eff86bf35197030c9c1656ebd71297e3c8b62b
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index d613921..b355c41 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -31,6 +31,7 @@
private static final String TAG = "ActionMenuView";
static final int MIN_CELL_SIZE = 56; // dips
+ static final int GENERATED_ITEM_PADDING = 4; // dips
private MenuBuilder mMenu;
@@ -39,6 +40,7 @@
private boolean mFormatItems;
private int mFormatItemsWidth;
private int mMinCellSize;
+ private int mGeneratedItemPadding;
private int mMeasuredExtraWidth;
public ActionMenuView(Context context) {
@@ -48,7 +50,9 @@
public ActionMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
setBaselineAligned(false);
- mMinCellSize = (int) (MIN_CELL_SIZE * context.getResources().getDisplayMetrics().density);
+ final float density = context.getResources().getDisplayMetrics().density;
+ mMinCellSize = (int) (MIN_CELL_SIZE * density);
+ mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density);
}
public void setPresenter(ActionMenuPresenter presenter) {
@@ -133,8 +137,15 @@
final View child = getChildAt(i);
if (child.getVisibility() == GONE) continue;
+ final boolean isGeneratedItem = child instanceof ActionMenuItemView;
visibleItemCount++;
+ if (isGeneratedItem) {
+ // Reset padding for generated menu item views; it may change below
+ // and views are recycled.
+ child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0);
+ }
+
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
lp.expanded = false;
lp.extraPixels = 0;
@@ -142,6 +153,7 @@
lp.expandable = false;
lp.leftMargin = 0;
lp.rightMargin = 0;
+ lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText();
// Overflow always gets 1 cell. No more, no less.
final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
@@ -158,6 +170,10 @@
if (cellsUsed == 1) smallestItemsAt |= (1 << i);
}
+ // When we have overflow and a single expanded (text) item, we want to try centering it
+ // visually in the available space even though overflow consumes some of it.
+ final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2;
+
// Divide space for remaining cells if we have items that can expand.
// Try distributing whole leftover cells to smaller items first.
@@ -184,16 +200,27 @@
}
}
- if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
-
// Items that get expanded will always be in the set of smallest items when we're done.
smallestItemsAt |= minCellsAt;
- for (int i = 0; i < childCount; i++) {
- if ((minCellsAt & (1 << i)) == 0) continue;
+ if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
+ // We have enough cells, all minimum size items will be incremented.
+ minCells++;
+
+ for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if ((minCellsAt & (1 << i)) == 0) {
+ // If this item is already at our small item count, mark it for later.
+ if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i;
+ continue;
+ }
+
+ if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) {
+ // Add padding to this item such that it centers.
+ child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0);
+ }
lp.cellsUsed++;
lp.expanded = true;
cellsRemaining--;
@@ -207,16 +234,18 @@
final boolean singleItem = !hasOverflow && visibleItemCount == 1;
if (cellsRemaining > 0 && smallestItemsAt != 0 &&
- (cellsRemaining < visibleItemCount - 1 || singleItem)) {
+ (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) {
float expandCount = Long.bitCount(smallestItemsAt);
if (!singleItem) {
// The items at the far edges may only expand by half in order to pin to either side.
if ((smallestItemsAt & 1) != 0) {
- expandCount -= 0.5f;
+ LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams();
+ if (!lp.preventEdgeOffset) expandCount -= 0.5f;
}
if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
- expandCount -= 0.5f;
+ LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams());
+ if (!lp.preventEdgeOffset) expandCount -= 0.5f;
}
}
@@ -232,7 +261,7 @@
// If this is one of our views, expand and measure at the larger size.
lp.extraPixels = extraPixels;
lp.expanded = true;
- if (i == 0) {
+ if (i == 0 && !lp.preventEdgeOffset) {
// First item gets part of its new padding pushed out of sight.
// The last item will get this implicitly from layout.
lp.leftMargin = -extraPixels / 2;
@@ -496,6 +525,8 @@
public int extraPixels;
@ViewDebug.ExportedProperty(category = "layout")
public boolean expandable;
+ @ViewDebug.ExportedProperty(category = "layout")
+ public boolean preventEdgeOffset;
public boolean expanded;