summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt16
-rw-r--r--core/java/android/app/ActionBar.java2
-rw-r--r--core/java/android/widget/ActionMenuPresenter.java1
-rw-r--r--core/java/android/widget/ActionMenuView.java53
-rw-r--r--core/java/android/widget/Toolbar.java532
-rw-r--r--core/java/com/android/internal/app/WindowDecorActionBar.java144
-rw-r--r--core/java/com/android/internal/widget/AbsActionBarView.java12
-rw-r--r--core/java/com/android/internal/widget/ActionBarContainer.java15
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java6
-rw-r--r--core/java/com/android/internal/widget/ActionBarOverlayLayout.java72
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java78
-rw-r--r--core/java/com/android/internal/widget/DecorToolbar.java94
-rw-r--r--core/java/com/android/internal/widget/ToolbarWidgetWrapper.java526
-rw-r--r--core/res/res/layout/screen_toolbar.xml51
-rw-r--r--core/res/res/values/attrs.xml28
-rw-r--r--core/res/res/values/styles.xml11
-rw-r--r--core/res/res/values/styles_quantum.xml3
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/res/res/values/themes.xml1
-rw-r--r--core/res/res/values/themes_quantum.xml2
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java4
21 files changed, 1438 insertions, 214 deletions
diff --git a/api/current.txt b/api/current.txt
index 5c931f9..679628a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -35852,10 +35852,14 @@ package android.widget {
public class ActionMenuView extends android.widget.LinearLayout {
ctor public ActionMenuView(android.content.Context);
ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
+ method public void dismissPopupMenus();
method public android.view.Menu getMenu();
+ method public boolean hideOverflowMenu();
+ method public boolean isOverflowMenuShowing();
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onDetachedFromWindow();
method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener);
+ method public boolean showOverflowMenu();
}
public static class ActionMenuView.LayoutParams extends android.widget.LinearLayout.LayoutParams {
@@ -38033,6 +38037,8 @@ package android.widget {
ctor public Toolbar(android.content.Context, android.util.AttributeSet);
ctor public Toolbar(android.content.Context, android.util.AttributeSet, int);
ctor public Toolbar(android.content.Context, android.util.AttributeSet, int, int);
+ method public void collapseActionView();
+ method public void dismissPopupMenus();
method public int getContentInsetEnd();
method public int getContentInsetLeft();
method public int getContentInsetRight();
@@ -38043,7 +38049,10 @@ package android.widget {
method public android.graphics.drawable.Drawable getNavigationIcon();
method public java.lang.CharSequence getSubtitle();
method public java.lang.CharSequence getTitle();
+ method public boolean hasExpandedActionView();
+ method public boolean hideOverflowMenu();
method public void inflateMenu(int);
+ method public boolean isOverflowMenuShowing();
method protected void onLayout(boolean, int, int, int, int);
method public void setContentInsetsAbsolute(int, int);
method public void setContentInsetsRelative(int, int);
@@ -38051,6 +38060,8 @@ package android.widget {
method public void setLogo(android.graphics.drawable.Drawable);
method public void setLogoDescription(int);
method public void setLogoDescription(java.lang.CharSequence);
+ method public void setNavigationContentDescription(java.lang.CharSequence);
+ method public void setNavigationContentDescription(int);
method public void setNavigationDescription(int);
method public void setNavigationDescription(java.lang.CharSequence);
method public void setNavigationIcon(int);
@@ -38061,17 +38072,18 @@ package android.widget {
method public void setSubtitle(java.lang.CharSequence);
method public void setTitle(int);
method public void setTitle(java.lang.CharSequence);
+ method public boolean showOverflowMenu();
}
- public static class Toolbar.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ public static class Toolbar.LayoutParams extends android.app.ActionBar.LayoutParams {
ctor public Toolbar.LayoutParams(android.content.Context, android.util.AttributeSet);
ctor public Toolbar.LayoutParams(int, int);
ctor public Toolbar.LayoutParams(int, int, int);
ctor public Toolbar.LayoutParams(int);
ctor public Toolbar.LayoutParams(android.widget.Toolbar.LayoutParams);
+ ctor public Toolbar.LayoutParams(android.app.ActionBar.LayoutParams);
ctor public Toolbar.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
ctor public Toolbar.LayoutParams(android.view.ViewGroup.LayoutParams);
- field public int gravity;
}
public static abstract interface Toolbar.OnMenuItemClickListener {
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 3c3df01..f05f4c7 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -1291,6 +1291,7 @@ public abstract class ActionBar {
public LayoutParams(int width, int height) {
super(width, height);
+ this.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
}
public LayoutParams(int width, int height, int gravity) {
@@ -1305,6 +1306,7 @@ public abstract class ActionBar {
public LayoutParams(LayoutParams source) {
super(source);
+ this.gravity = source.gravity;
}
public LayoutParams(ViewGroup.LayoutParams source) {
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
index 51759c5..1fddf3e 100644
--- a/core/java/android/widget/ActionMenuPresenter.java
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -544,6 +544,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter
public void setMenuView(ActionMenuView menuView) {
mMenuView = menuView;
+ menuView.initialize(mMenu);
}
private static class SavedState implements Parcelable {
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
index 3975edf..a9a5eae 100644
--- a/core/java/android/widget/ActionMenuView.java
+++ b/core/java/android/widget/ActionMenuView.java
@@ -69,6 +69,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
/** @hide */
public void setPresenter(ActionMenuPresenter presenter) {
mPresenter = presenter;
+ mPresenter.setMenuView(this);
}
@Override
@@ -488,7 +489,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mPresenter.dismissPopupMenus();
+ dismissPopupMenus();
}
/** @hide */
@@ -578,6 +579,56 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
}
/**
+ * Returns the current menu or null if one has not yet been configured.
+ * @hide Internal use only for action bar integration
+ */
+ public MenuBuilder peekMenu() {
+ return mMenu;
+ }
+
+ /**
+ * Show the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be shown, false otherwise
+ */
+ public boolean showOverflowMenu() {
+ return mPresenter != null && mPresenter.showOverflowMenu();
+ }
+
+ /**
+ * Hide the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be hidden, false otherwise
+ */
+ public boolean hideOverflowMenu() {
+ return mPresenter != null && mPresenter.hideOverflowMenu();
+ }
+
+ /**
+ * Check whether the overflow menu is currently showing. This may not reflect
+ * a pending show operation in progress.
+ *
+ * @return true if the overflow menu is currently showing
+ */
+ public boolean isOverflowMenuShowing() {
+ return mPresenter != null && mPresenter.isOverflowMenuShowing();
+ }
+
+ /** @hide */
+ public boolean isOverflowMenuShowPending() {
+ return mPresenter != null && mPresenter.isOverflowMenuShowPending();
+ }
+
+ /**
+ * Dismiss any popups associated with this menu view.
+ */
+ public void dismissPopupMenus() {
+ if (mPresenter != null) {
+ mPresenter.dismissPopupMenus();
+ }
+ }
+
+ /**
* @hide Private LinearLayout (superclass) API. Un-hide if LinearLayout API is made public.
*/
@Override
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index f903346..8c67bb7 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -18,13 +18,17 @@
package android.widget;
import android.annotation.NonNull;
+import android.app.ActionBar;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.Log;
+import android.view.CollapsibleActionView;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
@@ -32,7 +36,15 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.Window;
import com.android.internal.R;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPresenter;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
+import com.android.internal.widget.DecorToolbar;
+import com.android.internal.widget.ToolbarWidgetWrapper;
import java.util.ArrayList;
import java.util.List;
@@ -80,14 +92,25 @@ import java.util.List;
* layout is discouraged on API 21 devices and newer.</p>
*/
public class Toolbar extends ViewGroup {
+ private static final String TAG = "Toolbar";
+
private ActionMenuView mMenuView;
private TextView mTitleTextView;
private TextView mSubtitleTextView;
private ImageButton mNavButtonView;
private ImageView mLogoView;
+ private Drawable mCollapseIcon;
+ private ImageButton mCollapseButtonView;
+ View mExpandedActionView;
+
private int mTitleTextAppearance;
private int mSubtitleTextAppearance;
+ private int mNavButtonStyle;
+
+ private int mButtonGravity;
+
+ private int mMaxButtonHeight;
private int mTitleMarginStart;
private int mTitleMarginEnd;
@@ -117,6 +140,10 @@ public class Toolbar extends ViewGroup {
}
};
+ private ToolbarWidgetWrapper mWrapper;
+ private ActionMenuPresenter mOuterActionMenuPresenter;
+ private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
+
public Toolbar(Context context) {
this(context, null);
}
@@ -137,7 +164,9 @@ public class Toolbar extends ViewGroup {
mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);
+ mNavButtonStyle = a.getResourceId(R.styleable.Toolbar_navigationButtonStyle, 0);
mGravity = a.getInteger(R.styleable.Toolbar_gravity, mGravity);
+ mButtonGravity = a.getInteger(R.styleable.Toolbar_buttonGravity, Gravity.TOP);
mTitleMarginStart = mTitleMarginEnd = mTitleMarginTop = mTitleMarginBottom =
a.getDimensionPixelOffset(R.styleable.Toolbar_titleMargins, 0);
@@ -162,6 +191,8 @@ public class Toolbar extends ViewGroup {
mTitleMarginBottom = marginBottom;
}
+ mMaxButtonHeight = a.getDimensionPixelSize(R.styleable.Toolbar_maxButtonHeight, -1);
+
final int contentInsetStart =
a.getDimensionPixelOffset(R.styleable.Toolbar_contentInsetStart,
RtlSpacingHelper.UNDEFINED);
@@ -180,6 +211,8 @@ public class Toolbar extends ViewGroup {
mContentInsets.setRelative(contentInsetStart, contentInsetEnd);
}
+ mCollapseIcon = a.getDrawable(R.styleable.Toolbar_collapseIcon);
+
final CharSequence title = a.getText(R.styleable.Toolbar_title);
if (!TextUtils.isEmpty(title)) {
setTitle(title);
@@ -211,6 +244,110 @@ public class Toolbar extends ViewGroup {
setLogo(getContext().getDrawable(resId));
}
+ /** @hide */
+ public boolean canShowOverflowMenu() {
+ return getVisibility() == VISIBLE && mMenuView != null && mMenuView.isOverflowReserved();
+ }
+
+ /**
+ * Check whether the overflow menu is currently showing. This may not reflect
+ * a pending show operation in progress.
+ *
+ * @return true if the overflow menu is currently showing
+ */
+ public boolean isOverflowMenuShowing() {
+ return mMenuView != null && mMenuView.isOverflowMenuShowing();
+ }
+
+ /** @hide */
+ public boolean isOverflowMenuShowPending() {
+ return mMenuView != null && mMenuView.isOverflowMenuShowPending();
+ }
+
+ /**
+ * Show the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be shown, false otherwise
+ */
+ public boolean showOverflowMenu() {
+ return mMenuView != null && mMenuView.showOverflowMenu();
+ }
+
+ /**
+ * Hide the overflow items from the associated menu.
+ *
+ * @return true if the menu was able to be hidden, false otherwise
+ */
+ public boolean hideOverflowMenu() {
+ return mMenuView != null && mMenuView.hideOverflowMenu();
+ }
+
+ /** @hide */
+ public void setMenu(MenuBuilder menu, ActionMenuPresenter outerPresenter) {
+ if (menu == null && mMenuView == null) {
+ return;
+ }
+
+ ensureMenuView();
+ final MenuBuilder oldMenu = mMenuView.peekMenu();
+ if (oldMenu == menu) {
+ return;
+ }
+
+ if (oldMenu != null) {
+ oldMenu.removeMenuPresenter(mOuterActionMenuPresenter);
+ oldMenu.removeMenuPresenter(mExpandedMenuPresenter);
+ }
+
+ final Context context = getContext();
+
+ if (mExpandedMenuPresenter == null) {
+ mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
+ }
+
+ outerPresenter.setExpandedActionViewsExclusive(true);
+ if (menu != null) {
+ menu.addMenuPresenter(outerPresenter);
+ menu.addMenuPresenter(mExpandedMenuPresenter);
+ } else {
+ outerPresenter.initForMenu(context, null);
+ mExpandedMenuPresenter.initForMenu(context, null);
+ outerPresenter.updateMenuView(true);
+ mExpandedMenuPresenter.updateMenuView(true);
+ }
+ mMenuView.setPresenter(outerPresenter);
+ mOuterActionMenuPresenter = outerPresenter;
+ }
+
+ /**
+ * Dismiss all currently showing popup menus, including overflow or submenus.
+ */
+ public void dismissPopupMenus() {
+ if (mMenuView != null) {
+ mMenuView.dismissPopupMenus();
+ }
+ }
+
+ /** @hide */
+ public boolean isTitleTruncated() {
+ if (mTitleTextView == null) {
+ return false;
+ }
+
+ final Layout titleLayout = mTitleTextView.getLayout();
+ if (titleLayout == null) {
+ return false;
+ }
+
+ final int lineCount = titleLayout.getLineCount();
+ for (int i = 0; i < lineCount; i++) {
+ if (titleLayout.getEllipsisCount(i) > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Set a logo drawable.
*
@@ -222,9 +359,7 @@ public class Toolbar extends ViewGroup {
*/
public void setLogo(Drawable drawable) {
if (drawable != null) {
- if (mLogoView == null) {
- mLogoView = new ImageView(getContext());
- }
+ ensureLogoView();
if (mLogoView.getParent() == null) {
addSystemView(mLogoView);
}
@@ -268,8 +403,8 @@ public class Toolbar extends ViewGroup {
* @param description Description to set
*/
public void setLogoDescription(CharSequence description) {
- if (!TextUtils.isEmpty(description) && mLogoView == null) {
- mLogoView = new ImageView(getContext());
+ if (!TextUtils.isEmpty(description)) {
+ ensureLogoView();
}
if (mLogoView != null) {
mLogoView.setContentDescription(description);
@@ -285,10 +420,48 @@ public class Toolbar extends ViewGroup {
return mLogoView != null ? mLogoView.getContentDescription() : null;
}
+ private void ensureLogoView() {
+ if (mLogoView == null) {
+ mLogoView = new ImageView(getContext());
+ }
+ }
+
/**
- * Return the current title displayed in the toolbar.
+ * Check whether this Toolbar is currently hosting an expanded action view.
*
- * @return The current title
+ * <p>An action view may be expanded either directly from the
+ * {@link android.view.MenuItem MenuItem} it belongs to or by user action. If the Toolbar
+ * has an expanded action view it can be collapsed using the {@link #collapseActionView()}
+ * method.</p>
+ *
+ * @return true if the Toolbar has an expanded action view
+ */
+ public boolean hasExpandedActionView() {
+ return mExpandedMenuPresenter != null &&
+ mExpandedMenuPresenter.mCurrentExpandedItem != null;
+ }
+
+ /**
+ * Collapse a currently expanded action view. If this Toolbar does not have an
+ * expanded action view this method has no effect.
+ *
+ * <p>An action view may be expanded either directly from the
+ * {@link android.view.MenuItem MenuItem} it belongs to or by user action.</p>
+ *
+ * @see #hasExpandedActionView()
+ */
+ public void collapseActionView() {
+ final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
+ mExpandedMenuPresenter.mCurrentExpandedItem;
+ if (item != null) {
+ item.collapseActionView();
+ }
+ }
+
+ /**
+ * Returns the title of this toolbar.
+ *
+ * @return The current title.
*/
public CharSequence getTitle() {
return mTitleText;
@@ -319,6 +492,8 @@ public class Toolbar extends ViewGroup {
if (mTitleTextView == null) {
final Context context = getContext();
mTitleTextView = new TextView(context);
+ mTitleTextView.setSingleLine();
+ mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
mTitleTextView.setTextAppearance(context, mTitleTextAppearance);
}
if (mTitleTextView.getParent() == null) {
@@ -365,6 +540,8 @@ public class Toolbar extends ViewGroup {
if (mSubtitleTextView == null) {
final Context context = getContext();
mSubtitleTextView = new TextView(context);
+ mSubtitleTextView.setSingleLine();
+ mSubtitleTextView.setEllipsize(TextUtils.TruncateAt.END);
mSubtitleTextView.setTextAppearance(context, mSubtitleTextAppearance);
}
if (mSubtitleTextView.getParent() == null) {
@@ -395,6 +572,30 @@ public class Toolbar extends ViewGroup {
}
/**
+ * Set a content description for the navigation button if one is present. The content
+ * description will be read via screen readers or other accessibility systems to explain
+ * the action of the navigation button.
+ *
+ * @param description Content description to set
+ */
+ public void setNavigationContentDescription(CharSequence description) {
+ ensureNavButtonView();
+ mNavButtonView.setContentDescription(description);
+ }
+
+ /**
+ * Set a content description for the navigation button if one is present. The content
+ * description will be read via screen readers or other accessibility systems to explain
+ * the action of the navigation button.
+ *
+ * @param resId Resource ID of a content description string to set
+ */
+ public void setNavigationContentDescription(int resId) {
+ ensureNavButtonView();
+ mNavButtonView.setContentDescription(getContext().getText(resId));
+ }
+
+ /**
* Set the icon to use for the toolbar's navigation button.
*
* <p>The navigation button appears at the start of the toolbar if present. Setting an icon
@@ -480,12 +681,19 @@ public class Toolbar extends ViewGroup {
* @return The toolbar's Menu
*/
public Menu getMenu() {
+ ensureMenuView();
+ return mMenuView.getMenu();
+ }
+
+ private void ensureMenuView() {
if (mMenuView == null) {
mMenuView = new ActionMenuView(getContext());
mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener);
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ mMenuView.setLayoutParams(lp);
addSystemView(mMenuView);
}
- return mMenuView.getMenu();
}
private MenuInflater getMenuInflater() {
@@ -634,7 +842,27 @@ public class Toolbar extends ViewGroup {
private void ensureNavButtonView() {
if (mNavButtonView == null) {
- mNavButtonView = new ImageButton(getContext(), null, R.attr.borderlessButtonStyle);
+ mNavButtonView = new ImageButton(getContext(), null, 0, mNavButtonStyle);
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ mNavButtonView.setLayoutParams(lp);
+ }
+ }
+
+ private void ensureCollapseButtonView() {
+ if (mCollapseButtonView == null) {
+ mCollapseButtonView = new ImageButton(getContext(), null, 0, mNavButtonStyle);
+ mCollapseButtonView.setImageDrawable(mCollapseIcon);
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ lp.mViewType = LayoutParams.EXPANDED;
+ mCollapseButtonView.setLayoutParams(lp);
+ mCollapseButtonView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ collapseActionView();
+ }
+ });
}
}
@@ -657,6 +885,27 @@ public class Toolbar extends ViewGroup {
super.onRestoreInstanceState(ss.getSuperState());
}
+ private void measureChildConstrained(View child, int parentWidthSpec, int widthUsed,
+ int parentHeightSpec, int heightUsed, int heightConstraint) {
+ final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+ int childWidthSpec = getChildMeasureSpec(parentWidthSpec,
+ mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+ + widthUsed, lp.width);
+ int childHeightSpec = getChildMeasureSpec(parentHeightSpec,
+ mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
+ + heightUsed, lp.height);
+
+ final int childHeightMode = MeasureSpec.getMode(childHeightSpec);
+ if (childHeightMode != MeasureSpec.EXACTLY && heightConstraint >= 0) {
+ final int size = childHeightMode != MeasureSpec.UNSPECIFIED ?
+ Math.min(MeasureSpec.getSize(childHeightSpec), heightConstraint) :
+ heightConstraint;
+ childHeightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
+ }
+ child.measure(childWidthSpec, childHeightSpec);
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = 0;
@@ -667,18 +916,30 @@ public class Toolbar extends ViewGroup {
int navWidth = 0;
if (shouldLayout(mNavButtonView)) {
- measureChildWithMargins(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0);
+ measureChildConstrained(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0,
+ mMaxButtonHeight);
navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView);
height = Math.max(height, mNavButtonView.getMeasuredHeight() +
getVerticalMargins(mNavButtonView));
childState = combineMeasuredStates(childState, mNavButtonView.getMeasuredState());
}
+ if (shouldLayout(mCollapseButtonView)) {
+ measureChildConstrained(mCollapseButtonView, widthMeasureSpec, width,
+ heightMeasureSpec, 0, mMaxButtonHeight);
+ navWidth = mCollapseButtonView.getMeasuredWidth() +
+ getHorizontalMargins(mCollapseButtonView);
+ height = Math.max(height, mCollapseButtonView.getMeasuredHeight() +
+ getVerticalMargins(mCollapseButtonView));
+ childState = combineMeasuredStates(childState, mCollapseButtonView.getMeasuredState());
+ }
+
width += Math.max(getContentInsetStart(), navWidth);
int menuWidth = 0;
if (shouldLayout(mMenuView)) {
- measureChildWithMargins(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0);
+ measureChildConstrained(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0,
+ mMaxButtonHeight);
menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView);
height = Math.max(height, mMenuView.getMeasuredHeight() +
getVerticalMargins(mMenuView));
@@ -687,6 +948,16 @@ public class Toolbar extends ViewGroup {
width += Math.max(getContentInsetEnd(), menuWidth);
+ if (shouldLayout(mExpandedActionView)) {
+ measureChildWithMargins(mExpandedActionView, widthMeasureSpec, width,
+ heightMeasureSpec, 0);
+ width += mExpandedActionView.getMeasuredWidth() +
+ getHorizontalMargins(mExpandedActionView);
+ height = Math.max(height, mExpandedActionView.getMeasuredHeight() +
+ getVerticalMargins(mExpandedActionView));
+ childState = combineMeasuredStates(childState, mExpandedActionView.getMeasuredState());
+ }
+
if (shouldLayout(mLogoView)) {
measureChildWithMargins(mLogoView, widthMeasureSpec, width, heightMeasureSpec, 0);
width += mLogoView.getMeasuredWidth() + getHorizontalMargins(mLogoView);
@@ -723,7 +994,7 @@ public class Toolbar extends ViewGroup {
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType == LayoutParams.SYSTEM || !shouldLayout(child)) {
+ if (lp.mViewType != LayoutParams.CUSTOM || !shouldLayout(child)) {
// We already got all system views above. Skip them and GONE views.
continue;
}
@@ -768,6 +1039,14 @@ public class Toolbar extends ViewGroup {
}
}
+ if (shouldLayout(mCollapseButtonView)) {
+ if (isRtl) {
+ right = layoutChildRight(mCollapseButtonView, right);
+ } else {
+ left = layoutChildLeft(mCollapseButtonView, left);
+ }
+ }
+
if (shouldLayout(mMenuView)) {
if (isRtl) {
left = layoutChildLeft(mMenuView, left);
@@ -779,6 +1058,14 @@ public class Toolbar extends ViewGroup {
left = Math.max(left, getContentInsetLeft());
right = Math.min(right, width - paddingRight - getContentInsetRight());
+ if (shouldLayout(mExpandedActionView)) {
+ if (isRtl) {
+ right = layoutChildRight(mExpandedActionView, right);
+ } else {
+ left = layoutChildLeft(mExpandedActionView, left);
+ }
+ }
+
if (shouldLayout(mLogoView)) {
if (isRtl) {
right = layoutChildRight(mLogoView, right);
@@ -801,40 +1088,42 @@ public class Toolbar extends ViewGroup {
if (layoutTitle || layoutSubtitle) {
int titleTop;
+ final View topChild = layoutTitle ? mTitleTextView : mSubtitleTextView;
+ final View bottomChild = layoutSubtitle ? mSubtitleTextView : mTitleTextView;
+ final LayoutParams toplp = (LayoutParams) topChild.getLayoutParams();
+ final LayoutParams bottomlp = (LayoutParams) bottomChild.getLayoutParams();
+
switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) {
case Gravity.TOP:
- titleTop = getPaddingTop();
+ titleTop = getPaddingTop() + toplp.topMargin + mTitleMarginTop;
break;
default:
case Gravity.CENTER_VERTICAL:
- final View child = layoutTitle ? mTitleTextView : mSubtitleTextView;
- final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int space = height - paddingTop - paddingBottom;
int spaceAbove = (space - titleHeight) / 2;
- if (spaceAbove < lp.topMargin + mTitleMarginTop) {
- spaceAbove = lp.topMargin + mTitleMarginTop;
+ if (spaceAbove < toplp.topMargin + mTitleMarginTop) {
+ spaceAbove = toplp.topMargin + mTitleMarginTop;
} else {
final int spaceBelow = height - paddingBottom - titleHeight -
spaceAbove - paddingTop;
- if (spaceBelow < lp.bottomMargin + mTitleMarginBottom) {
+ if (spaceBelow < toplp.bottomMargin + mTitleMarginBottom) {
spaceAbove = Math.max(0, spaceAbove -
- (lp.bottomMargin + mTitleMarginBottom - spaceBelow));
+ (bottomlp.bottomMargin + mTitleMarginBottom - spaceBelow));
}
}
titleTop = paddingTop + spaceAbove;
break;
case Gravity.BOTTOM:
- titleTop = height - paddingBottom - titleHeight;
+ titleTop = height - paddingBottom - bottomlp.bottomMargin - mTitleMarginBottom -
+ titleHeight;
break;
}
if (isRtl) {
int titleRight = right;
int subtitleRight = right;
- titleTop += mTitleMarginTop;
if (layoutTitle) {
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
titleRight -= lp.rightMargin + mTitleMarginStart;
- titleTop += lp.topMargin;
final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth();
final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
@@ -855,11 +1144,9 @@ public class Toolbar extends ViewGroup {
} else {
int titleLeft = left;
int subtitleLeft = left;
- titleTop += mTitleMarginTop;
if (layoutTitle) {
final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams();
titleLeft += lp.leftMargin + mTitleMarginStart;
- titleTop += lp.topMargin;
final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth();
final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight();
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
@@ -897,7 +1184,7 @@ public class Toolbar extends ViewGroup {
// Centered views try to center with respect to the whole bar, but views pinned
// to the left or right can push the mass of centered views to one side or the other.
- addCustomViewsWithGravity(mTempViews, Gravity.CENTER);
+ addCustomViewsWithGravity(mTempViews, Gravity.CENTER_HORIZONTAL);
final int centerViewsWidth = getViewListMeasuredWidth(mTempViews);
final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2;
final int halfCenterViewsWidth = centerViewsWidth / 2;
@@ -1007,17 +1294,16 @@ public class Toolbar extends ViewGroup {
for (int i = childCount - 1; i >= 0; i--) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType != LayoutParams.SYSTEM && shouldLayout(child) &&
+ if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
getChildHorizontalGravity(lp.gravity) == absGrav) {
views.add(child);
}
-
}
} else {
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
- if (lp.mViewType != LayoutParams.SYSTEM && shouldLayout(child) &&
+ if (lp.mViewType == LayoutParams.CUSTOM && shouldLayout(child) &&
getChildHorizontalGravity(lp.gravity) == absGrav) {
views.add(child);
}
@@ -1054,14 +1340,16 @@ public class Toolbar extends ViewGroup {
}
@Override
- public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
- return super.generateLayoutParams(attrs);
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
}
@Override
- protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
if (p instanceof LayoutParams) {
return new LayoutParams((LayoutParams) p);
+ } else if (p instanceof ActionBar.LayoutParams) {
+ return new LayoutParams((ActionBar.LayoutParams) p);
} else if (p instanceof MarginLayoutParams) {
return new LayoutParams((MarginLayoutParams) p);
} else {
@@ -1070,7 +1358,7 @@ public class Toolbar extends ViewGroup {
}
@Override
- protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@@ -1083,6 +1371,25 @@ public class Toolbar extends ViewGroup {
return ((LayoutParams) child.getLayoutParams()).mViewType == LayoutParams.CUSTOM;
}
+ /** @hide */
+ public DecorToolbar getWrapper() {
+ if (mWrapper == null) {
+ mWrapper = new ToolbarWidgetWrapper(this);
+ }
+ return mWrapper;
+ }
+
+ private void setChildVisibilityForExpandedActionView(boolean expand) {
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp.mViewType != LayoutParams.EXPANDED && child != mMenuView) {
+ child.setVisibility(expand ? GONE : VISIBLE);
+ }
+ }
+ }
+
/**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
@@ -1103,44 +1410,15 @@ public class Toolbar extends ViewGroup {
*
* @attr ref android.R.styleable#Toolbar_LayoutParams_layout_gravity
*/
- public static class LayoutParams extends MarginLayoutParams {
- /**
- * Gravity for the view associated with these LayoutParams.
- *
- * @see android.view.Gravity
- */
- @ViewDebug.ExportedProperty(category = "layout", mapping = {
- @ViewDebug.IntToString(from = -1, to = "NONE"),
- @ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"),
- @ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"),
- @ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"),
- @ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"),
- @ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"),
- @ViewDebug.IntToString(from = Gravity.START, to = "START"),
- @ViewDebug.IntToString(from = Gravity.END, to = "END"),
- @ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"),
- @ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"),
- @ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
- @ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"),
- @ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
- @ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
- })
- public int gravity = Gravity.NO_GRAVITY;
-
+ public static class LayoutParams extends ActionBar.LayoutParams {
static final int CUSTOM = 0;
static final int SYSTEM = 1;
+ static final int EXPANDED = 2;
int mViewType = CUSTOM;
public LayoutParams(@NonNull Context c, AttributeSet attrs) {
super(c, attrs);
-
- TypedArray a = c.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.Toolbar_LayoutParams);
- gravity = a.getInt(
- com.android.internal.R.styleable.Toolbar_LayoutParams_layout_gravity,
- Gravity.NO_GRAVITY);
- a.recycle();
}
public LayoutParams(int width, int height) {
@@ -1160,7 +1438,11 @@ public class Toolbar extends ViewGroup {
public LayoutParams(LayoutParams source) {
super(source);
- this.gravity = source.gravity;
+ mViewType = source.mViewType;
+ }
+
+ public LayoutParams(ActionBar.LayoutParams source) {
+ super(source);
}
public LayoutParams(MarginLayoutParams source) {
@@ -1199,4 +1481,126 @@ public class Toolbar extends ViewGroup {
}
};
}
+
+ private class ExpandedActionViewMenuPresenter implements MenuPresenter {
+ MenuBuilder mMenu;
+ MenuItemImpl mCurrentExpandedItem;
+
+ @Override
+ public void initForMenu(Context context, MenuBuilder menu) {
+ // Clear the expanded action view when menus change.
+ if (mMenu != null && mCurrentExpandedItem != null) {
+ mMenu.collapseItemActionView(mCurrentExpandedItem);
+ }
+ mMenu = menu;
+ }
+
+ @Override
+ public MenuView getMenuView(ViewGroup root) {
+ return null;
+ }
+
+ @Override
+ public void updateMenuView(boolean cleared) {
+ // Make sure the expanded item we have is still there.
+ if (mCurrentExpandedItem != null) {
+ boolean found = false;
+
+ if (mMenu != null) {
+ final int count = mMenu.size();
+ for (int i = 0; i < count; i++) {
+ final MenuItem item = mMenu.getItem(i);
+ if (item == mCurrentExpandedItem) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ // The item we had expanded disappeared. Collapse.
+ collapseItemActionView(mMenu, mCurrentExpandedItem);
+ }
+ }
+ }
+
+ @Override
+ public void setCallback(Callback cb) {
+ }
+
+ @Override
+ public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
+ return false;
+ }
+
+ @Override
+ public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+ }
+
+ @Override
+ public boolean flagActionItems() {
+ return false;
+ }
+
+ @Override
+ public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
+ ensureCollapseButtonView();
+ if (mCollapseButtonView.getParent() != Toolbar.this) {
+ addView(mCollapseButtonView);
+ }
+ mExpandedActionView = item.getActionView();
+ mCurrentExpandedItem = item;
+ if (mExpandedActionView.getParent() != Toolbar.this) {
+ final LayoutParams lp = generateDefaultLayoutParams();
+ lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK);
+ lp.mViewType = LayoutParams.EXPANDED;
+ mExpandedActionView.setLayoutParams(lp);
+ addView(mExpandedActionView);
+ }
+
+ setChildVisibilityForExpandedActionView(true);
+ requestLayout();
+ item.setActionViewExpanded(true);
+
+ if (mExpandedActionView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
+ // Do this before detaching the actionview from the hierarchy, in case
+ // it needs to dismiss the soft keyboard, etc.
+ if (mExpandedActionView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
+ }
+
+ removeView(mExpandedActionView);
+ removeView(mCollapseButtonView);
+ mExpandedActionView = null;
+
+ setChildVisibilityForExpandedActionView(false);
+ mCurrentExpandedItem = null;
+ requestLayout();
+ item.setActionViewExpanded(false);
+
+ return true;
+ }
+
+ @Override
+ public int getId() {
+ return 0;
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ return null;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index a238ae3..a0c75a6 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -18,7 +18,10 @@ package com.android.internal.app;
import android.animation.ValueAnimator;
import android.content.res.TypedArray;
+import android.view.ViewGroup;
import android.view.ViewParent;
+import android.widget.AdapterView;
+import android.widget.Toolbar;
import com.android.internal.R;
import com.android.internal.view.ActionBarPolicy;
import com.android.internal.view.menu.MenuBuilder;
@@ -28,6 +31,7 @@ import com.android.internal.widget.ActionBarContainer;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarOverlayLayout;
import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.DecorToolbar;
import com.android.internal.widget.ScrollingTabContainerView;
import android.animation.Animator;
@@ -55,6 +59,7 @@ import android.view.Window;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.SpinnerAdapter;
+import com.android.internal.widget.ToolbarWidgetWrapper;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -77,7 +82,7 @@ public class WindowDecorActionBar extends ActionBar implements
private ActionBarOverlayLayout mOverlayLayout;
private ActionBarContainer mContainerView;
- private ActionBarView mActionView;
+ private DecorToolbar mDecorToolbar;
private ActionBarContextView mContextView;
private ActionBarContainer mSplitView;
private View mContentView;
@@ -187,7 +192,7 @@ public class WindowDecorActionBar extends ActionBar implements
if (mOverlayLayout != null) {
mOverlayLayout.setActionBarVisibilityCallback(this);
}
- mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
+ mDecorToolbar = getDecorToolbar(decor.findViewById(com.android.internal.R.id.action_bar));
mContextView = (ActionBarContextView) decor.findViewById(
com.android.internal.R.id.action_context_bar);
mContainerView = (ActionBarContainer) decor.findViewById(
@@ -195,18 +200,17 @@ public class WindowDecorActionBar extends ActionBar implements
mSplitView = (ActionBarContainer) decor.findViewById(
com.android.internal.R.id.split_action_bar);
- if (mActionView == null || mContextView == null || mContainerView == null) {
+ if (mDecorToolbar == null || mContextView == null || mContainerView == null) {
throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
"with a compatible window decor layout");
}
- mContext = mActionView.getContext();
- mActionView.setContextView(mContextView);
- mContextDisplayMode = mActionView.isSplitActionBar() ?
+ mContext = mDecorToolbar.getContext();
+ mContextDisplayMode = mDecorToolbar.isSplit() ?
CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
// This was initially read from the action bar style
- final int current = mActionView.getDisplayOptions();
+ final int current = mDecorToolbar.getDisplayOptions();
final boolean homeAsUp = (current & DISPLAY_HOME_AS_UP) != 0;
if (homeAsUp) {
mDisplayHomeAsUpSet = true;
@@ -225,6 +229,17 @@ public class WindowDecorActionBar extends ActionBar implements
a.recycle();
}
+ private DecorToolbar getDecorToolbar(View view) {
+ if (view instanceof DecorToolbar) {
+ return (DecorToolbar) view;
+ } else if (view instanceof Toolbar) {
+ return ((Toolbar) view).getWrapper();
+ } else {
+ throw new IllegalStateException("Can't make a decor toolbar out of " +
+ view.getClass().getSimpleName());
+ }
+ }
+
public void onConfigurationChanged(Configuration newConfig) {
setHasEmbeddedTabs(ActionBarPolicy.get(mContext).hasEmbeddedTabs());
}
@@ -233,11 +248,11 @@ public class WindowDecorActionBar extends ActionBar implements
mHasEmbeddedTabs = hasEmbeddedTabs;
// Switch tab layout configuration if needed
if (!mHasEmbeddedTabs) {
- mActionView.setEmbeddedTabView(null);
+ mDecorToolbar.setEmbeddedTabView(null);
mContainerView.setTabContainer(mTabScrollView);
} else {
mContainerView.setTabContainer(null);
- mActionView.setEmbeddedTabView(mTabScrollView);
+ mDecorToolbar.setEmbeddedTabView(mTabScrollView);
}
final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS;
if (mTabScrollView != null) {
@@ -250,7 +265,7 @@ public class WindowDecorActionBar extends ActionBar implements
mTabScrollView.setVisibility(View.GONE);
}
}
- mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode);
+ mDecorToolbar.setCollapsible(!mHasEmbeddedTabs && isInTabMode);
mOverlayLayout.setHasNonEmbeddedTabs(!mHasEmbeddedTabs && isInTabMode);
}
@@ -263,7 +278,7 @@ public class WindowDecorActionBar extends ActionBar implements
if (mHasEmbeddedTabs) {
tabScroller.setVisibility(View.VISIBLE);
- mActionView.setEmbeddedTabView(tabScroller);
+ mDecorToolbar.setEmbeddedTabView(tabScroller);
} else {
if (getNavigationMode() == NAVIGATION_MODE_TABS) {
tabScroller.setVisibility(View.VISIBLE);
@@ -326,7 +341,8 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public void setCustomView(int resId) {
- setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false));
+ setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId,
+ (ViewGroup) mDecorToolbar, false));
}
@Override
@@ -356,7 +372,7 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public void setHomeButtonEnabled(boolean enable) {
- mActionView.setHomeButtonEnabled(enable);
+ mDecorToolbar.setHomeButtonEnabled(enable);
}
@Override
@@ -370,12 +386,12 @@ public class WindowDecorActionBar extends ActionBar implements
}
public void setSelectedNavigationItem(int position) {
- switch (mActionView.getNavigationMode()) {
+ switch (mDecorToolbar.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
selectTab(mTabs.get(position));
break;
case NAVIGATION_MODE_LIST:
- mActionView.setDropdownSelectedPosition(position);
+ mDecorToolbar.setDropdownSelectedPosition(position);
break;
default:
throw new IllegalStateException(
@@ -399,26 +415,26 @@ public class WindowDecorActionBar extends ActionBar implements
}
public void setTitle(CharSequence title) {
- mActionView.setTitle(title);
+ mDecorToolbar.setTitle(title);
}
public void setSubtitle(CharSequence subtitle) {
- mActionView.setSubtitle(subtitle);
+ mDecorToolbar.setSubtitle(subtitle);
}
public void setDisplayOptions(int options) {
if ((options & DISPLAY_HOME_AS_UP) != 0) {
mDisplayHomeAsUpSet = true;
}
- mActionView.setDisplayOptions(options);
+ mDecorToolbar.setDisplayOptions(options);
}
public void setDisplayOptions(int options, int mask) {
- final int current = mActionView.getDisplayOptions();
+ final int current = mDecorToolbar.getDisplayOptions();
if ((mask & DISPLAY_HOME_AS_UP) != 0) {
mDisplayHomeAsUpSet = true;
}
- mActionView.setDisplayOptions((options & mask) | (current & ~mask));
+ mDecorToolbar.setDisplayOptions((options & mask) | (current & ~mask));
}
public void setBackgroundDrawable(Drawable d) {
@@ -436,23 +452,23 @@ public class WindowDecorActionBar extends ActionBar implements
}
public View getCustomView() {
- return mActionView.getCustomNavigationView();
+ return mDecorToolbar.getCustomView();
}
public CharSequence getTitle() {
- return mActionView.getTitle();
+ return mDecorToolbar.getTitle();
}
public CharSequence getSubtitle() {
- return mActionView.getSubtitle();
+ return mDecorToolbar.getSubtitle();
}
public int getNavigationMode() {
- return mActionView.getNavigationMode();
+ return mDecorToolbar.getNavigationMode();
}
public int getDisplayOptions() {
- return mActionView.getDisplayOptions();
+ return mDecorToolbar.getDisplayOptions();
}
public ActionMode startActionMode(ActionMode.Callback callback) {
@@ -572,7 +588,7 @@ public class WindowDecorActionBar extends ActionBar implements
return;
}
- final FragmentTransaction trans = mActionView.isInEditMode() ? null :
+ final FragmentTransaction trans = ((View) mDecorToolbar).isInEditMode() ? null :
mActivity.getFragmentManager().beginTransaction().disallowAddToBackStack();
if (mSelectedTab == tab) {
@@ -828,13 +844,18 @@ public class WindowDecorActionBar extends ActionBar implements
hideForActionMode();
}
- mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
+ mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
- if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) {
+ if (mTabScrollView != null && !mDecorToolbar.hasEmbeddedTabs() &&
+ isCollapsed((View) mDecorToolbar)) {
mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
}
}
+ private boolean isCollapsed(View view) {
+ return view == null || view.getVisibility() == View.GONE || view.getMeasuredHeight() == 0;
+ }
+
public Context getThemedContext() {
if (mThemedContext == null) {
TypedValue outValue = new TypedValue();
@@ -854,27 +875,27 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public boolean isTitleTruncated() {
- return mActionView != null && mActionView.isTitleTruncated();
+ return mDecorToolbar != null && mDecorToolbar.isTitleTruncated();
}
@Override
public void setHomeAsUpIndicator(Drawable indicator) {
- mActionView.setHomeAsUpIndicator(indicator);
+ mDecorToolbar.setNavigationIcon(indicator);
}
@Override
public void setHomeAsUpIndicator(int resId) {
- mActionView.setHomeAsUpIndicator(resId);
+ mDecorToolbar.setNavigationIcon(resId);
}
@Override
public void setHomeActionContentDescription(CharSequence description) {
- mActionView.setHomeActionContentDescription(description);
+ mDecorToolbar.setNavigationContentDescription(description);
}
@Override
public void setHomeActionContentDescription(int resId) {
- mActionView.setHomeActionContentDescription(resId);
+ mDecorToolbar.setNavigationContentDescription(resId);
}
@Override
@@ -938,7 +959,8 @@ public class WindowDecorActionBar extends ActionBar implements
// Clear out the context mode views after the animation finishes
mContextView.closeMode();
- mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ ((View) mDecorToolbar).sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
mOverlayLayout.setHideOnContentScrollEnabled(mHideOnContentScroll);
mActionMode = null;
@@ -1178,28 +1200,27 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public void setCustomView(View view) {
- mActionView.setCustomNavigationView(view);
+ mDecorToolbar.setCustomView(view);
}
@Override
public void setCustomView(View view, LayoutParams layoutParams) {
view.setLayoutParams(layoutParams);
- mActionView.setCustomNavigationView(view);
+ mDecorToolbar.setCustomView(view);
}
@Override
public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
- mActionView.setDropdownAdapter(adapter);
- mActionView.setCallback(callback);
+ mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
}
@Override
public int getSelectedNavigationIndex() {
- switch (mActionView.getNavigationMode()) {
+ switch (mDecorToolbar.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
case NAVIGATION_MODE_LIST:
- return mActionView.getDropdownSelectedPosition();
+ return mDecorToolbar.getDropdownSelectedPosition();
default:
return -1;
}
@@ -1207,12 +1228,11 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public int getNavigationItemCount() {
- switch (mActionView.getNavigationMode()) {
+ switch (mDecorToolbar.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
return mTabs.size();
case NAVIGATION_MODE_LIST:
- SpinnerAdapter adapter = mActionView.getDropdownAdapter();
- return adapter != null ? adapter.getCount() : 0;
+ return mDecorToolbar.getDropdownItemCount();
default:
return 0;
}
@@ -1225,7 +1245,7 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public void setNavigationMode(int mode) {
- final int oldMode = mActionView.getNavigationMode();
+ final int oldMode = mDecorToolbar.getNavigationMode();
switch (oldMode) {
case NAVIGATION_MODE_TABS:
mSavedTabPosition = getSelectedNavigationIndex();
@@ -1238,7 +1258,7 @@ public class WindowDecorActionBar extends ActionBar implements
mOverlayLayout.requestFitSystemWindows();
}
}
- mActionView.setNavigationMode(mode);
+ mDecorToolbar.setNavigationMode(mode);
switch (mode) {
case NAVIGATION_MODE_TABS:
ensureTabsExist();
@@ -1249,7 +1269,7 @@ public class WindowDecorActionBar extends ActionBar implements
}
break;
}
- mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
+ mDecorToolbar.setCollapsible(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
mOverlayLayout.setHasNonEmbeddedTabs(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
}
@@ -1261,30 +1281,30 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public void setIcon(int resId) {
- mActionView.setIcon(resId);
+ mDecorToolbar.setIcon(resId);
}
@Override
public void setIcon(Drawable icon) {
- mActionView.setIcon(icon);
+ mDecorToolbar.setIcon(icon);
}
public boolean hasIcon() {
- return mActionView.hasIcon();
+ return mDecorToolbar.hasIcon();
}
@Override
public void setLogo(int resId) {
- mActionView.setLogo(resId);
+ mDecorToolbar.setLogo(resId);
}
@Override
public void setLogo(Drawable logo) {
- mActionView.setLogo(logo);
+ mDecorToolbar.setLogo(logo);
}
public boolean hasLogo() {
- return mActionView.hasLogo();
+ return mDecorToolbar.hasLogo();
}
public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
@@ -1292,4 +1312,24 @@ public class WindowDecorActionBar extends ActionBar implements
setDisplayHomeAsUpEnabled(enable);
}
}
+
+ static class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
+ private final OnNavigationListener mListener;
+
+ public NavItemSelectedListener(OnNavigationListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ if (mListener != null) {
+ mListener.onNavigationItemSelected(position, id);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Do nothing
+ }
+ }
}
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 183478f..9e7ff93 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -34,7 +34,7 @@ import android.view.animation.DecelerateInterpolator;
public abstract class AbsActionBarView extends ViewGroup {
protected ActionMenuView mMenuView;
protected ActionMenuPresenter mActionMenuPresenter;
- protected ActionBarContainer mSplitView;
+ protected ViewGroup mSplitView;
protected boolean mSplitActionBar;
protected boolean mSplitWhenNarrow;
protected int mContentHeight;
@@ -74,7 +74,7 @@ public abstract class AbsActionBarView extends ViewGroup {
setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
a.recycle();
if (mSplitWhenNarrow) {
- setSplitActionBar(getContext().getResources().getBoolean(
+ setSplitToolbar(getContext().getResources().getBoolean(
com.android.internal.R.bool.split_action_bar_is_narrow));
}
if (mActionMenuPresenter != null) {
@@ -86,7 +86,7 @@ public abstract class AbsActionBarView extends ViewGroup {
* Sets whether the bar should be split right now, no questions asked.
* @param split true if the bar should split
*/
- public void setSplitActionBar(boolean split) {
+ public void setSplitToolbar(boolean split) {
mSplitActionBar = split;
}
@@ -107,7 +107,7 @@ public abstract class AbsActionBarView extends ViewGroup {
return mContentHeight;
}
- public void setSplitView(ActionBarContainer splitView) {
+ public void setSplitView(ViewGroup splitView) {
mSplitView = splitView;
}
@@ -214,6 +214,10 @@ public abstract class AbsActionBarView extends ViewGroup {
return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
}
+ public boolean canShowOverflowMenu() {
+ return isOverflowReserved() && getVisibility() == VISIBLE;
+ }
+
public void dismissPopupMenus() {
if (mActionMenuPresenter != null) {
mActionMenuPresenter.dismissPopupMenus();
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index ed07514..790b611 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -36,7 +36,7 @@ import android.widget.FrameLayout;
public class ActionBarContainer extends FrameLayout {
private boolean mIsTransitioning;
private View mTabContainer;
- private ActionBarView mActionBarView;
+ private View mActionBarView;
private Drawable mBackground;
private Drawable mStackedBackground;
@@ -76,7 +76,7 @@ public class ActionBarContainer extends FrameLayout {
@Override
public void onFinishInflate() {
super.onFinishInflate();
- mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ mActionBarView = findViewById(com.android.internal.R.id.action_bar);
}
public void setPrimaryBackground(Drawable bg) {
@@ -251,6 +251,10 @@ public class ActionBarContainer extends FrameLayout {
return null;
}
+ private boolean isCollapsed(View view) {
+ return view == null || view.getVisibility() == GONE || view.getMeasuredHeight() == 0;
+ }
+
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mActionBarView == null &&
@@ -263,7 +267,7 @@ public class ActionBarContainer extends FrameLayout {
if (mActionBarView == null) return;
final LayoutParams lp = (LayoutParams) mActionBarView.getLayoutParams();
- final int actionBarViewHeight = mActionBarView.isCollapsed() ? 0 :
+ final int actionBarViewHeight = isCollapsed(mActionBarView) ? 0 :
mActionBarView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
@@ -298,9 +302,8 @@ public class ActionBarContainer extends FrameLayout {
}
} else {
if (mBackground != null) {
- final ActionBarView actionBarView = mActionBarView;
- mBackground.setBounds(actionBarView.getLeft(), actionBarView.getTop(),
- actionBarView.getRight(), actionBarView.getBottom());
+ mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
+ mActionBarView.getRight(), mActionBarView.getBottom());
needsInvalidate = true;
}
mIsStacked = hasTabs;
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index e10070f..6ff77a0 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -83,7 +83,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.ActionMode, defStyleAttr, defStyleRes);
- setBackgroundDrawable(a.getDrawable(
+ setBackground(a.getDrawable(
com.android.internal.R.styleable.ActionMode_background));
mTitleStyleRes = a.getResourceId(
com.android.internal.R.styleable.ActionMode_titleTextStyle, 0);
@@ -109,7 +109,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
}
@Override
- public void setSplitActionBar(boolean split) {
+ public void setSplitToolbar(boolean split) {
if (mSplitActionBar != split) {
if (mActionMenuPresenter != null) {
// Mode is already active; move everything over and adjust the menu itself.
@@ -137,7 +137,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
mSplitView.addView(mMenuView, layoutParams);
}
}
- super.setSplitActionBar(split);
+ super.setSplitToolbar(split);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 7ab4bed..8a9cb22 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -39,6 +39,7 @@ import android.view.ViewPropertyAnimator;
import android.view.Window;
import android.view.WindowInsets;
import android.widget.OverScroller;
+import android.widget.Toolbar;
import com.android.internal.view.menu.MenuPresenter;
/**
@@ -59,7 +60,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
private ActionBarContainer mActionBarTop;
// Some interior UI elements.
- private ActionBarView mActionBarView;
+ private DecorToolbar mDecorToolbar;
// Content overlay drawable - generally the action bar's shadow
private Drawable mWindowContentOverlay;
@@ -401,7 +402,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
topInset = mActionBarTop.getMeasuredHeight();
}
- if (mActionBarView.isSplitActionBar()) {
+ if (mDecorToolbar.isSplit()) {
// If action bar is split, adjust bottom insets for it.
if (mActionBarBottom != null) {
if (stable) {
@@ -563,12 +564,23 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
mContent = findViewById(com.android.internal.R.id.content);
mActionBarTop = (ActionBarContainer) findViewById(
com.android.internal.R.id.action_bar_container);
- mActionBarView = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
+ mDecorToolbar = getDecorToolbar(findViewById(com.android.internal.R.id.action_bar));
mActionBarBottom = (ActionBarContainer) findViewById(
com.android.internal.R.id.split_action_bar);
}
}
+ private DecorToolbar getDecorToolbar(View view) {
+ if (view instanceof DecorToolbar) {
+ return (DecorToolbar) view;
+ } else if (view instanceof Toolbar) {
+ return ((Toolbar) view).getWrapper();
+ } else {
+ throw new IllegalStateException("Can't make a decor toolbar out of " +
+ view.getClass().getSimpleName());
+ }
+ }
+
public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) {
if (hideOnContentScroll != mHideOnContentScroll) {
mHideOnContentScroll = hideOnContentScroll;
@@ -648,9 +660,9 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
final int action = event.getAction();
// Collapse any expanded action views.
- if (mActionBarView != null && mActionBarView.hasExpandedActionView()) {
+ if (mDecorToolbar != null && mDecorToolbar.hasExpandedActionView()) {
if (action == KeyEvent.ACTION_UP) {
- mActionBarView.collapseActionView();
+ mDecorToolbar.collapseActionView();
}
return true;
}
@@ -662,19 +674,19 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
@Override
public void setWindowCallback(Window.Callback cb) {
pullChildren();
- mActionBarView.setWindowCallback(cb);
+ mDecorToolbar.setWindowCallback(cb);
}
@Override
public void setWindowTitle(CharSequence title) {
pullChildren();
- mActionBarView.setWindowTitle(title);
+ mDecorToolbar.setWindowTitle(title);
}
@Override
public CharSequence getTitle() {
pullChildren();
- return mActionBarView.getTitle();
+ return mDecorToolbar.getTitle();
}
@Override
@@ -682,10 +694,10 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
pullChildren();
switch (windowFeature) {
case Window.FEATURE_PROGRESS:
- mActionBarView.initProgress();
+ mDecorToolbar.initProgress();
break;
case Window.FEATURE_INDETERMINATE_PROGRESS:
- mActionBarView.initIndeterminateProgress();
+ mDecorToolbar.initIndeterminateProgress();
break;
case Window.FEATURE_ACTION_BAR_OVERLAY:
setOverlayMode(true);
@@ -704,15 +716,15 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
}
if (splitActionBar) {
pullChildren();
- if (mActionBarBottom != null) {
- mActionBarView.setSplitView(mActionBarBottom);
- mActionBarView.setSplitActionBar(splitActionBar);
- mActionBarView.setSplitWhenNarrow(splitWhenNarrow);
+ if (mActionBarBottom != null && mDecorToolbar.canSplit()) {
+ mDecorToolbar.setSplitView(mActionBarBottom);
+ mDecorToolbar.setSplitToolbar(splitActionBar);
+ mDecorToolbar.setSplitWhenNarrow(splitWhenNarrow);
final ActionBarContextView cab = (ActionBarContextView) findViewById(
com.android.internal.R.id.action_context_bar);
cab.setSplitView(mActionBarBottom);
- cab.setSplitActionBar(splitActionBar);
+ cab.setSplitToolbar(splitActionBar);
cab.setSplitWhenNarrow(splitWhenNarrow);
} else if (splitActionBar) {
Log.e(TAG, "Requested split action bar with " +
@@ -724,91 +736,91 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
@Override
public boolean hasIcon() {
pullChildren();
- return mActionBarView.hasIcon();
+ return mDecorToolbar.hasIcon();
}
@Override
public boolean hasLogo() {
pullChildren();
- return mActionBarView.hasLogo();
+ return mDecorToolbar.hasLogo();
}
@Override
public void setIcon(int resId) {
pullChildren();
- mActionBarView.setIcon(resId);
+ mDecorToolbar.setIcon(resId);
}
@Override
public void setIcon(Drawable d) {
pullChildren();
- mActionBarView.setIcon(d);
+ mDecorToolbar.setIcon(d);
}
@Override
public void setLogo(int resId) {
pullChildren();
- mActionBarView.setLogo(resId);
+ mDecorToolbar.setLogo(resId);
}
@Override
public boolean canShowOverflowMenu() {
pullChildren();
- return mActionBarView.isOverflowReserved() && mActionBarView.getVisibility() == VISIBLE;
+ return mDecorToolbar.canShowOverflowMenu();
}
@Override
public boolean isOverflowMenuShowing() {
pullChildren();
- return mActionBarView.isOverflowMenuShowing();
+ return mDecorToolbar.isOverflowMenuShowing();
}
@Override
public boolean isOverflowMenuShowPending() {
pullChildren();
- return mActionBarView.isOverflowMenuShowPending();
+ return mDecorToolbar.isOverflowMenuShowPending();
}
@Override
public boolean showOverflowMenu() {
pullChildren();
- return mActionBarView.showOverflowMenu();
+ return mDecorToolbar.showOverflowMenu();
}
@Override
public boolean hideOverflowMenu() {
pullChildren();
- return mActionBarView.hideOverflowMenu();
+ return mDecorToolbar.hideOverflowMenu();
}
@Override
public void setMenuPrepared() {
pullChildren();
- mActionBarView.setMenuPrepared();
+ mDecorToolbar.setMenuPrepared();
}
@Override
public void setMenu(Menu menu, MenuPresenter.Callback cb) {
pullChildren();
- mActionBarView.setMenu(menu, cb);
+ mDecorToolbar.setMenu(menu, cb);
}
@Override
public void saveToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) {
pullChildren();
- mActionBarView.saveHierarchyState(toolbarStates);
+ mDecorToolbar.saveHierarchyState(toolbarStates);
}
@Override
public void restoreToolbarHierarchyState(SparseArray<Parcelable> toolbarStates) {
pullChildren();
- mActionBarView.restoreHierarchyState(toolbarStates);
+ mDecorToolbar.restoreHierarchyState(toolbarStates);
}
@Override
public void dismissPopups() {
pullChildren();
- mActionBarView.dismissPopupMenus();
+ mDecorToolbar.dismissPopupMenus();
}
public static class LayoutParams extends MarginLayoutParams {
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 60631b9..af82778 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -18,7 +18,6 @@ package com.android.internal.widget;
import android.animation.LayoutTransition;
import android.app.ActionBar;
-import android.app.ActionBar.OnNavigationListener;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -63,7 +62,7 @@ import com.android.internal.view.menu.SubMenuBuilder;
/**
* @hide
*/
-public class ActionBarView extends AbsActionBarView {
+public class ActionBarView extends AbsActionBarView implements DecorToolbar {
private static final String TAG = "ActionBarView";
/**
@@ -117,8 +116,7 @@ public class ActionBarView extends AbsActionBarView {
private boolean mUserTitle;
private boolean mIncludeTabs;
- private boolean mIsCollapsable;
- private boolean mIsCollapsed;
+ private boolean mIsCollapsible;
private boolean mWasHomeEnabled; // Was it enabled before action view expansion?
private MenuBuilder mOptionsMenu;
@@ -129,7 +127,7 @@ public class ActionBarView extends AbsActionBarView {
private ActionMenuItem mLogoNavItem;
private SpinnerAdapter mSpinnerAdapter;
- private OnNavigationListener mCallback;
+ private AdapterView.OnItemSelectedListener mNavItemSelectedListener;
private Runnable mTabSelector;
@@ -138,18 +136,6 @@ public class ActionBarView extends AbsActionBarView {
Window.Callback mWindowCallback;
- private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
- new AdapterView.OnItemSelectedListener() {
- public void onItemSelected(AdapterView parent, View view, int position, long id) {
- if (mCallback != null) {
- mCallback.onNavigationItemSelected(position, id);
- }
- }
- public void onNothingSelected(AdapterView parent) {
- // Do nothing
- }
- };
-
private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() {
@Override
public void onClick(View v) {
@@ -178,8 +164,6 @@ public class ActionBarView extends AbsActionBarView {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
com.android.internal.R.attr.actionBarStyle, 0);
- ApplicationInfo appInfo = context.getApplicationInfo();
- PackageManager pm = context.getPackageManager();
mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode,
ActionBar.NAVIGATION_MODE_STANDARD);
mTitle = a.getText(R.styleable.ActionBar_title);
@@ -260,7 +244,7 @@ public class ActionBarView extends AbsActionBarView {
}
if (mHomeDescriptionRes != 0) {
- setHomeActionContentDescription(mHomeDescriptionRes);
+ setNavigationContentDescription(mHomeDescriptionRes);
}
if (mTabScrollView != null && mIncludeTabs) {
@@ -313,7 +297,7 @@ public class ActionBarView extends AbsActionBarView {
}
@Override
- public void setSplitActionBar(boolean splitActionBar) {
+ public void setSplitToolbar(boolean splitActionBar) {
if (mSplitActionBar != splitActionBar) {
if (mMenuView != null) {
final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
@@ -349,18 +333,26 @@ public class ActionBarView extends AbsActionBarView {
mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
}
}
- super.setSplitActionBar(splitActionBar);
+ super.setSplitToolbar(splitActionBar);
}
}
- public boolean isSplitActionBar() {
+ public boolean isSplit() {
return mSplitActionBar;
}
+ public boolean canSplit() {
+ return true;
+ }
+
public boolean hasEmbeddedTabs() {
return mIncludeTabs;
}
+ public void setEmbeddedTabView(View view) {
+ setEmbeddedTabView((ScrollingTabContainerView) view);
+ }
+
public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
if (mTabScrollView != null) {
removeView(mTabScrollView);
@@ -376,10 +368,6 @@ public class ActionBarView extends AbsActionBarView {
}
}
- public void setCallback(OnNavigationListener callback) {
- mCallback = callback;
- }
-
public void setMenuPrepared() {
mMenuPrepared = true;
}
@@ -473,7 +461,7 @@ public class ActionBarView extends AbsActionBarView {
}
}
- public void setCustomNavigationView(View view) {
+ public void setCustomView(View view) {
final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
if (showCustom) {
ActionBarTransition.beginDelayedTransition(this);
@@ -765,15 +753,16 @@ public class ActionBarView extends AbsActionBarView {
}
}
- public void setDropdownAdapter(SpinnerAdapter adapter) {
+ public void setDropdownParams(SpinnerAdapter adapter, AdapterView.OnItemSelectedListener l) {
mSpinnerAdapter = adapter;
+ mNavItemSelectedListener = l;
if (mSpinner != null) {
mSpinner.setAdapter(adapter);
}
}
- public SpinnerAdapter getDropdownAdapter() {
- return mSpinnerAdapter;
+ public int getDropdownItemCount() {
+ return mSpinnerAdapter != null ? mSpinnerAdapter.getCount() : 0;
}
public void setDropdownSelectedPosition(int position) {
@@ -784,7 +773,7 @@ public class ActionBarView extends AbsActionBarView {
return mSpinner.getSelectedItemPosition();
}
- public View getCustomNavigationView() {
+ public View getCustomView() {
return mCustomNavView;
}
@@ -797,6 +786,11 @@ public class ActionBarView extends AbsActionBarView {
}
@Override
+ public ViewGroup getViewGroup() {
+ return this;
+ }
+
+ @Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
// Used by custom nav views if they don't supply layout params. Everything else
// added to an ActionBarView should have them already.
@@ -860,12 +854,8 @@ public class ActionBarView extends AbsActionBarView {
mContextView = view;
}
- public void setCollapsable(boolean collapsable) {
- mIsCollapsable = collapsable;
- }
-
- public boolean isCollapsed() {
- return mIsCollapsed;
+ public void setCollapsible(boolean collapsible) {
+ mIsCollapsible = collapsible;
}
/**
@@ -893,7 +883,7 @@ public class ActionBarView extends AbsActionBarView {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int childCount = getChildCount();
- if (mIsCollapsable) {
+ if (mIsCollapsible) {
int visibleChildren = 0;
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
@@ -915,11 +905,9 @@ public class ActionBarView extends AbsActionBarView {
if (visibleChildren == 0) {
// No size for an empty action bar when collapsable.
setMeasuredDimension(0, 0);
- mIsCollapsed = true;
return;
}
}
- mIsCollapsed = false;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
@@ -1323,20 +1311,20 @@ public class ActionBarView extends AbsActionBarView {
}
}
- public void setHomeAsUpIndicator(Drawable indicator) {
+ public void setNavigationIcon(Drawable indicator) {
mHomeLayout.setUpIndicator(indicator);
}
- public void setHomeAsUpIndicator(int resId) {
+ public void setNavigationIcon(int resId) {
mHomeLayout.setUpIndicator(resId);
}
- public void setHomeActionContentDescription(CharSequence description) {
+ public void setNavigationContentDescription(CharSequence description) {
mHomeDescription = description;
updateHomeAccessibility(mUpGoerFive.isEnabled());
}
- public void setHomeActionContentDescription(int resId) {
+ public void setNavigationContentDescription(int resId) {
mHomeDescriptionRes = resId;
mHomeDescription = resId != 0 ? getResources().getText(resId) : null;
updateHomeAccessibility(mUpGoerFive.isEnabled());
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
new file mode 100644
index 0000000..ee6988e
--- /dev/null
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.internal.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Parcelable;
+import android.util.SparseArray;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.SpinnerAdapter;
+import com.android.internal.view.menu.MenuPresenter;
+
+/**
+ * Common interface for a toolbar that sits as part of the window decor.
+ * Layouts that control window decor use this as a point of interaction with different
+ * bar implementations.
+ *
+ * @hide
+ */
+public interface DecorToolbar {
+ ViewGroup getViewGroup();
+ Context getContext();
+ boolean isSplit();
+ boolean hasExpandedActionView();
+ void collapseActionView();
+ void setWindowCallback(Window.Callback cb);
+ void setWindowTitle(CharSequence title);
+ CharSequence getTitle();
+ void setTitle(CharSequence title);
+ CharSequence getSubtitle();
+ void setSubtitle(CharSequence subtitle);
+ void initProgress();
+ void initIndeterminateProgress();
+ boolean canSplit();
+ void setSplitView(ViewGroup splitView);
+ void setSplitToolbar(boolean split);
+ void setSplitWhenNarrow(boolean splitWhenNarrow);
+ boolean hasIcon();
+ boolean hasLogo();
+ void setIcon(int resId);
+ void setIcon(Drawable d);
+ void setLogo(int resId);
+ void setLogo(Drawable d);
+ boolean canShowOverflowMenu();
+ boolean isOverflowMenuShowing();
+ boolean isOverflowMenuShowPending();
+ boolean showOverflowMenu();
+ boolean hideOverflowMenu();
+ void setMenuPrepared();
+ void setMenu(Menu menu, MenuPresenter.Callback cb);
+ void dismissPopupMenus();
+
+ int getDisplayOptions();
+ void setDisplayOptions(int opts);
+ void setEmbeddedTabView(View tabView);
+ boolean hasEmbeddedTabs();
+ boolean isTitleTruncated();
+ void setCollapsible(boolean collapsible);
+ void setHomeButtonEnabled(boolean enable);
+ int getNavigationMode();
+ void setNavigationMode(int mode);
+ void setDropdownParams(SpinnerAdapter adapter, AdapterView.OnItemSelectedListener listener);
+ void setDropdownSelectedPosition(int position);
+ int getDropdownSelectedPosition();
+ int getDropdownItemCount();
+ void setCustomView(View view);
+ View getCustomView();
+ void animateToVisibility(int visibility);
+ void setNavigationIcon(Drawable icon);
+ void setNavigationIcon(int resId);
+ void setNavigationContentDescription(CharSequence description);
+ void setNavigationContentDescription(int resId);
+ void saveHierarchyState(SparseArray<Parcelable> toolbarStates);
+ void restoreHierarchyState(SparseArray<Parcelable> toolbarStates);
+}
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
new file mode 100644
index 0000000..f90aaea
--- /dev/null
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.internal.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.ActionBar;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.ActionMenuPresenter;
+import android.widget.AdapterView;
+import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
+import android.widget.Toolbar;
+import com.android.internal.R;
+import com.android.internal.view.menu.ActionMenuItem;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuPresenter;
+
+/**
+ * Internal class used to interact with the Toolbar widget without
+ * exposing interface methods to the public API.
+ *
+ * <p>ToolbarWidgetWrapper manages the differences between Toolbar and ActionBarView
+ * so that either variant acting as a
+ * {@link com.android.internal.app.WindowDecorActionBar WindowDecorActionBar} can behave
+ * in the same way.</p>
+ *
+ * @hide
+ */
+public class ToolbarWidgetWrapper implements DecorToolbar {
+ private static final String TAG = "ToolbarWidgetWrapper";
+
+ private static final int AFFECTS_LOGO_MASK =
+ ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO;
+
+ private Toolbar mToolbar;
+
+ private int mDisplayOpts;
+ private View mTabView;
+ private Spinner mSpinner;
+ private View mCustomView;
+
+ private Drawable mIcon;
+ private Drawable mLogo;
+ private Drawable mNavIcon;
+
+ private boolean mTitleSet;
+ private CharSequence mTitle;
+ private CharSequence mSubtitle;
+
+ private Window.Callback mWindowCallback;
+ private boolean mMenuPrepared;
+ private ActionMenuPresenter mActionMenuPresenter;
+
+ public ToolbarWidgetWrapper(Toolbar toolbar) {
+ mToolbar = toolbar;
+
+ final TypedArray a = toolbar.getContext().obtainStyledAttributes(null,
+ R.styleable.ActionBar, R.attr.actionBarStyle, 0);
+
+ final CharSequence title = a.getText(R.styleable.ActionBar_title);
+ if (title != null) {
+ setTitle(title);
+ }
+
+ final CharSequence subtitle = a.getText(R.styleable.ActionBar_subtitle);
+ if (subtitle != null) {
+ setSubtitle(subtitle);
+ }
+
+ final Drawable logo = a.getDrawable(R.styleable.ActionBar_logo);
+ if (logo != null) {
+ setLogo(logo);
+ }
+
+ final Drawable icon = a.getDrawable(R.styleable.ActionBar_icon);
+ if (icon != null) {
+ setIcon(icon);
+ }
+
+ final Drawable navIcon = a.getDrawable(R.styleable.ActionBar_homeAsUpIndicator);
+ if (navIcon != null) {
+ setNavigationIcon(navIcon);
+ }
+
+ setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, 0));
+
+ final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
+ if (customNavId != 0) {
+ setCustomView(LayoutInflater.from(mToolbar.getContext()).inflate(customNavId,
+ mToolbar, false));
+ setDisplayOptions(mDisplayOpts | ActionBar.DISPLAY_SHOW_CUSTOM);
+ }
+
+ final int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
+ if (height > 0) {
+ final ViewGroup.LayoutParams lp = mToolbar.getLayoutParams();
+ lp.height = height;
+ mToolbar.setLayoutParams(lp);
+ }
+
+ final int contentInsetStart = a.getDimensionPixelOffset(
+ R.styleable.ActionBar_contentInsetStart, 0);
+ final int contentInsetEnd = a.getDimensionPixelOffset(
+ R.styleable.ActionBar_contentInsetEnd, 0);
+ if (contentInsetStart > 0 || contentInsetEnd > 0) {
+ mToolbar.setContentInsetsRelative(contentInsetStart, contentInsetEnd);
+ }
+
+ a.recycle();
+
+ mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(),
+ 0, android.R.id.home, 0, 0, mTitle);
+ @Override
+ public void onClick(View v) {
+ if (mWindowCallback != null && mMenuPrepared) {
+ mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mNavItem);
+ }
+ }
+ });
+ }
+
+ @Override
+ public ViewGroup getViewGroup() {
+ return mToolbar;
+ }
+
+ @Override
+ public Context getContext() {
+ return mToolbar.getContext();
+ }
+
+ @Override
+ public boolean isSplit() {
+ return false;
+ }
+
+ @Override
+ public boolean hasExpandedActionView() {
+ return mToolbar.hasExpandedActionView();
+ }
+
+ @Override
+ public void collapseActionView() {
+ mToolbar.collapseActionView();
+ }
+
+ @Override
+ public void setWindowCallback(Window.Callback cb) {
+ mWindowCallback = cb;
+ }
+
+ @Override
+ public void setWindowTitle(CharSequence title) {
+ // "Real" title always trumps window title.
+ if (!mTitleSet) {
+ setTitleInt(title);
+ }
+ }
+
+ @Override
+ public CharSequence getTitle() {
+ return mToolbar.getTitle();
+ }
+
+ @Override
+ public void setTitle(CharSequence title) {
+ mTitleSet = true;
+ setTitleInt(title);
+ }
+
+ private void setTitleInt(CharSequence title) {
+ mTitle = title;
+ if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ mToolbar.setTitle(title);
+ }
+ }
+
+ @Override
+ public CharSequence getSubtitle() {
+ return mToolbar.getSubtitle();
+ }
+
+ @Override
+ public void setSubtitle(CharSequence subtitle) {
+ mSubtitle = subtitle;
+ if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ mToolbar.setSubtitle(subtitle);
+ }
+ }
+
+ @Override
+ public void initProgress() {
+ Log.i(TAG, "Progress display unsupported");
+ }
+
+ @Override
+ public void initIndeterminateProgress() {
+ Log.i(TAG, "Progress display unsupported");
+ }
+
+ @Override
+ public boolean canSplit() {
+ return false;
+ }
+
+ @Override
+ public void setSplitView(ViewGroup splitView) {
+ }
+
+ @Override
+ public void setSplitToolbar(boolean split) {
+ if (split) {
+ throw new UnsupportedOperationException("Cannot split an android.widget.Toolbar");
+ }
+ }
+
+ @Override
+ public void setSplitWhenNarrow(boolean splitWhenNarrow) {
+ // Ignore.
+ }
+
+ @Override
+ public boolean hasIcon() {
+ return mIcon != null;
+ }
+
+ @Override
+ public boolean hasLogo() {
+ return mLogo != null;
+ }
+
+ @Override
+ public void setIcon(int resId) {
+ setIcon(resId != 0 ? getContext().getDrawable(resId) : null);
+ }
+
+ @Override
+ public void setIcon(Drawable d) {
+ mIcon = d;
+ updateToolbarLogo();
+ }
+
+ @Override
+ public void setLogo(int resId) {
+ setLogo(resId != 0 ? getContext().getDrawable(resId) : null);
+ }
+
+ @Override
+ public void setLogo(Drawable d) {
+ mLogo = d;
+ updateToolbarLogo();
+ }
+
+ private void updateToolbarLogo() {
+ Drawable logo = null;
+ if ((mDisplayOpts & ActionBar.DISPLAY_SHOW_HOME) != 0) {
+ if ((mDisplayOpts & ActionBar.DISPLAY_USE_LOGO) != 0) {
+ logo = mLogo != null ? mLogo : mIcon;
+ } else {
+ logo = mIcon;
+ }
+ }
+ mToolbar.setLogo(logo);
+ }
+
+ @Override
+ public boolean canShowOverflowMenu() {
+ return mToolbar.canShowOverflowMenu();
+ }
+
+ @Override
+ public boolean isOverflowMenuShowing() {
+ return mToolbar.isOverflowMenuShowing();
+ }
+
+ @Override
+ public boolean isOverflowMenuShowPending() {
+ return mToolbar.isOverflowMenuShowPending();
+ }
+
+ @Override
+ public boolean showOverflowMenu() {
+ return mToolbar.showOverflowMenu();
+ }
+
+ @Override
+ public boolean hideOverflowMenu() {
+ return mToolbar.hideOverflowMenu();
+ }
+
+ @Override
+ public void setMenuPrepared() {
+ mMenuPrepared = true;
+ }
+
+ @Override
+ public void setMenu(Menu menu, MenuPresenter.Callback cb) {
+ if (mActionMenuPresenter == null) {
+ mActionMenuPresenter = new ActionMenuPresenter(mToolbar.getContext());
+ mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
+ }
+ mActionMenuPresenter.setCallback(cb);
+ mToolbar.setMenu((MenuBuilder) menu, mActionMenuPresenter);
+ }
+
+ @Override
+ public void dismissPopupMenus() {
+ mToolbar.dismissPopupMenus();
+ }
+
+ @Override
+ public int getDisplayOptions() {
+ return mDisplayOpts;
+ }
+
+ @Override
+ public void setDisplayOptions(int newOpts) {
+ final int oldOpts = mDisplayOpts;
+ final int changed = oldOpts ^ newOpts;
+ mDisplayOpts = newOpts;
+ if (changed != 0) {
+ if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ if ((newOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ mToolbar.setNavigationIcon(mNavIcon);
+ } else {
+ mToolbar.setNavigationIcon(null);
+ }
+ }
+
+ if ((changed & AFFECTS_LOGO_MASK) != 0) {
+ updateToolbarLogo();
+ }
+
+ if ((changed & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ if ((newOpts & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
+ mToolbar.setTitle(mTitle);
+ mToolbar.setSubtitle(mSubtitle);
+ } else {
+ mToolbar.setTitle(null);
+ mToolbar.setSubtitle(null);
+ }
+ }
+
+ if ((changed & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomView != null) {
+ if ((newOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
+ mToolbar.addView(mCustomView);
+ } else {
+ mToolbar.removeView(mCustomView);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setEmbeddedTabView(View tabView) {
+ mTabView = tabView;
+ }
+
+ @Override
+ public boolean hasEmbeddedTabs() {
+ return mTabView != null;
+ }
+
+ @Override
+ public boolean isTitleTruncated() {
+ return mToolbar.isTitleTruncated();
+ }
+
+ @Override
+ public void setCollapsible(boolean collapsible) {
+ // Ignore
+ }
+
+ @Override
+ public void setHomeButtonEnabled(boolean enable) {
+ // Ignore
+ }
+
+ @Override
+ public int getNavigationMode() {
+ return 0;
+ }
+
+ @Override
+ public void setNavigationMode(int mode) {
+ if (mode != ActionBar.NAVIGATION_MODE_STANDARD) {
+ throw new IllegalArgumentException(
+ "Navigation modes not supported in this configuration");
+ }
+ }
+
+ @Override
+ public void setDropdownParams(SpinnerAdapter adapter,
+ AdapterView.OnItemSelectedListener listener) {
+ if (mSpinner == null) {
+ mSpinner = new Spinner(getContext());
+ }
+ mSpinner.setAdapter(adapter);
+ mSpinner.setOnItemSelectedListener(listener);
+ }
+
+ @Override
+ public void setDropdownSelectedPosition(int position) {
+ if (mSpinner == null) {
+ throw new IllegalStateException(
+ "Can't set dropdown selected position without an adapter");
+ }
+ mSpinner.setSelection(position);
+ }
+
+ @Override
+ public int getDropdownSelectedPosition() {
+ return mSpinner != null ? mSpinner.getSelectedItemPosition() : 0;
+ }
+
+ @Override
+ public int getDropdownItemCount() {
+ return mSpinner != null ? mSpinner.getCount() : 0;
+ }
+
+ @Override
+ public void setCustomView(View view) {
+ if (mCustomView != null && (mDisplayOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
+ mToolbar.removeView(mCustomView);
+ }
+ mCustomView = view;
+ if (view != null && (mDisplayOpts & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
+ mToolbar.addView(mCustomView);
+ }
+ }
+
+ @Override
+ public View getCustomView() {
+ return mCustomView;
+ }
+
+ @Override
+ public void animateToVisibility(int visibility) {
+ if (visibility == View.GONE) {
+ mToolbar.animate().translationY(mToolbar.getHeight()).alpha(0)
+ .setListener(new AnimatorListenerAdapter() {
+ private boolean mCanceled = false;
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mCanceled) {
+ mToolbar.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCanceled = true;
+ }
+ });
+ } else if (visibility == View.VISIBLE) {
+ mToolbar.animate().translationY(0).alpha(1)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mToolbar.setVisibility(View.VISIBLE);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void setNavigationIcon(Drawable icon) {
+ mNavIcon = icon;
+ if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ mToolbar.setNavigationIcon(icon);
+ }
+ }
+
+ @Override
+ public void setNavigationIcon(int resId) {
+ setNavigationIcon(mToolbar.getContext().getDrawable(resId));
+ }
+
+ @Override
+ public void setNavigationContentDescription(CharSequence description) {
+ mToolbar.setNavigationContentDescription(description);
+ }
+
+ @Override
+ public void setNavigationContentDescription(int resId) {
+ mToolbar.setNavigationContentDescription(resId);
+ }
+
+ @Override
+ public void saveHierarchyState(SparseArray<Parcelable> toolbarStates) {
+ mToolbar.saveHierarchyState(toolbarStates);
+ }
+
+ @Override
+ public void restoreHierarchyState(SparseArray<Parcelable> toolbarStates) {
+ mToolbar.restoreHierarchyState(toolbarStates);
+ }
+
+}
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
new file mode 100644
index 0000000..290c7da
--- /dev/null
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+This is an optimized layout for a screen with a toolbar enabled.
+-->
+
+<com.android.internal.widget.ActionBarOverlayLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/decor_content_parent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:splitMotionEvents="false"
+ android:theme="?attr/actionBarTheme">
+ <FrameLayout android:id="@android:id/content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <com.android.internal.widget.ActionBarContainer
+ android:id="@+id/action_bar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ style="?attr/actionBarStyle"
+ android:viewName="android:action_bar"
+ android:gravity="top">
+ <Toolbar
+ android:id="@+id/action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?attr/toolbarStyle" />
+ <com.android.internal.widget.ActionBarContextView
+ android:id="@+id/action_context_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?attr/actionModeStyle" />
+ </com.android.internal.widget.ActionBarContainer>
+</com.android.internal.widget.ActionBarOverlayLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c05dfca..5fec907 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -493,6 +493,9 @@
{@link android.view.Window#setAllowExitTransitionOverlap(boolean)}. -->
<attr name="windowAllowExitTransitionOverlap" format="boolean"/>
+ <!-- Internal layout used internally for window decor -->
+ <attr name="windowActionBarFullscreenDecorLayout" format="reference" />
+
<!-- ============ -->
<!-- Alert Dialog styles -->
<!-- ============ -->
@@ -685,6 +688,7 @@
<!-- Default ActivityChooserView style. -->
<attr name="activityChooserViewStyle" format="reference" />
+ <!-- Default Toolbar style. -->
<attr name="toolbarStyle" format="reference" />
<!-- Fast scroller styles -->
@@ -1713,6 +1717,7 @@
<attr name="windowSwipeToDismiss" />
<attr name="windowContentTransitions" />
<attr name="windowContentTransitionManager" />
+ <attr name="windowActionBarFullscreenDecorLayout" />
<!-- The minimum width the window is allowed to be, along the major
axis of the screen. That is, when in landscape. Can be either
@@ -6398,11 +6403,17 @@
<attr name="indeterminateProgressStyle" format="reference" />
<!-- Specifies the horizontal padding on either end for an embedded progress bar. -->
<attr name="progressBarPadding" format="dimension" />
+ <!-- Up navigation glyph -->
+ <attr name="homeAsUpIndicator" />
<!-- Specifies padding that should be applied to the left and right sides of
system-provided items in the bar. -->
<attr name="itemPadding" format="dimension" />
<!-- Set true to hide the action bar on a vertical nested scroll of content. -->
<attr name="hideOnContentScroll" format="boolean" />
+ <attr name="contentInsetStart" format="dimension" />
+ <attr name="contentInsetEnd" format="dimension" />
+ <attr name="contentInsetLeft" format="dimension" />
+ <attr name="contentInsetRight" format="dimension" />
</declare-styleable>
<declare-styleable name="ActionMode">
@@ -6653,10 +6664,19 @@
<attr name="titleMarginEnd" format="dimension" />
<attr name="titleMarginTop" format="dimension" />
<attr name="titleMarginBottom" format="dimension" />
- <attr name="contentInsetStart" format="dimension" />
- <attr name="contentInsetEnd" format="dimension" />
- <attr name="contentInsetLeft" format="dimension" />
- <attr name="contentInsetRight" format="dimension" />
+ <attr name="contentInsetStart" />
+ <attr name="contentInsetEnd" />
+ <attr name="contentInsetLeft" />
+ <attr name="contentInsetRight" />
+ <attr name="maxButtonHeight" format="dimension" />
+ <attr name="navigationButtonStyle" format="reference" />
+ <attr name="buttonGravity">
+ <!-- Push object to the top of its container, not changing its size. -->
+ <flag name="top" value="0x30" />
+ <!-- Push object to the bottom of its container, not changing its size. -->
+ <flag name="bottom" value="0x50" />
+ </attr>
+ <attr name="collapseIcon" format="reference" />
</declare-styleable>
<declare-styleable name="Toolbar_LayoutParams">
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f6cd9e8..fc6110d 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1197,6 +1197,16 @@ please see styles_device_defaults.xml.
<item name="android:subtitleTextAppearance">@android:style/TextAppearance.Widget.Toolbar.Subtitle</item>
<item name="android:minHeight">?android:attr/actionBarSize</item>
<item name="android:titleMargins">4dp</item>
+ <item name="android:maxButtonHeight">56dp</item>
+ <item name="android:buttonGravity">top</item>
+ <item name="android:navigationButtonStyle">@android:style/Widget.Toolbar.Button.Navigation</item>
+ <item name="android:collapseIcon">?android:attr/homeAsUpIndicator</item>
+ </style>
+
+ <style name="Widget.Toolbar.Button.Navigation" parent="@android:style/Widget">
+ <item name="android:background">?android:attr/selectableItemBackground</item>
+ <item name="android:minWidth">56dp</item>
+ <item name="android:scaleType">center</item>
</style>
<style name="TextAppearance.Widget.ActionBar.Title"
@@ -2394,7 +2404,6 @@ please see styles_device_defaults.xml.
<item name="android:background">@android:drawable/ab_transparent_light_holo</item>
<item name="android:backgroundStacked">@android:drawable/ab_stacked_transparent_light_holo</item>
<item name="android:backgroundSplit">@android:drawable/ab_bottom_transparent_light_holo</item>
- <item name="android:homeAsUpIndicator">@android:drawable/ic_ab_back_holo_light</item>
<item name="android:progressBarStyle">@android:style/Widget.Holo.Light.ProgressBar.Horizontal</item>
<item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.Light.ProgressBar</item>
</style>
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index 2e7a5b1..ea32681 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -773,7 +773,7 @@ please see styles_device_defaults.xml.
<item name="background">@null</item>
<item name="backgroundStacked">@null</item>
<item name="backgroundSplit">@null</item>
- <item name="displayOptions">useLogo|showHome|showTitle</item>
+ <item name="displayOptions">showTitle</item>
<item name="divider">?attr/dividerVertical</item>
<item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
<item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
@@ -783,6 +783,7 @@ please see styles_device_defaults.xml.
<item name="itemPadding">8dip</item>
<item name="homeLayout">@layout/action_bar_home_quantum</item>
<item name="gravity">center_vertical</item>
+ <item name="contentInsetStart">56dp</item>
</style>
<style name="Widget.Quantum.ActionBar.Solid">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 69f73e5..4109d03 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1862,6 +1862,7 @@
<java-symbol type="attr" name="toolbarStyle" />
<java-symbol type="attr" name="titleTextAppearance" />
<java-symbol type="attr" name="subtitleTextAppearance" />
+ <java-symbol type="attr" name="windowActionBarFullscreenDecorLayout" />
<java-symbol type="drawable" name="ic_lock_bugreport" />
<java-symbol type="id" name="icon_frame" />
<java-symbol type="style" name="Animation.VolumePanel" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index aaab949..41f4ff8 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -192,6 +192,7 @@ please see themes_device_defaults.xml.
<item name="windowDrawsSystemBarBackgrounds">false</item>
<item name="statusBarColor">@android:color/black</item>
<item name="navigationBarColor">@android:color/black</item>
+ <item name="windowActionBarFullscreenDecorLayout">@layout/screen_action_bar</item>
<!-- Define these here; ContextThemeWrappers around themes that define them should
always clear these values. -->
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
index bb787bb..484c694 100644
--- a/core/res/res/values/themes_quantum.xml
+++ b/core/res/res/values/themes_quantum.xml
@@ -162,6 +162,7 @@ please see themes_device_defaults.xml.
<item name="windowActionBar">true</item>
<item name="windowActionModeOverlay">false</item>
<item name="windowDrawsSystemBarBackgrounds">true</item>
+ <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
<item name="statusBarColor">?attr/colorPrimaryDark</item>
<item name="navigationBarColor">?attr/colorPrimaryDark</item>
@@ -505,6 +506,7 @@ please see themes_device_defaults.xml.
<item name="windowActionBar">true</item>
<item name="windowActionModeOverlay">false</item>
<item name="windowDrawsSystemBarBackgrounds">true</item>
+ <item name="windowActionBarFullscreenDecorLayout">@layout/screen_toolbar</item>
<item name="statusBarColor">?attr/colorPrimaryDark</item>
<item name="navigationBarColor">?attr/colorPrimaryDark</item>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 2fea785..6b0095a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -3179,7 +3179,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
com.android.internal.R.attr.dialogTitleDecorLayout, res, true);
layoutResource = res.resourceId;
} else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
- layoutResource = com.android.internal.R.layout.screen_action_bar;
+ layoutResource = a.getResourceId(
+ com.android.internal.R.styleable.Window_windowActionBarFullscreenDecorLayout,
+ com.android.internal.R.layout.screen_action_bar);
} else {
layoutResource = com.android.internal.R.layout.screen_title;
}