blob: dda1a105d76c8d9b904650f95ad9ab6fbc169bc0 [file] [log] [blame]
Adam Powell33b97432010-04-20 10:01:14 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Adam Powell89e06452010-06-23 20:24:52 -070017package com.android.internal.widget;
Adam Powell33b97432010-04-20 10:01:14 -070018
Adam Powell96675b12010-06-10 18:58:59 -070019import com.android.internal.R;
Adam Powell96675b12010-06-10 18:58:59 -070020import com.android.internal.view.menu.ActionMenuItem;
Adam Powell696cba52011-03-29 10:38:16 -070021import com.android.internal.view.menu.ActionMenuPresenter;
Adam Powell7ade1be2010-06-17 12:51:21 -070022import com.android.internal.view.menu.ActionMenuView;
Adam Powell96675b12010-06-10 18:58:59 -070023import com.android.internal.view.menu.MenuBuilder;
Adam Powell8d02dea2011-05-31 21:35:13 -070024import com.android.internal.view.menu.MenuItemImpl;
Adam Powell696cba52011-03-29 10:38:16 -070025import com.android.internal.view.menu.MenuPresenter;
Adam Powell8d02dea2011-05-31 21:35:13 -070026import com.android.internal.view.menu.MenuView;
27import com.android.internal.view.menu.SubMenuBuilder;
Adam Powell33b97432010-04-20 10:01:14 -070028
Adam Powellfd75eef2012-08-02 10:27:31 -070029import android.animation.LayoutTransition;
Adam Powell33b97432010-04-20 10:01:14 -070030import android.app.ActionBar;
Adam Powell8515ee82010-11-30 14:09:55 -080031import android.app.ActionBar.OnNavigationListener;
Adam Powell9146ac72010-08-16 18:53:38 -070032import android.app.Activity;
Adam Powell33b97432010-04-20 10:01:14 -070033import android.content.Context;
34import android.content.pm.ApplicationInfo;
35import android.content.pm.PackageManager;
Adam Powell9ab97872010-10-26 21:47:29 -070036import android.content.pm.PackageManager.NameNotFoundException;
Adam Powell45c0b192011-07-28 15:11:57 -070037import android.content.res.Configuration;
Adam Powell33b97432010-04-20 10:01:14 -070038import android.content.res.TypedArray;
Adam Powell33b97432010-04-20 10:01:14 -070039import android.graphics.drawable.Drawable;
Adam Powell8d02dea2011-05-31 21:35:13 -070040import android.os.Parcel;
41import android.os.Parcelable;
Adam Powell27cba382013-01-22 18:55:20 -080042import android.text.Layout;
Adam Powell2a7ea672011-01-23 20:25:15 -080043import android.text.TextUtils;
Adam Powell33b97432010-04-20 10:01:14 -070044import android.util.AttributeSet;
Adam Powell9ab97872010-10-26 21:47:29 -070045import android.util.Log;
Adam Powell038f1c82011-07-21 14:28:10 -070046import android.view.CollapsibleActionView;
Adam Powell661c9082010-07-02 10:09:44 -070047import android.view.Gravity;
Adam Powell89e06452010-06-23 20:24:52 -070048import android.view.LayoutInflater;
49import android.view.Menu;
Adam Powell8d02dea2011-05-31 21:35:13 -070050import android.view.MenuItem;
Adam Powell7bc3ca02011-08-26 18:29:58 -070051import android.view.MotionEvent;
Adam Powell89e06452010-06-23 20:24:52 -070052import android.view.View;
53import android.view.ViewGroup;
Adam Powell9ab97872010-10-26 21:47:29 -070054import android.view.ViewParent;
Adam Powell8d12e202010-11-15 16:44:17 -080055import android.view.Window;
Adam Powell7bc3ca02011-08-26 18:29:58 -070056import android.view.accessibility.AccessibilityEvent;
Adam Powella4082912010-06-04 18:34:02 -070057import android.widget.AdapterView;
Adam Powell2b0952b2011-03-09 00:15:38 -080058import android.widget.FrameLayout;
Adam Powell33b97432010-04-20 10:01:14 -070059import android.widget.ImageView;
Adam Powell0e94b512010-06-29 17:58:20 -070060import android.widget.LinearLayout;
Adam Powell6af97e12010-11-11 21:11:53 -080061import android.widget.ProgressBar;
Adam Powella4082912010-06-04 18:34:02 -070062import android.widget.Spinner;
63import android.widget.SpinnerAdapter;
Adam Powell33b97432010-04-20 10:01:14 -070064import android.widget.TextView;
65
Adam Powell33b97432010-04-20 10:01:14 -070066/**
67 * @hide
68 */
Adam Powell640a66e2011-04-29 10:18:53 -070069public class ActionBarView extends AbsActionBarView {
Adam Powell33b97432010-04-20 10:01:14 -070070 private static final String TAG = "ActionBarView";
Adam Powellbe4d68e2010-10-08 18:16:34 -070071
Adam Powell33b97432010-04-20 10:01:14 -070072 /**
73 * Display options applied by default
74 */
75 public static final int DISPLAY_DEFAULT = 0;
76
77 /**
78 * Display options that require re-layout as opposed to a simple invalidate
79 */
Adam Powella1700782010-05-13 13:27:35 -070080 private static final int DISPLAY_RELAYOUT_MASK =
Adam Powell9ab97872010-10-26 21:47:29 -070081 ActionBar.DISPLAY_SHOW_HOME |
82 ActionBar.DISPLAY_USE_LOGO |
83 ActionBar.DISPLAY_HOME_AS_UP |
84 ActionBar.DISPLAY_SHOW_CUSTOM |
Adam Powell27cba382013-01-22 18:55:20 -080085 ActionBar.DISPLAY_SHOW_TITLE |
86 ActionBar.DISPLAY_TITLE_MULTIPLE_LINES;
Adam Powell9ab97872010-10-26 21:47:29 -070087
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -070088 private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
Casey Burkhardt8452a7f2013-04-30 15:56:41 -070089
Adam Powell33b97432010-04-20 10:01:14 -070090 private int mNavigationMode;
Adam Powell82f24e82011-08-18 20:15:20 -070091 private int mDisplayOptions = -1;
Adam Powell33b97432010-04-20 10:01:14 -070092 private CharSequence mTitle;
93 private CharSequence mSubtitle;
94 private Drawable mIcon;
95 private Drawable mLogo;
Adam Powelle0e2f4f2013-04-05 16:27:35 -070096 private CharSequence mHomeDescription;
97 private int mHomeDescriptionRes;
Adam Powell33b97432010-04-20 10:01:14 -070098
Adam Powell8d02dea2011-05-31 21:35:13 -070099 private HomeView mHomeLayout;
100 private HomeView mExpandedHomeLayout;
Adam Powell0e94b512010-06-29 17:58:20 -0700101 private LinearLayout mTitleLayout;
Adam Powell33b97432010-04-20 10:01:14 -0700102 private TextView mTitleView;
103 private TextView mSubtitleView;
Adam Powell54c7d7e2011-06-17 20:30:13 -0700104 private View mTitleUpView;
Adam Powell27cba382013-01-22 18:55:20 -0800105 private ViewGroup mUpGoerFive;
Adam Powell54c7d7e2011-06-17 20:30:13 -0700106
Adam Powella4082912010-06-04 18:34:02 -0700107 private Spinner mSpinner;
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800108 private LinearLayout mListNavLayout;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700109 private ScrollingTabContainerView mTabScrollView;
Adam Powella4082912010-06-04 18:34:02 -0700110 private View mCustomNavView;
Adam Powell6af97e12010-11-11 21:11:53 -0800111 private ProgressBar mProgressView;
112 private ProgressBar mIndeterminateProgressView;
113
114 private int mProgressBarPadding;
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800115 private int mItemPadding;
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700116
Adam Powelle2194442010-08-12 18:13:03 -0700117 private int mTitleStyleRes;
118 private int mSubtitleStyleRes;
Adam Powell6af97e12010-11-11 21:11:53 -0800119 private int mProgressStyle;
120 private int mIndeterminateProgressStyle;
Adam Powelle2194442010-08-12 18:13:03 -0700121
Adam Powelle92ea342010-07-14 14:45:50 -0700122 private boolean mUserTitle;
Adam Powelldae78242011-04-25 15:23:41 -0700123 private boolean mIncludeTabs;
Adam Powelld21aa122011-05-27 13:09:52 -0700124 private boolean mIsCollapsable;
Adam Powellf6ce6a92011-06-29 10:25:01 -0700125 private boolean mIsCollapsed;
Adam Powell62f33032013-02-04 12:44:34 -0800126 private boolean mWasHomeEnabled; // Was it enabled before action view expansion?
Adam Powell33b97432010-04-20 10:01:14 -0700127
Adam Powell96675b12010-06-10 18:58:59 -0700128 private MenuBuilder mOptionsMenu;
Adam Powell8c16aa92013-04-04 10:47:52 -0700129 private boolean mMenuPrepared;
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700130
Adam Powelle2194442010-08-12 18:13:03 -0700131 private ActionBarContextView mContextView;
132
Adam Powell33b97432010-04-20 10:01:14 -0700133 private ActionMenuItem mLogoNavItem;
Adam Powell9ab97872010-10-26 21:47:29 -0700134
135 private SpinnerAdapter mSpinnerAdapter;
Adam Powell8515ee82010-11-30 14:09:55 -0800136 private OnNavigationListener mCallback;
Adam Powell33b97432010-04-20 10:01:14 -0700137
Adam Powellf8ac6b72011-05-23 18:14:09 -0700138 private Runnable mTabSelector;
139
Adam Powell8d02dea2011-05-31 21:35:13 -0700140 private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
141 View mExpandedActionView;
142
Adam Powell915ce0d2011-09-28 15:52:57 -0700143 Window.Callback mWindowCallback;
144
Adam Powella4082912010-06-04 18:34:02 -0700145 private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
146 new AdapterView.OnItemSelectedListener() {
147 public void onItemSelected(AdapterView parent, View view, int position, long id) {
148 if (mCallback != null) {
149 mCallback.onNavigationItemSelected(position, id);
150 }
151 }
152 public void onNothingSelected(AdapterView parent) {
153 // Do nothing
154 }
155 };
156
Adam Powell8d02dea2011-05-31 21:35:13 -0700157 private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() {
158 @Override
159 public void onClick(View v) {
160 final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem;
161 if (item != null) {
162 item.collapseActionView();
163 }
164 }
165 };
Adam Powell2b6230e2010-09-07 17:55:25 -0700166
Adam Powell54c7d7e2011-06-17 20:30:13 -0700167 private final OnClickListener mUpClickListener = new OnClickListener() {
168 public void onClick(View v) {
Adam Powell8c16aa92013-04-04 10:47:52 -0700169 if (mMenuPrepared) {
170 // Only invoke the window callback if the options menu has been initialized.
171 mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem);
172 }
Adam Powell54c7d7e2011-06-17 20:30:13 -0700173 }
174 };
175
Adam Powell33b97432010-04-20 10:01:14 -0700176 public ActionBarView(Context context, AttributeSet attrs) {
177 super(context, attrs);
178
Adam Powell654e4e42011-01-03 16:33:50 -0800179 // Background is always provided by the container.
180 setBackgroundResource(0);
181
Adam Powell45c0b192011-07-28 15:11:57 -0700182 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
183 com.android.internal.R.attr.actionBarStyle, 0);
Adam Powell33b97432010-04-20 10:01:14 -0700184
Adam Powell9ab97872010-10-26 21:47:29 -0700185 ApplicationInfo appInfo = context.getApplicationInfo();
Adam Powell33b97432010-04-20 10:01:14 -0700186 PackageManager pm = context.getPackageManager();
Adam Powell661c9082010-07-02 10:09:44 -0700187 mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode,
188 ActionBar.NAVIGATION_MODE_STANDARD);
Adam Powell33b97432010-04-20 10:01:14 -0700189 mTitle = a.getText(R.styleable.ActionBar_title);
190 mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700191
Adam Powell33b97432010-04-20 10:01:14 -0700192 mLogo = a.getDrawable(R.styleable.ActionBar_logo);
193 if (mLogo == null) {
Adam Powell9ab97872010-10-26 21:47:29 -0700194 if (context instanceof Activity) {
195 try {
196 mLogo = pm.getActivityLogo(((Activity) context).getComponentName());
197 } catch (NameNotFoundException e) {
198 Log.e(TAG, "Activity component name not found!", e);
199 }
200 }
201 if (mLogo == null) {
202 mLogo = appInfo.loadLogo(pm);
203 }
Adam Powell33b97432010-04-20 10:01:14 -0700204 }
Adam Powell9ab97872010-10-26 21:47:29 -0700205
Adam Powell33b97432010-04-20 10:01:14 -0700206 mIcon = a.getDrawable(R.styleable.ActionBar_icon);
207 if (mIcon == null) {
Adam Powell9ab97872010-10-26 21:47:29 -0700208 if (context instanceof Activity) {
209 try {
210 mIcon = pm.getActivityIcon(((Activity) context).getComponentName());
211 } catch (NameNotFoundException e) {
212 Log.e(TAG, "Activity component name not found!", e);
213 }
214 }
215 if (mIcon == null) {
216 mIcon = appInfo.loadIcon(pm);
217 }
Adam Powell33b97432010-04-20 10:01:14 -0700218 }
Adam Powell9ab97872010-10-26 21:47:29 -0700219
Ed Heyl1c603002010-11-18 12:18:23 -0800220 final LayoutInflater inflater = LayoutInflater.from(context);
Adam Powell9ab97872010-10-26 21:47:29 -0700221
Ed Heyl1c603002010-11-18 12:18:23 -0800222 final int homeResId = a.getResourceId(
Adam Powellb33be1c2010-11-18 12:11:40 -0800223 com.android.internal.R.styleable.ActionBar_homeLayout,
224 com.android.internal.R.layout.action_bar_home);
Adam Powell9ab97872010-10-26 21:47:29 -0700225
Adam Powell27cba382013-01-22 18:55:20 -0800226 mUpGoerFive = (ViewGroup) inflater.inflate(
227 com.android.internal.R.layout.action_bar_up_container, this, false);
228 mHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
Ed Heyl1c603002010-11-18 12:18:23 -0800229
Adam Powell27cba382013-01-22 18:55:20 -0800230 mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
Adam Powell8d02dea2011-05-31 21:35:13 -0700231 mExpandedHomeLayout.setUp(true);
232 mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
Adam Powell7bc3ca02011-08-26 18:29:58 -0700233 mExpandedHomeLayout.setContentDescription(getResources().getText(
234 R.string.action_bar_up_description));
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700235
Adam Powell62f33032013-02-04 12:44:34 -0800236 // This needs to highlight/be focusable on its own.
237 // TODO: Clean up the handoff between expanded/normal.
238 final Drawable upBackground = mUpGoerFive.getBackground();
239 if (upBackground != null) {
240 mExpandedHomeLayout.setBackground(upBackground.getConstantState().newDrawable());
241 }
242 mExpandedHomeLayout.setEnabled(true);
243 mExpandedHomeLayout.setFocusable(true);
244
Adam Powelle2194442010-08-12 18:13:03 -0700245 mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
246 mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
Adam Powell6af97e12010-11-11 21:11:53 -0800247 mProgressStyle = a.getResourceId(R.styleable.ActionBar_progressBarStyle, 0);
248 mIndeterminateProgressStyle = a.getResourceId(
249 R.styleable.ActionBar_indeterminateProgressStyle, 0);
250
251 mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_progressBarPadding, 0);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800252 mItemPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_itemPadding, 0);
Adam Powelle2194442010-08-12 18:13:03 -0700253
Adam Powell9ab97872010-10-26 21:47:29 -0700254 setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT));
255
Adam Powell33b97432010-04-20 10:01:14 -0700256 final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
257 if (customNavId != 0) {
Ed Heyl1c603002010-11-18 12:18:23 -0800258 mCustomNavView = (View) inflater.inflate(customNavId, this, false);
Adam Powell9ab97872010-10-26 21:47:29 -0700259 mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
260 setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM);
Adam Powell33b97432010-04-20 10:01:14 -0700261 }
262
Adam Powelle2194442010-08-12 18:13:03 -0700263 mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700264
Adam Powell33b97432010-04-20 10:01:14 -0700265 a.recycle();
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700266
Ben Komaload199ec2010-11-01 12:24:16 -0700267 mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
Adam Powell27cba382013-01-22 18:55:20 -0800268
269 mUpGoerFive.setOnClickListener(mUpClickListener);
270 mUpGoerFive.setClickable(true);
271 mUpGoerFive.setFocusable(true);
Svetoslav Ganov42138042012-03-20 11:51:39 -0700272
273 if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
274 setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
275 }
Adam Powell33b97432010-04-20 10:01:14 -0700276 }
Adam Powella7db0372010-06-30 17:08:47 -0700277
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700278 @Override
Adam Powell45c0b192011-07-28 15:11:57 -0700279 protected void onConfigurationChanged(Configuration newConfig) {
280 super.onConfigurationChanged(newConfig);
281
Adam Powell07a047f2011-08-31 10:33:20 -0700282 mTitleView = null;
283 mSubtitleView = null;
284 mTitleUpView = null;
Adam Powell27cba382013-01-22 18:55:20 -0800285 if (mTitleLayout != null && mTitleLayout.getParent() == mUpGoerFive) {
286 mUpGoerFive.removeView(mTitleLayout);
Adam Powell07a047f2011-08-31 10:33:20 -0700287 }
288 mTitleLayout = null;
289 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
290 initTitle();
291 }
Adam Powell425689e2011-09-08 18:09:33 -0700292
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700293 if (mHomeDescriptionRes != 0) {
294 setHomeActionContentDescription(mHomeDescriptionRes);
295 }
296
Adam Powell425689e2011-09-08 18:09:33 -0700297 if (mTabScrollView != null && mIncludeTabs) {
298 ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
Adam Powellb8440112011-09-12 19:14:11 -0700299 if (lp != null) {
300 lp.width = LayoutParams.WRAP_CONTENT;
301 lp.height = LayoutParams.MATCH_PARENT;
302 }
Adam Powell425689e2011-09-08 18:09:33 -0700303 mTabScrollView.setAllowCollapse(true);
304 }
Adam Powell45c0b192011-07-28 15:11:57 -0700305 }
306
Adam Powell915ce0d2011-09-28 15:52:57 -0700307 /**
308 * Set the window callback used to invoke menu items; used for dispatching home button presses.
309 * @param cb Window callback to dispatch to
310 */
311 public void setWindowCallback(Window.Callback cb) {
312 mWindowCallback = cb;
313 }
314
Adam Powell45c0b192011-07-28 15:11:57 -0700315 @Override
Adam Powellf8ac6b72011-05-23 18:14:09 -0700316 public void onDetachedFromWindow() {
317 super.onDetachedFromWindow();
318 removeCallbacks(mTabSelector);
Adam Powell97e18362011-10-20 15:37:18 -0700319 if (mActionMenuPresenter != null) {
320 mActionMenuPresenter.hideOverflowMenu();
321 mActionMenuPresenter.hideSubMenus();
322 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700323 }
324
325 @Override
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700326 public boolean shouldDelayChildPressedState() {
327 return false;
328 }
329
Adam Powell6af97e12010-11-11 21:11:53 -0800330 public void initProgress() {
331 mProgressView = new ProgressBar(mContext, null, 0, mProgressStyle);
332 mProgressView.setId(R.id.progress_horizontal);
333 mProgressView.setMax(10000);
Adam Powell45b075d2012-01-09 15:41:40 -0800334 mProgressView.setVisibility(GONE);
Adam Powell6af97e12010-11-11 21:11:53 -0800335 addView(mProgressView);
336 }
337
338 public void initIndeterminateProgress() {
339 mIndeterminateProgressView = new ProgressBar(mContext, null, 0,
340 mIndeterminateProgressStyle);
341 mIndeterminateProgressView.setId(R.id.progress_circular);
Adam Powell45b075d2012-01-09 15:41:40 -0800342 mIndeterminateProgressView.setVisibility(GONE);
Adam Powell6af97e12010-11-11 21:11:53 -0800343 addView(mIndeterminateProgressView);
344 }
345
Adam Powella05aba92011-09-23 14:22:49 -0700346 @Override
Adam Powell9b4bee02011-04-27 19:24:47 -0700347 public void setSplitActionBar(boolean splitActionBar) {
348 if (mSplitActionBar != splitActionBar) {
349 if (mMenuView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700350 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
351 if (oldParent != null) {
352 oldParent.removeView(mMenuView);
353 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700354 if (splitActionBar) {
Adam Powell9b4bee02011-04-27 19:24:47 -0700355 if (mSplitView != null) {
356 mSplitView.addView(mMenuView);
357 }
Adam Powellf203e0a2012-03-06 17:40:12 -0800358 mMenuView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
Adam Powell9b4bee02011-04-27 19:24:47 -0700359 } else {
360 addView(mMenuView);
Adam Powellf203e0a2012-03-06 17:40:12 -0800361 mMenuView.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
Adam Powell9b4bee02011-04-27 19:24:47 -0700362 }
Adam Powellf203e0a2012-03-06 17:40:12 -0800363 mMenuView.requestLayout();
Adam Powell9b4bee02011-04-27 19:24:47 -0700364 }
Adam Powella05aba92011-09-23 14:22:49 -0700365 if (mSplitView != null) {
366 mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE);
367 }
Adam Powellf203e0a2012-03-06 17:40:12 -0800368
369 if (mActionMenuPresenter != null) {
370 if (!splitActionBar) {
371 mActionMenuPresenter.setExpandedActionViewsExclusive(
372 getResources().getBoolean(
373 com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
374 } else {
375 mActionMenuPresenter.setExpandedActionViewsExclusive(false);
376 // Allow full screen width in split mode.
377 mActionMenuPresenter.setWidthLimit(
378 getContext().getResources().getDisplayMetrics().widthPixels, true);
379 // No limit to the item count; use whatever will fit.
380 mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
381 }
382 }
Adam Powella05aba92011-09-23 14:22:49 -0700383 super.setSplitActionBar(splitActionBar);
Adam Powell9b4bee02011-04-27 19:24:47 -0700384 }
385 }
386
387 public boolean isSplitActionBar() {
388 return mSplitActionBar;
389 }
390
Adam Powelldae78242011-04-25 15:23:41 -0700391 public boolean hasEmbeddedTabs() {
392 return mIncludeTabs;
393 }
394
Adam Powellf8ac6b72011-05-23 18:14:09 -0700395 public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
Adam Powelle0adac02011-06-14 13:46:30 -0700396 if (mTabScrollView != null) {
397 removeView(mTabScrollView);
398 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700399 mTabScrollView = tabs;
400 mIncludeTabs = tabs != null;
Adam Powellc3076422011-06-01 18:19:04 -0700401 if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
Adam Powell39a8dc42011-05-27 18:44:00 -0700402 addView(mTabScrollView);
Adam Powellf5645cb2011-08-10 22:49:02 -0700403 ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
404 lp.width = LayoutParams.WRAP_CONTENT;
405 lp.height = LayoutParams.MATCH_PARENT;
406 tabs.setAllowCollapse(true);
Adam Powell39a8dc42011-05-27 18:44:00 -0700407 }
Adam Powelldae78242011-04-25 15:23:41 -0700408 }
409
Adam Powell8515ee82010-11-30 14:09:55 -0800410 public void setCallback(OnNavigationListener callback) {
Adam Powell96675b12010-06-10 18:58:59 -0700411 mCallback = callback;
Adam Powell33b97432010-04-20 10:01:14 -0700412 }
Adam Powella7db0372010-06-30 17:08:47 -0700413
Adam Powell8c16aa92013-04-04 10:47:52 -0700414 public void setMenuPrepared() {
415 mMenuPrepared = true;
416 }
417
Adam Powell696cba52011-03-29 10:38:16 -0700418 public void setMenu(Menu menu, MenuPresenter.Callback cb) {
Adam Powellf2d7a5d2011-02-07 18:05:24 -0800419 if (menu == mOptionsMenu) return;
420
Adam Powell696cba52011-03-29 10:38:16 -0700421 if (mOptionsMenu != null) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700422 mOptionsMenu.removeMenuPresenter(mActionMenuPresenter);
423 mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter);
Adam Powell696cba52011-03-29 10:38:16 -0700424 }
425
Adam Powell96675b12010-06-10 18:58:59 -0700426 MenuBuilder builder = (MenuBuilder) menu;
427 mOptionsMenu = builder;
428 if (mMenuView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700429 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
430 if (oldParent != null) {
431 oldParent.removeView(mMenuView);
432 }
Adam Powell33b97432010-04-20 10:01:14 -0700433 }
Adam Powell8d02dea2011-05-31 21:35:13 -0700434 if (mActionMenuPresenter == null) {
Adam Powell538e5652011-10-11 13:47:08 -0700435 mActionMenuPresenter = new ActionMenuPresenter(mContext);
Adam Powell8d02dea2011-05-31 21:35:13 -0700436 mActionMenuPresenter.setCallback(cb);
Adam Powell11ed1d62011-07-11 21:19:59 -0700437 mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
Adam Powell8d02dea2011-05-31 21:35:13 -0700438 mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
Adam Powell696cba52011-03-29 10:38:16 -0700439 }
Adam Powell35265562011-05-27 15:29:41 -0700440
Adam Powell1ab418a2011-06-09 20:49:49 -0700441 ActionMenuView menuView;
Adam Powell96675b12010-06-10 18:58:59 -0700442 final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
443 LayoutParams.MATCH_PARENT);
Adam Powell9b4bee02011-04-27 19:24:47 -0700444 if (!mSplitActionBar) {
Adam Powellb187cd92011-07-20 14:17:56 -0700445 mActionMenuPresenter.setExpandedActionViewsExclusive(
446 getResources().getBoolean(
447 com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
Adam Powellf35d0492011-08-17 13:56:47 -0700448 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700449 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell894bf542011-07-22 13:39:08 -0700450 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
451 if (oldParent != null && oldParent != this) {
452 oldParent.removeView(menuView);
453 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700454 addView(menuView, layoutParams);
Adam Powell9b4bee02011-04-27 19:24:47 -0700455 } else {
Adam Powellb187cd92011-07-20 14:17:56 -0700456 mActionMenuPresenter.setExpandedActionViewsExclusive(false);
Adam Powell9b4bee02011-04-27 19:24:47 -0700457 // Allow full screen width in split mode.
Adam Powell8d02dea2011-05-31 21:35:13 -0700458 mActionMenuPresenter.setWidthLimit(
Adam Powell640a66e2011-04-29 10:18:53 -0700459 getContext().getResources().getDisplayMetrics().widthPixels, true);
Adam Powell9b4bee02011-04-27 19:24:47 -0700460 // No limit to the item count; use whatever will fit.
Adam Powell8d02dea2011-05-31 21:35:13 -0700461 mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
Adam Powell640a66e2011-04-29 10:18:53 -0700462 // Span the whole width
463 layoutParams.width = LayoutParams.MATCH_PARENT;
Adam Powellf35d0492011-08-17 13:56:47 -0700464 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700465 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell9b4bee02011-04-27 19:24:47 -0700466 if (mSplitView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700467 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
468 if (oldParent != null && oldParent != mSplitView) {
469 oldParent.removeView(menuView);
470 }
Adam Powell9a5cc282011-08-28 16:18:16 -0700471 menuView.setVisibility(getAnimatedVisibility());
Adam Powell1ab418a2011-06-09 20:49:49 -0700472 mSplitView.addView(menuView, layoutParams);
473 } else {
474 // We'll add this later if we missed it this time.
475 menuView.setLayoutParams(layoutParams);
476 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700477 }
Adam Powell96675b12010-06-10 18:58:59 -0700478 mMenuView = menuView;
Adam Powell33b97432010-04-20 10:01:14 -0700479 }
Adam Powella7db0372010-06-30 17:08:47 -0700480
Adam Powellf35d0492011-08-17 13:56:47 -0700481 private void configPresenters(MenuBuilder builder) {
482 if (builder != null) {
483 builder.addMenuPresenter(mActionMenuPresenter);
484 builder.addMenuPresenter(mExpandedMenuPresenter);
485 } else {
486 mActionMenuPresenter.initForMenu(mContext, null);
487 mExpandedMenuPresenter.initForMenu(mContext, null);
488 mActionMenuPresenter.updateMenuView(true);
489 mExpandedMenuPresenter.updateMenuView(true);
490 }
491 }
492
Adam Powellb80d3322011-07-15 21:33:11 -0700493 public boolean hasExpandedActionView() {
494 return mExpandedMenuPresenter != null &&
495 mExpandedMenuPresenter.mCurrentExpandedItem != null;
496 }
497
498 public void collapseActionView() {
499 final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
500 mExpandedMenuPresenter.mCurrentExpandedItem;
501 if (item != null) {
502 item.collapseActionView();
503 }
504 }
505
Adam Powell33b97432010-04-20 10:01:14 -0700506 public void setCustomNavigationView(View view) {
Adam Powell9ab97872010-10-26 21:47:29 -0700507 final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
508 if (mCustomNavView != null && showCustom) {
509 removeView(mCustomNavView);
510 }
Adam Powella4082912010-06-04 18:34:02 -0700511 mCustomNavView = view;
Adam Powell9ab97872010-10-26 21:47:29 -0700512 if (mCustomNavView != null && showCustom) {
513 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700514 }
Adam Powell33b97432010-04-20 10:01:14 -0700515 }
Adam Powella7db0372010-06-30 17:08:47 -0700516
Adam Powell33b97432010-04-20 10:01:14 -0700517 public CharSequence getTitle() {
518 return mTitle;
519 }
Adam Powella7db0372010-06-30 17:08:47 -0700520
Adam Powelle92ea342010-07-14 14:45:50 -0700521 /**
522 * Set the action bar title. This will always replace or override window titles.
523 * @param title Title to set
524 *
525 * @see #setWindowTitle(CharSequence)
526 */
Adam Powell33b97432010-04-20 10:01:14 -0700527 public void setTitle(CharSequence title) {
Adam Powelle92ea342010-07-14 14:45:50 -0700528 mUserTitle = true;
529 setTitleImpl(title);
530 }
531
532 /**
533 * Set the window title. A window title will always be replaced or overridden by a user title.
534 * @param title Title to set
535 *
536 * @see #setTitle(CharSequence)
537 */
538 public void setWindowTitle(CharSequence title) {
539 if (!mUserTitle) {
540 setTitleImpl(title);
541 }
542 }
543
544 private void setTitleImpl(CharSequence title) {
Adam Powell33b97432010-04-20 10:01:14 -0700545 mTitle = title;
546 if (mTitleView != null) {
547 mTitleView.setText(title);
Adam Powellb0e217e2011-08-12 11:36:51 -0700548 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700549 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700550 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
551 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700552 }
553 if (mLogoNavItem != null) {
554 mLogoNavItem.setTitle(title);
555 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700556 mUpGoerFive.setContentDescription(buildHomeContentDescription());
Adam Powell33b97432010-04-20 10:01:14 -0700557 }
Adam Powella7db0372010-06-30 17:08:47 -0700558
Adam Powell33b97432010-04-20 10:01:14 -0700559 public CharSequence getSubtitle() {
560 return mSubtitle;
561 }
Adam Powella7db0372010-06-30 17:08:47 -0700562
Adam Powell33b97432010-04-20 10:01:14 -0700563 public void setSubtitle(CharSequence subtitle) {
564 mSubtitle = subtitle;
565 if (mSubtitleView != null) {
566 mSubtitleView.setText(subtitle);
Adam Powell04587962010-11-11 22:15:07 -0800567 mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE);
Adam Powellb0e217e2011-08-12 11:36:51 -0700568 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700569 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700570 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
571 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700572 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700573 mUpGoerFive.setContentDescription(buildHomeContentDescription());
Adam Powell33b97432010-04-20 10:01:14 -0700574 }
Adam Powella7db0372010-06-30 17:08:47 -0700575
Adam Powellc29f4e52011-07-13 20:40:52 -0700576 public void setHomeButtonEnabled(boolean enable) {
Adam Powell07cf9712013-02-05 16:13:57 -0800577 setHomeButtonEnabled(enable, true);
578 }
579
580 private void setHomeButtonEnabled(boolean enable, boolean recordState) {
581 if (recordState) {
582 mWasHomeEnabled = enable;
583 }
584
585 if (mExpandedActionView != null) {
586 // There's an action view currently showing and we want to keep the state
587 // configured for the action view at the moment. If we needed to record the
588 // new state for later we will have done so above.
589 return;
590 }
591
Adam Powell27cba382013-01-22 18:55:20 -0800592 mUpGoerFive.setEnabled(enable);
593 mUpGoerFive.setFocusable(enable);
Adam Powellc29f4e52011-07-13 20:40:52 -0700594 // Make sure the home button has an accurate content description for accessibility.
595 if (!enable) {
Adam Powell27cba382013-01-22 18:55:20 -0800596 mUpGoerFive.setContentDescription(null);
597 mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
Adam Powellc29f4e52011-07-13 20:40:52 -0700598 } else {
Adam Powell27cba382013-01-22 18:55:20 -0800599 mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700600 mUpGoerFive.setContentDescription(buildHomeContentDescription());
601 }
602 }
603
604 /**
605 * Compose a content description for the Home/Up affordance.
606 *
607 * <p>As this encompasses the icon/logo, title and subtitle all in one, we need
608 * a description for the whole wad of stuff that can be localized properly.</p>
609 */
610 private CharSequence buildHomeContentDescription() {
611 final CharSequence homeDesc;
612 if (mHomeDescription != null) {
613 homeDesc = mHomeDescription;
614 } else {
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700615 if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700616 homeDesc = mContext.getResources().getText(R.string.action_bar_up_description);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700617 } else {
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700618 homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700619 }
Adam Powellc29f4e52011-07-13 20:40:52 -0700620 }
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700621
622 final CharSequence title = getTitle();
623 final CharSequence subtitle = getSubtitle();
624 if (!TextUtils.isEmpty(title)) {
625 final String result;
626 if (!TextUtils.isEmpty(subtitle)) {
627 result = getResources().getString(
628 R.string.action_bar_home_subtitle_description_format,
629 title, subtitle, homeDesc);
630 } else {
631 result = getResources().getString(R.string.action_bar_home_description_format,
632 title, homeDesc);
633 }
634 return result;
635 }
636 return homeDesc;
Adam Powellc29f4e52011-07-13 20:40:52 -0700637 }
638
Adam Powell33b97432010-04-20 10:01:14 -0700639 public void setDisplayOptions(int options) {
Adam Powell82f24e82011-08-18 20:15:20 -0700640 final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions;
Adam Powell33b97432010-04-20 10:01:14 -0700641 mDisplayOptions = options;
Adam Powelldae78242011-04-25 15:23:41 -0700642
Adam Powell33b97432010-04-20 10:01:14 -0700643 if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
Adam Powell54c7d7e2011-06-17 20:30:13 -0700644 final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
Adam Powella8743f12011-11-11 18:35:53 -0800645 final int vis = showHome && mExpandedActionView == null ? VISIBLE : GONE;
Adam Powell9ab97872010-10-26 21:47:29 -0700646 mHomeLayout.setVisibility(vis);
647
648 if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powellc29f4e52011-07-13 20:40:52 -0700649 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
650 mHomeLayout.setUp(setUp);
651
652 // Showing home as up implicitly enables interaction with it.
653 // In honeycomb it was always enabled, so make this transition
654 // a bit easier for developers in the common case.
655 // (It would be silly to show it as up without responding to it.)
656 if (setUp) {
657 setHomeButtonEnabled(true);
658 }
Adam Powella1700782010-05-13 13:27:35 -0700659 }
Adam Powell9ab97872010-10-26 21:47:29 -0700660
Ed Heyl1c603002010-11-18 12:18:23 -0800661 if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
662 final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0;
Adam Powell8d02dea2011-05-31 21:35:13 -0700663 mHomeLayout.setIcon(logoVis ? mLogo : mIcon);
Adam Powell9ab97872010-10-26 21:47:29 -0700664 }
665
666 if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
667 if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
668 initTitle();
669 } else {
Adam Powell27cba382013-01-22 18:55:20 -0800670 mUpGoerFive.removeView(mTitleLayout);
Adam Powell9ab97872010-10-26 21:47:29 -0700671 }
672 }
673
Adam Powell15a16a82011-06-20 10:35:27 -0700674 if (mTitleLayout != null && (flagsChanged &
Adam Powell54c7d7e2011-06-17 20:30:13 -0700675 (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) {
Adam Powellb1e2f252011-08-22 17:42:12 -0700676 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
677 mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700678 }
679
Adam Powell9ab97872010-10-26 21:47:29 -0700680 if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
681 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
682 addView(mCustomNavView);
683 } else {
684 removeView(mCustomNavView);
685 }
Adam Powella1700782010-05-13 13:27:35 -0700686 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700687
Adam Powell27cba382013-01-22 18:55:20 -0800688 if (mTitleLayout != null &&
689 (flagsChanged & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
690 if ((options & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
691 mTitleView.setSingleLine(false);
692 mTitleView.setMaxLines(2);
693 } else {
694 mTitleView.setMaxLines(1);
695 mTitleView.setSingleLine(true);
696 }
697 }
698
Adam Powell33b97432010-04-20 10:01:14 -0700699 requestLayout();
700 } else {
701 invalidate();
702 }
Adam Powellf3cd1d92011-04-26 17:31:52 -0700703
704 // Make sure the home button has an accurate content description for accessibility.
Adam Powellc29f4e52011-07-13 20:40:52 -0700705 if (!mHomeLayout.isEnabled()) {
Adam Powellf3cd1d92011-04-26 17:31:52 -0700706 mHomeLayout.setContentDescription(null);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700707 mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
Adam Powellf3cd1d92011-04-26 17:31:52 -0700708 } else {
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700709 mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
710 if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
711 mHomeLayout.setContentDescription(mContext.getResources().getText(
712 R.string.action_bar_up_description));
713 } else {
714 mHomeLayout.setContentDescription(mContext.getResources().getText(
715 R.string.action_bar_home_description));
716 }
Adam Powellf3cd1d92011-04-26 17:31:52 -0700717 }
Adam Powell33b97432010-04-20 10:01:14 -0700718 }
719
Adam Powell1969b872011-03-22 11:52:48 -0700720 public void setIcon(Drawable icon) {
721 mIcon = icon;
722 if (icon != null &&
723 ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700724 mHomeLayout.setIcon(icon);
Adam Powell1969b872011-03-22 11:52:48 -0700725 }
Adam Powellf8218192012-02-21 17:10:10 -0800726 if (mExpandedActionView != null) {
727 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
728 }
Adam Powell1969b872011-03-22 11:52:48 -0700729 }
730
Adam Powell45c515b2011-04-21 18:50:20 -0700731 public void setIcon(int resId) {
Adam Powellf2b09612011-08-12 14:18:04 -0700732 setIcon(mContext.getResources().getDrawable(resId));
Adam Powell45c515b2011-04-21 18:50:20 -0700733 }
734
Adam Powell1969b872011-03-22 11:52:48 -0700735 public void setLogo(Drawable logo) {
736 mLogo = logo;
737 if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700738 mHomeLayout.setIcon(logo);
Adam Powell1969b872011-03-22 11:52:48 -0700739 }
740 }
741
Adam Powell45c515b2011-04-21 18:50:20 -0700742 public void setLogo(int resId) {
Adam Powell29764ea2011-08-04 13:12:01 -0700743 setLogo(mContext.getResources().getDrawable(resId));
Adam Powell45c515b2011-04-21 18:50:20 -0700744 }
745
Adam Powell33b97432010-04-20 10:01:14 -0700746 public void setNavigationMode(int mode) {
Adam Powella1700782010-05-13 13:27:35 -0700747 final int oldMode = mNavigationMode;
748 if (mode != oldMode) {
749 switch (oldMode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700750 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powellc3076422011-06-01 18:19:04 -0700751 if (mListNavLayout != null) {
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800752 removeView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700753 }
754 break;
Adam Powell661c9082010-07-02 10:09:44 -0700755 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700756 if (mTabScrollView != null && mIncludeTabs) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700757 removeView(mTabScrollView);
Adam Powell661c9082010-07-02 10:09:44 -0700758 }
Adam Powella1700782010-05-13 13:27:35 -0700759 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700760
Adam Powella1700782010-05-13 13:27:35 -0700761 switch (mode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700762 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800763 if (mSpinner == null) {
764 mSpinner = new Spinner(mContext, null,
765 com.android.internal.R.attr.actionDropDownStyle);
Adam Powell29c04ef2012-12-10 15:42:22 -0800766 mSpinner.setId(com.android.internal.R.id.action_bar_spinner);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800767 mListNavLayout = new LinearLayout(mContext, null,
768 com.android.internal.R.attr.actionBarTabBarStyle);
769 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
Adam Powelle7d46842011-01-13 21:36:09 -0800770 LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800771 params.gravity = Gravity.CENTER;
772 mListNavLayout.addView(mSpinner, params);
773 }
774 if (mSpinner.getAdapter() != mSpinnerAdapter) {
775 mSpinner.setAdapter(mSpinnerAdapter);
776 }
Adam Powella4082912010-06-04 18:34:02 -0700777 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800778 addView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700779 break;
Adam Powell661c9082010-07-02 10:09:44 -0700780 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700781 if (mTabScrollView != null && mIncludeTabs) {
Adam Powelldae78242011-04-25 15:23:41 -0700782 addView(mTabScrollView);
783 }
Adam Powell661c9082010-07-02 10:09:44 -0700784 break;
Adam Powella1700782010-05-13 13:27:35 -0700785 }
Adam Powell33b97432010-04-20 10:01:14 -0700786 mNavigationMode = mode;
787 requestLayout();
788 }
789 }
Adam Powelldae78242011-04-25 15:23:41 -0700790
Adam Powella4082912010-06-04 18:34:02 -0700791 public void setDropdownAdapter(SpinnerAdapter adapter) {
Adam Powell9ab97872010-10-26 21:47:29 -0700792 mSpinnerAdapter = adapter;
793 if (mSpinner != null) {
794 mSpinner.setAdapter(adapter);
795 }
796 }
797
798 public SpinnerAdapter getDropdownAdapter() {
799 return mSpinnerAdapter;
Adam Powella4082912010-06-04 18:34:02 -0700800 }
Adam Powell17809772010-07-21 13:25:11 -0700801
802 public void setDropdownSelectedPosition(int position) {
803 mSpinner.setSelection(position);
804 }
805
806 public int getDropdownSelectedPosition() {
807 return mSpinner.getSelectedItemPosition();
808 }
809
Adam Powell33b97432010-04-20 10:01:14 -0700810 public View getCustomNavigationView() {
Adam Powella4082912010-06-04 18:34:02 -0700811 return mCustomNavView;
Adam Powell33b97432010-04-20 10:01:14 -0700812 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700813
Adam Powell33b97432010-04-20 10:01:14 -0700814 public int getNavigationMode() {
815 return mNavigationMode;
816 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700817
Adam Powell33b97432010-04-20 10:01:14 -0700818 public int getDisplayOptions() {
819 return mDisplayOptions;
820 }
Adam Powella7db0372010-06-30 17:08:47 -0700821
822 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -0700823 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
Adam Powella7db0372010-06-30 17:08:47 -0700824 // Used by custom nav views if they don't supply layout params. Everything else
825 // added to an ActionBarView should have them already.
Adam Powell9ab97872010-10-26 21:47:29 -0700826 return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY);
Adam Powella7db0372010-06-30 17:08:47 -0700827 }
828
Adam Powell33b97432010-04-20 10:01:14 -0700829 @Override
830 protected void onFinishInflate() {
831 super.onFinishInflate();
832
Adam Powell27cba382013-01-22 18:55:20 -0800833 mUpGoerFive.addView(mHomeLayout, 0);
834 addView(mUpGoerFive);
Adam Powell9ab97872010-10-26 21:47:29 -0700835
Adam Powell9ab97872010-10-26 21:47:29 -0700836 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
837 final ViewParent parent = mCustomNavView.getParent();
838 if (parent != this) {
839 if (parent instanceof ViewGroup) {
840 ((ViewGroup) parent).removeView(mCustomNavView);
841 }
Adam Powella4082912010-06-04 18:34:02 -0700842 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700843 }
Adam Powell33b97432010-04-20 10:01:14 -0700844 }
845 }
Adam Powellc8b0b002011-06-23 14:39:05 -0700846
Adam Powella1700782010-05-13 13:27:35 -0700847 private void initTitle() {
Adam Powell15a16a82011-06-20 10:35:27 -0700848 if (mTitleLayout == null) {
849 LayoutInflater inflater = LayoutInflater.from(getContext());
Adam Powell9e58df52011-08-15 17:06:49 -0700850 mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item,
851 this, false);
Adam Powell15a16a82011-06-20 10:35:27 -0700852 mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
853 mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
854 mTitleUpView = (View) mTitleLayout.findViewById(R.id.up);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700855
Adam Powell15a16a82011-06-20 10:35:27 -0700856 if (mTitleStyleRes != 0) {
857 mTitleView.setTextAppearance(mContext, mTitleStyleRes);
858 }
859 if (mTitle != null) {
860 mTitleView.setText(mTitle);
861 }
Adam Powelle2194442010-08-12 18:13:03 -0700862
Adam Powell15a16a82011-06-20 10:35:27 -0700863 if (mSubtitleStyleRes != 0) {
864 mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
865 }
866 if (mSubtitle != null) {
867 mSubtitleView.setText(mSubtitle);
868 mSubtitleView.setVisibility(VISIBLE);
869 }
870
871 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
Adam Powellb1e2f252011-08-22 17:42:12 -0700872 final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0;
Adam Powell6231ab82012-06-22 14:08:11 -0700873 final boolean showTitleUp = !showHome;
874 mTitleUpView.setVisibility(showTitleUp ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
Adam Powell0e94b512010-06-29 17:58:20 -0700875 }
Adam Powelle2194442010-08-12 18:13:03 -0700876
Adam Powell27cba382013-01-22 18:55:20 -0800877 mUpGoerFive.addView(mTitleLayout);
Adam Powell82f24e82011-08-18 20:15:20 -0700878 if (mExpandedActionView != null ||
879 (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
880 // Don't show while in expanded mode or with empty text
Adam Powell71f34172011-08-11 20:07:11 -0700881 mTitleLayout.setVisibility(GONE);
Adam Powell6684e922013-03-26 15:38:26 -0700882 } else {
883 mTitleLayout.setVisibility(VISIBLE);
Adam Powell71f34172011-08-11 20:07:11 -0700884 }
Adam Powella1700782010-05-13 13:27:35 -0700885 }
Adam Powell33b97432010-04-20 10:01:14 -0700886
Adam Powelle2194442010-08-12 18:13:03 -0700887 public void setContextView(ActionBarContextView view) {
888 mContextView = view;
889 }
890
Adam Powelld21aa122011-05-27 13:09:52 -0700891 public void setCollapsable(boolean collapsable) {
892 mIsCollapsable = collapsable;
893 }
894
Adam Powellf6ce6a92011-06-29 10:25:01 -0700895 public boolean isCollapsed() {
896 return mIsCollapsed;
897 }
898
Adam Powell27cba382013-01-22 18:55:20 -0800899 /**
900 * @return True if any characters in the title were truncated
901 */
902 public boolean isTitleTruncated() {
903 if (mTitleView == null) {
904 return false;
905 }
906
907 final Layout titleLayout = mTitleView.getLayout();
908 if (titleLayout == null) {
909 return false;
910 }
911
912 final int lineCount = titleLayout.getLineCount();
913 for (int i = 0; i < lineCount; i++) {
914 if (titleLayout.getEllipsisCount(i) > 0) {
915 return true;
916 }
917 }
918 return false;
919 }
920
Adam Powell33b97432010-04-20 10:01:14 -0700921 @Override
922 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Adam Powelld21aa122011-05-27 13:09:52 -0700923 final int childCount = getChildCount();
924 if (mIsCollapsable) {
925 int visibleChildren = 0;
926 for (int i = 0; i < childCount; i++) {
927 final View child = getChildAt(i);
928 if (child.getVisibility() != GONE &&
Adam Powell27cba382013-01-22 18:55:20 -0800929 !(child == mMenuView && mMenuView.getChildCount() == 0) &&
930 child != mUpGoerFive) {
931 visibleChildren++;
932 }
933 }
934
935 final int upChildCount = mUpGoerFive.getChildCount();
936 for (int i = 0; i < upChildCount; i++) {
937 final View child = mUpGoerFive.getChildAt(i);
938 if (child.getVisibility() != GONE) {
Adam Powelld21aa122011-05-27 13:09:52 -0700939 visibleChildren++;
940 }
941 }
942
943 if (visibleChildren == 0) {
944 // No size for an empty action bar when collapsable.
945 setMeasuredDimension(0, 0);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700946 mIsCollapsed = true;
Adam Powelld21aa122011-05-27 13:09:52 -0700947 return;
948 }
949 }
Adam Powellf6ce6a92011-06-29 10:25:01 -0700950 mIsCollapsed = false;
Adam Powelld21aa122011-05-27 13:09:52 -0700951
Adam Powell33b97432010-04-20 10:01:14 -0700952 int widthMode = MeasureSpec.getMode(widthMeasureSpec);
953 if (widthMode != MeasureSpec.EXACTLY) {
954 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
955 "with android:layout_width=\"match_parent\" (or fill_parent)");
956 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700957
Adam Powell33b97432010-04-20 10:01:14 -0700958 int heightMode = MeasureSpec.getMode(heightMeasureSpec);
959 if (heightMode != MeasureSpec.AT_MOST) {
960 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
961 "with android:layout_height=\"wrap_content\"");
962 }
963
964 int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
Adam Powelle2194442010-08-12 18:13:03 -0700965
Adam Powell570470a2012-08-06 17:00:17 -0700966 int maxHeight = mContentHeight >= 0 ?
Adam Powelle2194442010-08-12 18:13:03 -0700967 mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700968
Adam Powelle2194442010-08-12 18:13:03 -0700969 final int verticalPadding = getPaddingTop() + getPaddingBottom();
Adam Powell9ab97872010-10-26 21:47:29 -0700970 final int paddingLeft = getPaddingLeft();
971 final int paddingRight = getPaddingRight();
Adam Powelle2194442010-08-12 18:13:03 -0700972 final int height = maxHeight - verticalPadding;
Adam Powella1700782010-05-13 13:27:35 -0700973 final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
Adam Powell6322af52012-08-08 15:59:12 -0700974 final int exactHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
Adam Powell33b97432010-04-20 10:01:14 -0700975
Adam Powell9ab97872010-10-26 21:47:29 -0700976 int availableWidth = contentWidth - paddingLeft - paddingRight;
977 int leftOfCenter = availableWidth / 2;
978 int rightOfCenter = leftOfCenter;
979
Adam Powellb1e2f252011-08-22 17:42:12 -0700980 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powell8d02dea2011-05-31 21:35:13 -0700981
Adam Powell27cba382013-01-22 18:55:20 -0800982 int homeWidth = 0;
983 if (homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive) {
Adam Powell9a5cc282011-08-28 16:18:16 -0700984 final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams();
Adam Powell0d5d1b7e2011-06-22 17:40:40 -0700985 int homeWidthSpec;
986 if (lp.width < 0) {
987 homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
988 } else {
989 homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
990 }
Adam Powell27cba382013-01-22 18:55:20 -0800991
992 /*
993 * This is a little weird.
994 * We're only measuring the *home* affordance within the Up container here
995 * on purpose, because we want to give the available space to all other views before
996 * the title text. We'll remeasure the whole up container again later.
997 */
Adam Powell6322af52012-08-08 15:59:12 -0700998 homeLayout.measure(homeWidthSpec, exactHeightSpec);
Adam Powell27cba382013-01-22 18:55:20 -0800999 homeWidth = homeLayout.getMeasuredWidth();
1000 final int homeOffsetWidth = homeWidth + homeLayout.getStartOffset();
1001 availableWidth = Math.max(0, availableWidth - homeOffsetWidth);
1002 leftOfCenter = Math.max(0, availableWidth - homeOffsetWidth);
Adam Powell33b97432010-04-20 10:01:14 -07001003 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -07001004
Adam Powell9b4bee02011-04-27 19:24:47 -07001005 if (mMenuView != null && mMenuView.getParent() == this) {
Adam Powell6322af52012-08-08 15:59:12 -07001006 availableWidth = measureChildView(mMenuView, availableWidth, exactHeightSpec, 0);
Adam Powell1b4a1622011-05-17 12:13:13 -07001007 rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
Adam Powell33b97432010-04-20 10:01:14 -07001008 }
Adam Powell9ab97872010-10-26 21:47:29 -07001009
Adam Powellaa8e509b2011-08-25 09:29:21 -07001010 if (mIndeterminateProgressView != null &&
1011 mIndeterminateProgressView.getVisibility() != GONE) {
1012 availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
1013 childSpecHeight, 0);
1014 rightOfCenter = Math.max(0,
1015 rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
1016 }
Adam Powell9ab97872010-10-26 21:47:29 -07001017
Adam Powellaa8e509b2011-08-25 09:29:21 -07001018 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
1019 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
1020
1021 if (mExpandedActionView == null) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001022 switch (mNavigationMode) {
1023 case ActionBar.NAVIGATION_MODE_LIST:
1024 if (mListNavLayout != null) {
1025 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
1026 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
1027 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
1028 mListNavLayout.measure(
1029 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
1030 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1031 final int listNavWidth = mListNavLayout.getMeasuredWidth();
1032 availableWidth = Math.max(0, availableWidth - listNavWidth);
1033 leftOfCenter = Math.max(0, leftOfCenter - listNavWidth);
1034 }
1035 break;
1036 case ActionBar.NAVIGATION_MODE_TABS:
1037 if (mTabScrollView != null) {
1038 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
1039 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
1040 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
1041 mTabScrollView.measure(
1042 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
1043 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1044 final int tabWidth = mTabScrollView.getMeasuredWidth();
1045 availableWidth = Math.max(0, availableWidth - tabWidth);
1046 leftOfCenter = Math.max(0, leftOfCenter - tabWidth);
1047 }
1048 break;
Adam Powell33b97432010-04-20 10:01:14 -07001049 }
Adam Powell33b97432010-04-20 10:01:14 -07001050 }
1051
Adam Powell8d02dea2011-05-31 21:35:13 -07001052 View customView = null;
1053 if (mExpandedActionView != null) {
1054 customView = mExpandedActionView;
1055 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1056 mCustomNavView != null) {
1057 customView = mCustomNavView;
1058 }
1059
1060 if (customView != null) {
Adam Powell9a5cc282011-08-28 16:18:16 -07001061 final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams());
Adam Powell9ab97872010-10-26 21:47:29 -07001062 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1063 (ActionBar.LayoutParams) lp : null;
1064
1065 int horizontalMargin = 0;
1066 int verticalMargin = 0;
1067 if (ablp != null) {
1068 horizontalMargin = ablp.leftMargin + ablp.rightMargin;
1069 verticalMargin = ablp.topMargin + ablp.bottomMargin;
1070 }
1071
1072 // If the action bar is wrapping to its content height, don't allow a custom
1073 // view to MATCH_PARENT.
1074 int customNavHeightMode;
1075 if (mContentHeight <= 0) {
1076 customNavHeightMode = MeasureSpec.AT_MOST;
1077 } else {
1078 customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
1079 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
1080 }
1081 final int customNavHeight = Math.max(0,
1082 (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin);
1083
1084 final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
1085 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
1086 int customNavWidth = Math.max(0,
1087 (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth)
1088 - horizontalMargin);
1089 final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) &
1090 Gravity.HORIZONTAL_GRAVITY_MASK;
1091
1092 // Centering a custom view is treated specially; we try to center within the whole
1093 // action bar rather than in the available space.
1094 if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) {
1095 customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2;
1096 }
1097
Adam Powell8d02dea2011-05-31 21:35:13 -07001098 customView.measure(
Adam Powell9ab97872010-10-26 21:47:29 -07001099 MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
1100 MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
Adam Powellaa8e509b2011-08-25 09:29:21 -07001101 availableWidth -= horizontalMargin + customView.getMeasuredWidth();
1102 }
1103
Adam Powell27cba382013-01-22 18:55:20 -08001104 /*
1105 * Measure the whole up container now, allowing for the full home+title sections.
1106 * (This will re-measure the home view.)
1107 */
1108 availableWidth = measureChildView(mUpGoerFive, availableWidth + homeWidth,
1109 MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
1110 if (mTitleLayout != null) {
Adam Powellaa8e509b2011-08-25 09:29:21 -07001111 leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
Adam Powell9ab97872010-10-26 21:47:29 -07001112 }
1113
Adam Powelle2194442010-08-12 18:13:03 -07001114 if (mContentHeight <= 0) {
1115 int measuredHeight = 0;
Adam Powelld21aa122011-05-27 13:09:52 -07001116 for (int i = 0; i < childCount; i++) {
Adam Powelle2194442010-08-12 18:13:03 -07001117 View v = getChildAt(i);
1118 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
1119 if (paddedViewHeight > measuredHeight) {
1120 measuredHeight = paddedViewHeight;
1121 }
1122 }
1123 setMeasuredDimension(contentWidth, measuredHeight);
1124 } else {
1125 setMeasuredDimension(contentWidth, maxHeight);
1126 }
1127
1128 if (mContextView != null) {
Adam Powell425689e2011-09-08 18:09:33 -07001129 mContextView.setContentHeight(getMeasuredHeight());
Adam Powelle2194442010-08-12 18:13:03 -07001130 }
Adam Powell6af97e12010-11-11 21:11:53 -08001131
1132 if (mProgressView != null && mProgressView.getVisibility() != GONE) {
1133 mProgressView.measure(MeasureSpec.makeMeasureSpec(
1134 contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY),
1135 MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
1136 }
Adam Powell33b97432010-04-20 10:01:14 -07001137 }
1138
Adam Powell33b97432010-04-20 10:01:14 -07001139 @Override
1140 protected void onLayout(boolean changed, int l, int t, int r, int b) {
Adam Powell33b97432010-04-20 10:01:14 -07001141 final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
1142
Adam Powelld21aa122011-05-27 13:09:52 -07001143 if (contentHeight <= 0) {
1144 // Nothing to do if we can't see anything.
1145 return;
1146 }
1147
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001148 final boolean isLayoutRtl = isLayoutRtl();
1149 final int direction = isLayoutRtl ? +1 : -1;
1150 int menuStart = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
1151 // In LTR mode, we start from left padding and go to the right; in RTL mode, we start
1152 // from the padding right and go to the left (in reverse way)
1153 int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
1154 final int y = getPaddingTop();
1155
Adam Powellb1e2f252011-08-22 17:42:12 -07001156 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powell27cba382013-01-22 18:55:20 -08001157 final int startOffset = homeLayout.getVisibility() != GONE &&
1158 homeLayout.getParent() == mUpGoerFive ? homeLayout.getStartOffset() : 0;
1159
1160 // Position the up container based on where the edge of the home layout should go.
1161 x += positionChild(mUpGoerFive,
1162 next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
1163 x = next(x, startOffset, isLayoutRtl);
Adam Powell9ab97872010-10-26 21:47:29 -07001164
Adam Powell8d02dea2011-05-31 21:35:13 -07001165 if (mExpandedActionView == null) {
1166 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
Adam Powell15a16a82011-06-20 10:35:27 -07001167 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
Adam Powell8d02dea2011-05-31 21:35:13 -07001168
1169 switch (mNavigationMode) {
1170 case ActionBar.NAVIGATION_MODE_STANDARD:
1171 break;
1172 case ActionBar.NAVIGATION_MODE_LIST:
1173 if (mListNavLayout != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001174 if (showTitle) {
1175 x = next(x, mItemPadding, isLayoutRtl);
1176 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001177 x += positionChild(mListNavLayout, x, y, contentHeight, isLayoutRtl);
1178 x = next(x, mItemPadding, isLayoutRtl);
Adam Powell8d02dea2011-05-31 21:35:13 -07001179 }
1180 break;
1181 case ActionBar.NAVIGATION_MODE_TABS:
1182 if (mTabScrollView != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001183 if (showTitle) x = next(x, mItemPadding, isLayoutRtl);
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001184 x += positionChild(mTabScrollView, x, y, contentHeight, isLayoutRtl);
1185 x = next(x, mItemPadding, isLayoutRtl);
Adam Powell8d02dea2011-05-31 21:35:13 -07001186 }
1187 break;
Adam Powell661c9082010-07-02 10:09:44 -07001188 }
Adam Powell33b97432010-04-20 10:01:14 -07001189 }
1190
Adam Powell9b4bee02011-04-27 19:24:47 -07001191 if (mMenuView != null && mMenuView.getParent() == this) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001192 positionChild(mMenuView, menuStart, y, contentHeight, !isLayoutRtl);
1193 menuStart += direction * mMenuView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001194 }
1195
Adam Powell6af97e12010-11-11 21:11:53 -08001196 if (mIndeterminateProgressView != null &&
1197 mIndeterminateProgressView.getVisibility() != GONE) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001198 positionChild(mIndeterminateProgressView, menuStart, y, contentHeight, !isLayoutRtl);
1199 menuStart += direction * mIndeterminateProgressView.getMeasuredWidth();
Adam Powell6af97e12010-11-11 21:11:53 -08001200 }
1201
Adam Powell8d02dea2011-05-31 21:35:13 -07001202 View customView = null;
1203 if (mExpandedActionView != null) {
1204 customView = mExpandedActionView;
1205 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1206 mCustomNavView != null) {
1207 customView = mCustomNavView;
1208 }
1209 if (customView != null) {
Fabrice Di Meglio6bf6eb72012-10-10 15:30:28 -07001210 final int layoutDirection = getLayoutDirection();
Fabrice Di Megliobb4b6012012-10-26 16:27:55 -07001211 ViewGroup.LayoutParams lp = customView.getLayoutParams();
Adam Powell9ab97872010-10-26 21:47:29 -07001212 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1213 (ActionBar.LayoutParams) lp : null;
Adam Powell9ab97872010-10-26 21:47:29 -07001214 final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY;
Adam Powell8d02dea2011-05-31 21:35:13 -07001215 final int navWidth = customView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001216
1217 int topMargin = 0;
1218 int bottomMargin = 0;
1219 if (ablp != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001220 x = next(x, ablp.getMarginStart(), isLayoutRtl);
1221 menuStart += direction * ablp.getMarginEnd();
Adam Powell9ab97872010-10-26 21:47:29 -07001222 topMargin = ablp.topMargin;
1223 bottomMargin = ablp.bottomMargin;
1224 }
1225
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001226 int hgravity = gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
Adam Powell9ab97872010-10-26 21:47:29 -07001227 // See if we actually have room to truly center; if not push against left or right.
1228 if (hgravity == Gravity.CENTER_HORIZONTAL) {
1229 final int centeredLeft = ((mRight - mLeft) - navWidth) / 2;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001230 if (isLayoutRtl) {
1231 final int centeredStart = centeredLeft + navWidth;
1232 final int centeredEnd = centeredLeft;
1233 if (centeredStart > x) {
1234 hgravity = Gravity.RIGHT;
1235 } else if (centeredEnd < menuStart) {
1236 hgravity = Gravity.LEFT;
1237 }
1238 } else {
1239 final int centeredStart = centeredLeft;
1240 final int centeredEnd = centeredLeft + navWidth;
1241 if (centeredStart < x) {
1242 hgravity = Gravity.LEFT;
1243 } else if (centeredEnd > menuStart) {
1244 hgravity = Gravity.RIGHT;
1245 }
Adam Powell9ab97872010-10-26 21:47:29 -07001246 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001247 } else if (gravity == Gravity.NO_GRAVITY) {
1248 hgravity = Gravity.START;
Adam Powell9ab97872010-10-26 21:47:29 -07001249 }
1250
1251 int xpos = 0;
Fabrice Di Meglio6bf6eb72012-10-10 15:30:28 -07001252 switch (Gravity.getAbsoluteGravity(hgravity, layoutDirection)) {
Adam Powell9ab97872010-10-26 21:47:29 -07001253 case Gravity.CENTER_HORIZONTAL:
1254 xpos = ((mRight - mLeft) - navWidth) / 2;
1255 break;
1256 case Gravity.LEFT:
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001257 xpos = isLayoutRtl ? menuStart : x;
Adam Powell9ab97872010-10-26 21:47:29 -07001258 break;
1259 case Gravity.RIGHT:
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001260 xpos = isLayoutRtl ? x - navWidth : menuStart - navWidth;
Adam Powell9ab97872010-10-26 21:47:29 -07001261 break;
1262 }
1263
Adam Powell7a2424d2011-08-18 11:59:11 -07001264 int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
1265
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001266 if (gravity == Gravity.NO_GRAVITY) {
Adam Powell7a2424d2011-08-18 11:59:11 -07001267 vgravity = Gravity.CENTER_VERTICAL;
1268 }
1269
Adam Powell9ab97872010-10-26 21:47:29 -07001270 int ypos = 0;
Adam Powell7a2424d2011-08-18 11:59:11 -07001271 switch (vgravity) {
Adam Powell9ab97872010-10-26 21:47:29 -07001272 case Gravity.CENTER_VERTICAL:
Adam Powell6556c072011-06-24 17:16:57 -07001273 final int paddedTop = getPaddingTop();
1274 final int paddedBottom = mBottom - mTop - getPaddingBottom();
Adam Powell8d02dea2011-05-31 21:35:13 -07001275 ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2;
Adam Powell9ab97872010-10-26 21:47:29 -07001276 break;
1277 case Gravity.TOP:
1278 ypos = getPaddingTop() + topMargin;
1279 break;
1280 case Gravity.BOTTOM:
Adam Powell8d02dea2011-05-31 21:35:13 -07001281 ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight()
Adam Powell9ab97872010-10-26 21:47:29 -07001282 - bottomMargin;
1283 break;
1284 }
Adam Powell6556c072011-06-24 17:16:57 -07001285 final int customWidth = customView.getMeasuredWidth();
1286 customView.layout(xpos, ypos, xpos + customWidth,
1287 ypos + customView.getMeasuredHeight());
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001288 x = next(x, customWidth, isLayoutRtl);
Adam Powell33b97432010-04-20 10:01:14 -07001289 }
Adam Powell6af97e12010-11-11 21:11:53 -08001290
1291 if (mProgressView != null) {
1292 mProgressView.bringToFront();
1293 final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2;
1294 mProgressView.layout(mProgressBarPadding, -halfProgressHeight,
1295 mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight);
1296 }
Adam Powell33b97432010-04-20 10:01:14 -07001297 }
1298
Adam Powell8d02dea2011-05-31 21:35:13 -07001299 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001300 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
Adam Powellaad47fd2011-08-17 17:33:33 -07001301 return new ActionBar.LayoutParams(getContext(), attrs);
1302 }
1303
1304 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001305 public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001306 if (lp == null) {
1307 lp = generateDefaultLayoutParams();
1308 }
1309 return lp;
1310 }
1311
1312 @Override
1313 public Parcelable onSaveInstanceState() {
1314 Parcelable superState = super.onSaveInstanceState();
1315 SavedState state = new SavedState(superState);
1316
1317 if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
1318 state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
1319 }
1320
1321 state.isOverflowOpen = isOverflowMenuShowing();
1322
1323 return state;
1324 }
1325
1326 @Override
1327 public void onRestoreInstanceState(Parcelable p) {
1328 SavedState state = (SavedState) p;
1329
1330 super.onRestoreInstanceState(state.getSuperState());
1331
1332 if (state.expandedMenuItemId != 0 &&
1333 mExpandedMenuPresenter != null && mOptionsMenu != null) {
1334 final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId);
1335 if (item != null) {
1336 item.expandActionView();
1337 }
1338 }
1339
1340 if (state.isOverflowOpen) {
1341 postShowOverflowMenu();
1342 }
1343 }
1344
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001345 public void setHomeAsUpIndicator(Drawable indicator) {
1346 mHomeLayout.setUpIndicator(indicator);
1347 }
1348
1349 public void setHomeAsUpIndicator(int resId) {
1350 mHomeLayout.setUpIndicator(resId);
1351 }
1352
1353 public void setHomeActionContentDescription(CharSequence description) {
1354 mHomeDescription = description;
1355 }
1356
1357 public void setHomeActionContentDescription(int resId) {
1358 mHomeDescriptionRes = resId;
Adam Powell2eeb4192013-04-18 13:53:27 -07001359 mHomeDescription = resId != 0 ? getResources().getText(resId) : null;
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001360 }
1361
Adam Powell8d02dea2011-05-31 21:35:13 -07001362 static class SavedState extends BaseSavedState {
1363 int expandedMenuItemId;
1364 boolean isOverflowOpen;
1365
1366 SavedState(Parcelable superState) {
1367 super(superState);
1368 }
1369
1370 private SavedState(Parcel in) {
1371 super(in);
1372 expandedMenuItemId = in.readInt();
1373 isOverflowOpen = in.readInt() != 0;
1374 }
1375
1376 @Override
1377 public void writeToParcel(Parcel out, int flags) {
1378 super.writeToParcel(out, flags);
1379 out.writeInt(expandedMenuItemId);
1380 out.writeInt(isOverflowOpen ? 1 : 0);
1381 }
1382
1383 public static final Parcelable.Creator<SavedState> CREATOR =
1384 new Parcelable.Creator<SavedState>() {
1385 public SavedState createFromParcel(Parcel in) {
1386 return new SavedState(in);
1387 }
1388
1389 public SavedState[] newArray(int size) {
1390 return new SavedState[size];
1391 }
1392 };
1393 }
1394
Adam Powell2b0952b2011-03-09 00:15:38 -08001395 private static class HomeView extends FrameLayout {
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001396 private ImageView mUpView;
Adam Powell8d02dea2011-05-31 21:35:13 -07001397 private ImageView mIconView;
Adam Powellb1e2f252011-08-22 17:42:12 -07001398 private int mUpWidth;
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001399 private int mUpIndicatorRes;
1400 private Drawable mDefaultUpIndicator;
Adam Powell2b0952b2011-03-09 00:15:38 -08001401
Adam Powellfd75eef2012-08-02 10:27:31 -07001402 private static final long DEFAULT_TRANSITION_DURATION = 150;
1403
Adam Powell2b0952b2011-03-09 00:15:38 -08001404 public HomeView(Context context) {
1405 this(context, null);
1406 }
1407
1408 public HomeView(Context context, AttributeSet attrs) {
1409 super(context, attrs);
Adam Powellfd75eef2012-08-02 10:27:31 -07001410 LayoutTransition t = getLayoutTransition();
1411 if (t != null) {
1412 // Set a lower duration than the default
1413 t.setDuration(DEFAULT_TRANSITION_DURATION);
1414 }
Adam Powell2b0952b2011-03-09 00:15:38 -08001415 }
1416
Adam Powell8d02dea2011-05-31 21:35:13 -07001417 public void setUp(boolean isUp) {
1418 mUpView.setVisibility(isUp ? VISIBLE : GONE);
1419 }
1420
1421 public void setIcon(Drawable icon) {
1422 mIconView.setImageDrawable(icon);
1423 }
1424
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001425 public void setUpIndicator(Drawable d) {
1426 mUpView.setImageDrawable(d != null ? d : mDefaultUpIndicator);
1427 mUpIndicatorRes = 0;
1428 }
1429
1430 public void setUpIndicator(int resId) {
1431 mUpIndicatorRes = resId;
1432 mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
1433 }
1434
1435 @Override
1436 protected void onConfigurationChanged(Configuration newConfig) {
1437 super.onConfigurationChanged(newConfig);
1438 if (mUpIndicatorRes != 0) {
1439 // Reload for config change
1440 setUpIndicator(mUpIndicatorRes);
1441 }
1442 }
1443
Adam Powell2b0952b2011-03-09 00:15:38 -08001444 @Override
Adam Powell7bc3ca02011-08-26 18:29:58 -07001445 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
1446 onPopulateAccessibilityEvent(event);
1447 return true;
1448 }
1449
1450 @Override
1451 public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1452 super.onPopulateAccessibilityEvent(event);
1453 final CharSequence cdesc = getContentDescription();
1454 if (!TextUtils.isEmpty(cdesc)) {
1455 event.getText().add(cdesc);
1456 }
1457 }
1458
1459 @Override
1460 public boolean dispatchHoverEvent(MotionEvent event) {
1461 // Don't allow children to hover; we want this to be treated as a single component.
1462 return onHoverEvent(event);
1463 }
1464
1465 @Override
Adam Powell2b0952b2011-03-09 00:15:38 -08001466 protected void onFinishInflate() {
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001467 mUpView = (ImageView) findViewById(com.android.internal.R.id.up);
Adam Powell2b0952b2011-03-09 00:15:38 -08001468 mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001469 mDefaultUpIndicator = mUpView.getDrawable();
Adam Powell2b0952b2011-03-09 00:15:38 -08001470 }
1471
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001472 public int getStartOffset() {
Adam Powellb1e2f252011-08-22 17:42:12 -07001473 return mUpView.getVisibility() == GONE ? mUpWidth : 0;
Adam Powell8d02dea2011-05-31 21:35:13 -07001474 }
1475
Adam Powell2b0952b2011-03-09 00:15:38 -08001476 @Override
1477 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1478 measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
1479 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
Adam Powellb1e2f252011-08-22 17:42:12 -07001480 mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin;
1481 int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth;
Adam Powell2b0952b2011-03-09 00:15:38 -08001482 int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
1483 measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
1484 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1485 width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
1486 height = Math.max(height,
1487 iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
Adam Powell0d5d1b7e2011-06-22 17:40:40 -07001488
1489 final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
1490 final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
1491 final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
1492 final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
1493
1494 switch (widthMode) {
1495 case MeasureSpec.AT_MOST:
1496 width = Math.min(width, widthSize);
1497 break;
1498 case MeasureSpec.EXACTLY:
1499 width = widthSize;
1500 break;
1501 case MeasureSpec.UNSPECIFIED:
1502 default:
1503 break;
1504 }
1505 switch (heightMode) {
1506 case MeasureSpec.AT_MOST:
1507 height = Math.min(height, heightSize);
1508 break;
1509 case MeasureSpec.EXACTLY:
1510 height = heightSize;
1511 break;
1512 case MeasureSpec.UNSPECIFIED:
1513 default:
1514 break;
1515 }
Adam Powell2b0952b2011-03-09 00:15:38 -08001516 setMeasuredDimension(width, height);
1517 }
1518
1519 @Override
1520 protected void onLayout(boolean changed, int l, int t, int r, int b) {
1521 final int vCenter = (b - t) / 2;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001522 final boolean isLayoutRtl = isLayoutRtl();
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001523 final int width = getWidth();
Adam Powellc8b0b002011-06-23 14:39:05 -07001524 int upOffset = 0;
Adam Powell2b0952b2011-03-09 00:15:38 -08001525 if (mUpView.getVisibility() != GONE) {
1526 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
1527 final int upHeight = mUpView.getMeasuredHeight();
1528 final int upWidth = mUpView.getMeasuredWidth();
Adam Powellc8b0b002011-06-23 14:39:05 -07001529 upOffset = upLp.leftMargin + upWidth + upLp.rightMargin;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001530 final int upTop = vCenter - upHeight / 2;
1531 final int upBottom = upTop + upHeight;
1532 final int upRight;
1533 final int upLeft;
1534 if (isLayoutRtl) {
1535 upRight = width;
1536 upLeft = upRight - upWidth;
1537 r -= upOffset;
1538 } else {
1539 upRight = upWidth;
1540 upLeft = 0;
1541 l += upOffset;
1542 }
1543 mUpView.layout(upLeft, upTop, upRight, upBottom);
Adam Powell2b0952b2011-03-09 00:15:38 -08001544 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001545
Adam Powell2b0952b2011-03-09 00:15:38 -08001546 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1547 final int iconHeight = mIconView.getMeasuredHeight();
1548 final int iconWidth = mIconView.getMeasuredWidth();
1549 final int hCenter = (r - l) / 2;
Adam Powellc8b0b002011-06-23 14:39:05 -07001550 final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2);
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001551 final int iconBottom = iconTop + iconHeight;
1552 final int iconLeft;
1553 final int iconRight;
1554 int marginStart = iconLp.getMarginStart();
1555 final int delta = Math.max(marginStart, hCenter - iconWidth / 2);
1556 if (isLayoutRtl) {
1557 iconRight = width - upOffset - delta;
1558 iconLeft = iconRight - iconWidth;
1559 } else {
1560 iconLeft = upOffset + delta;
1561 iconRight = iconLeft + iconWidth;
1562 }
1563 mIconView.layout(iconLeft, iconTop, iconRight, iconBottom);
Adam Powell2b0952b2011-03-09 00:15:38 -08001564 }
1565 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001566
1567 private class ExpandedActionViewMenuPresenter implements MenuPresenter {
1568 MenuBuilder mMenu;
1569 MenuItemImpl mCurrentExpandedItem;
1570
1571 @Override
1572 public void initForMenu(Context context, MenuBuilder menu) {
1573 // Clear the expanded action view when menus change.
Adam Powell6b0e97c2011-08-03 12:06:32 -07001574 if (mMenu != null && mCurrentExpandedItem != null) {
1575 mMenu.collapseItemActionView(mCurrentExpandedItem);
Adam Powell8d02dea2011-05-31 21:35:13 -07001576 }
1577 mMenu = menu;
1578 }
1579
1580 @Override
1581 public MenuView getMenuView(ViewGroup root) {
1582 return null;
1583 }
1584
1585 @Override
1586 public void updateMenuView(boolean cleared) {
1587 // Make sure the expanded item we have is still there.
1588 if (mCurrentExpandedItem != null) {
1589 boolean found = false;
Adam Powellf35d0492011-08-17 13:56:47 -07001590
1591 if (mMenu != null) {
1592 final int count = mMenu.size();
1593 for (int i = 0; i < count; i++) {
1594 final MenuItem item = mMenu.getItem(i);
1595 if (item == mCurrentExpandedItem) {
1596 found = true;
1597 break;
1598 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001599 }
1600 }
1601
1602 if (!found) {
1603 // The item we had expanded disappeared. Collapse.
1604 collapseItemActionView(mMenu, mCurrentExpandedItem);
1605 }
1606 }
1607 }
1608
1609 @Override
1610 public void setCallback(Callback cb) {
1611 }
1612
1613 @Override
1614 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
1615 return false;
1616 }
1617
1618 @Override
1619 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1620 }
1621
1622 @Override
1623 public boolean flagActionItems() {
1624 return false;
1625 }
1626
1627 @Override
1628 public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
1629 mExpandedActionView = item.getActionView();
Adam Powell28fa07e2011-07-15 20:17:25 -07001630 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
Adam Powell8d02dea2011-05-31 21:35:13 -07001631 mCurrentExpandedItem = item;
1632 if (mExpandedActionView.getParent() != ActionBarView.this) {
1633 addView(mExpandedActionView);
1634 }
Adam Powell27cba382013-01-22 18:55:20 -08001635 if (mExpandedHomeLayout.getParent() != mUpGoerFive) {
1636 mUpGoerFive.addView(mExpandedHomeLayout);
Adam Powell8d02dea2011-05-31 21:35:13 -07001637 }
1638 mHomeLayout.setVisibility(GONE);
Adam Powell15a16a82011-06-20 10:35:27 -07001639 if (mTitleLayout != null) mTitleLayout.setVisibility(GONE);
Adam Powell8d02dea2011-05-31 21:35:13 -07001640 if (mTabScrollView != null) mTabScrollView.setVisibility(GONE);
1641 if (mSpinner != null) mSpinner.setVisibility(GONE);
1642 if (mCustomNavView != null) mCustomNavView.setVisibility(GONE);
Adam Powell07cf9712013-02-05 16:13:57 -08001643 setHomeButtonEnabled(false, false);
Adam Powell8d02dea2011-05-31 21:35:13 -07001644 requestLayout();
1645 item.setActionViewExpanded(true);
Adam Powell038f1c82011-07-21 14:28:10 -07001646
1647 if (mExpandedActionView instanceof CollapsibleActionView) {
1648 ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
1649 }
Amith Yamasani10da5902011-07-26 16:14:26 -07001650
Adam Powell8d02dea2011-05-31 21:35:13 -07001651 return true;
1652 }
1653
1654 @Override
1655 public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
Amith Yamasani10da5902011-07-26 16:14:26 -07001656 // Do this before detaching the actionview from the hierarchy, in case
1657 // it needs to dismiss the soft keyboard, etc.
1658 if (mExpandedActionView instanceof CollapsibleActionView) {
1659 ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
1660 }
1661
Adam Powell8d02dea2011-05-31 21:35:13 -07001662 removeView(mExpandedActionView);
Adam Powell27cba382013-01-22 18:55:20 -08001663 mUpGoerFive.removeView(mExpandedHomeLayout);
Adam Powellb0e217e2011-08-12 11:36:51 -07001664 mExpandedActionView = null;
Adam Powell8d02dea2011-05-31 21:35:13 -07001665 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
1666 mHomeLayout.setVisibility(VISIBLE);
1667 }
1668 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
Adam Powell15a16a82011-06-20 10:35:27 -07001669 if (mTitleLayout == null) {
1670 initTitle();
1671 } else {
1672 mTitleLayout.setVisibility(VISIBLE);
1673 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001674 }
Adam Powell6684e922013-03-26 15:38:26 -07001675 if (mTabScrollView != null) mTabScrollView.setVisibility(VISIBLE);
1676 if (mSpinner != null) mSpinner.setVisibility(VISIBLE);
1677 if (mCustomNavView != null) mCustomNavView.setVisibility(VISIBLE);
1678
Adam Powell8d02dea2011-05-31 21:35:13 -07001679 mExpandedHomeLayout.setIcon(null);
1680 mCurrentExpandedItem = null;
Adam Powell62f33032013-02-04 12:44:34 -08001681 setHomeButtonEnabled(mWasHomeEnabled); // Set by expandItemActionView above
Adam Powell8d02dea2011-05-31 21:35:13 -07001682 requestLayout();
1683 item.setActionViewExpanded(false);
Adam Powell038f1c82011-07-21 14:28:10 -07001684
Adam Powell8d02dea2011-05-31 21:35:13 -07001685 return true;
1686 }
Adam Powell11ed1d62011-07-11 21:19:59 -07001687
1688 @Override
1689 public int getId() {
1690 return 0;
1691 }
1692
1693 @Override
1694 public Parcelable onSaveInstanceState() {
1695 return null;
1696 }
1697
1698 @Override
1699 public void onRestoreInstanceState(Parcelable state) {
1700 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001701 }
Adam Powell33b97432010-04-20 10:01:14 -07001702}