Revisiting ActionBar API and layout.
Fix several bugs where ActionBar was ignoring LayoutParams in action
views.
Add convenience methods for toggling display options flags.
Add layout resource version of ActionBar#setCustomView
Fix a bug preventing actionViewClasses from being loaded properly in
menu xml.
Change-Id: I0d9a0b635fd9cfc020bac69369c0c7749c226349
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 67eb02d..8d5a6da 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -154,6 +154,25 @@
public abstract void setCustomView(View view, LayoutParams layoutParams);
/**
+ * Set the action bar into custom navigation mode, supplying a view
+ * for custom navigation.
+ *
+ * <p>Custom navigation views appear between the application icon and
+ * any action buttons and may use any space available there. Common
+ * use cases for custom navigation views might include an auto-suggesting
+ * address bar for a browser or other navigation mechanisms that do not
+ * translate well to provided navigation modes.</p>
+ *
+ * <p>The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for
+ * the custom view to be displayed.</p>
+ *
+ * @param resId Resource ID of a layout to inflate into the ActionBar.
+ *
+ * @see #setDisplayOptions(int, int)
+ */
+ public abstract void setCustomView(int resId);
+
+ /**
* @param view
* @deprecated Use {@link #setCustomView(View)} and {@link #setDisplayOptions(int)} instead.
*/
@@ -319,7 +338,72 @@
* @param mask A bit mask declaring which display options should be changed.
*/
public abstract void setDisplayOptions(int options, int mask);
-
+
+ /**
+ * Set whether to display the activity logo rather than the activity icon.
+ * A logo is often a wider, more detailed image.
+ *
+ * <p>To set several display options at once, see the setDisplayOptions methods.
+ *
+ * @param useLogo true to use the activity logo, false to use the activity icon.
+ *
+ * @see #setDisplayOptions(int)
+ * @see #setDisplayOptions(int, int)
+ */
+ public abstract void setDisplayUseLogoEnabled(boolean useLogo);
+
+ /**
+ * Set whether to include the application home affordance in the action bar.
+ * Home is presented as either an activity icon or logo.
+ *
+ * <p>To set several display options at once, see the setDisplayOptions methods.
+ *
+ * @param showHome true to show home, false otherwise.
+ *
+ * @see #setDisplayOptions(int)
+ * @see #setDisplayOptions(int, int)
+ */
+ public abstract void setDisplayShowHomeEnabled(boolean showHome);
+
+ /**
+ * Set whether home should be displayed as an "up" affordance.
+ * Set this to true if selecting "home" returns up by a single level in your UI
+ * rather than back to the top level or front page.
+ *
+ * <p>To set several display options at once, see the setDisplayOptions methods.
+ *
+ * @param showHomeAsUp true to show the user that selecting home will return one
+ * level up rather than to the top level of the app.
+ *
+ * @see #setDisplayOptions(int)
+ * @see #setDisplayOptions(int, int)
+ */
+ public abstract void setDisplayHomeAsUpEnabled(boolean showHomeAsUp);
+
+ /**
+ * Set whether an activity title/subtitle should be displayed.
+ *
+ * <p>To set several display options at once, see the setDisplayOptions methods.
+ *
+ * @param showTitle true to display a title/subtitle if present.
+ *
+ * @see #setDisplayOptions(int)
+ * @see #setDisplayOptions(int, int)
+ */
+ public abstract void setDisplayShowTitleEnabled(boolean showTitle);
+
+ /**
+ * Set whether a custom view should be displayed, if set.
+ *
+ * <p>To set several display options at once, see the setDisplayOptions methods.
+ *
+ * @param showCustom true if the currently set custom view should be displayed, false otherwise.
+ *
+ * @see #setDisplayOptions(int)
+ * @see #setDisplayOptions(int, int)
+ */
+ public abstract void setDisplayShowCustomEnabled(boolean showCustom);
+
/**
* Set the ActionBar's background.
*
diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java
index 7d5dcd8..ab515c9 100644
--- a/core/java/android/view/MenuInflater.java
+++ b/core/java/android/view/MenuInflater.java
@@ -379,15 +379,15 @@
if (itemActionViewClassName != null) {
try {
- final Class<?> clazz = Class.forName(itemActionViewClassName);
+ final Class<?> clazz = Class.forName(itemActionViewClassName, true,
+ mContext.getClassLoader());
Constructor<?> c = clazz.getConstructor(ACTION_VIEW_CONSTRUCTOR_SIGNATURE);
item.setActionView((View) c.newInstance(mContext));
} catch (Exception e) {
throw new InflateException(e);
}
} else if (itemActionViewLayout > 0) {
- final LayoutInflater inflater = LayoutInflater.from(mContext);
- item.setActionView(inflater.inflate(itemActionViewLayout, null));
+ item.setActionView(itemActionViewLayout);
}
}
diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java
index 602c765..780c52e 100644
--- a/core/java/android/view/MenuItem.java
+++ b/core/java/android/view/MenuItem.java
@@ -433,6 +433,18 @@
public MenuItem setActionView(View view);
/**
+ * Set an action view for this menu item. An action view will be displayed in place
+ * of an automatically generated menu item element in the UI when this item is shown
+ * as an action within a parent.
+ *
+ * @param resId Layout resource to use for presenting this item to the user.
+ * @return This Item so additional setters can be called.
+ *
+ * @see #setShowAsAction(int)
+ */
+ public MenuItem setActionView(int resId);
+
+ /**
* Returns the currently set action view for this menu item.
*
* @return This item's action view
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 633bdd3..f5c0124 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -238,6 +238,36 @@
}
@Override
+ public void setCustomView(int resId) {
+ setCustomView(LayoutInflater.from(mContext).inflate(resId, mActionView, false));
+ }
+
+ @Override
+ public void setDisplayUseLogoEnabled(boolean useLogo) {
+ setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO);
+ }
+
+ @Override
+ public void setDisplayShowHomeEnabled(boolean showHome) {
+ setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME);
+ }
+
+ @Override
+ public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
+ setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP);
+ }
+
+ @Override
+ public void setDisplayShowTitleEnabled(boolean showTitle) {
+ setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE);
+ }
+
+ @Override
+ public void setDisplayShowCustomEnabled(boolean showCustom) {
+ setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM);
+ }
+
+ @Override
public void setTitle(int resId) {
setTitle(mContext.getString(resId));
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index d2851a9..0ef4861 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -231,4 +231,9 @@
public View getActionView() {
return null;
}
+
+ @Override
+ public MenuItem setActionView(int resId) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index 871973d..96c1ed3 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -22,6 +22,7 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -156,6 +157,13 @@
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ if (p instanceof LayoutParams) {
+ LayoutParams result = new LayoutParams((LayoutParams) p);
+ if (result.gravity <= Gravity.NO_GRAVITY) {
+ result.gravity = Gravity.CENTER_VERTICAL;
+ }
+ return result;
+ }
return generateDefaultLayoutParams();
}
@@ -186,13 +194,25 @@
addView(makeDividerView(), makeDividerLayoutParams());
}
final MenuItemImpl itemData = itemsToShow.get(i);
- final View actionView = itemData.getActionView();
+ View actionView = itemData.getActionView();
+
+ if (actionView == null) {
+ // Check for a layout ID instead
+ final int layoutId = itemData.getActionViewId();
+ if (layoutId != 0) {
+ LayoutInflater inflater = LayoutInflater.from(getContext());
+ actionView = inflater.inflate(layoutId, this, false);
+ itemData.setActionView(0);
+ itemData.setActionView(actionView);
+ }
+ }
+
if (actionView != null) {
final ViewParent parent = actionView.getParent();
if (parent instanceof ViewGroup) {
((ViewGroup) parent).removeView(actionView);
}
- addView(actionView, makeActionViewLayoutParams());
+ addView(actionView, makeActionViewLayoutParams(actionView));
} else {
needsDivider = addItemView(i == 0 || !needsDivider,
(ActionMenuItemView) itemData.getItemView(
@@ -274,8 +294,8 @@
return params;
}
- private LayoutParams makeActionViewLayoutParams() {
- LayoutParams params = generateDefaultLayoutParams();
+ private LayoutParams makeActionViewLayoutParams(View view) {
+ LayoutParams params = generateLayoutParams(view.getLayoutParams());
params.leftMargin = (int) mButtonPaddingLeft;
params.rightMargin = (int) mButtonPaddingRight;
return params;
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 8eee360..9faffe5 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -83,6 +83,7 @@
private int mShowAsAction = SHOW_AS_ACTION_NEVER;
private View mActionView;
+ private int mActionViewId;
/** Used for the icon resource ID if this item does not have an icon */
static final int NO_ICON = 0;
@@ -694,7 +695,16 @@
return this;
}
+ public MenuItem setActionView(int resId) {
+ mActionViewId = resId;
+ return this;
+ }
+
public View getActionView() {
return mActionView;
}
+
+ public int getActionViewId() {
+ return mActionViewId;
+ }
}