blob: 1273c4dd6e365c84cf620a1570644583f491880d [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 Powellfd75eef2012-08-02 10:27:31 -070019import android.animation.LayoutTransition;
Adam Powell33b97432010-04-20 10:01:14 -070020import android.app.ActionBar;
Adam Powell8515ee82010-11-30 14:09:55 -080021import android.app.ActionBar.OnNavigationListener;
Adam Powell33b97432010-04-20 10:01:14 -070022import android.content.Context;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageManager;
Adam Powell45c0b192011-07-28 15:11:57 -070025import android.content.res.Configuration;
Adam Powell33b97432010-04-20 10:01:14 -070026import android.content.res.TypedArray;
Adam Powell33b97432010-04-20 10:01:14 -070027import android.graphics.drawable.Drawable;
Adam Powell8d02dea2011-05-31 21:35:13 -070028import android.os.Parcel;
29import android.os.Parcelable;
Adam Powell27cba382013-01-22 18:55:20 -080030import android.text.Layout;
Adam Powell2a7ea672011-01-23 20:25:15 -080031import android.text.TextUtils;
Adam Powell33b97432010-04-20 10:01:14 -070032import android.util.AttributeSet;
Adam Powell038f1c82011-07-21 14:28:10 -070033import android.view.CollapsibleActionView;
Adam Powell661c9082010-07-02 10:09:44 -070034import android.view.Gravity;
Adam Powell89e06452010-06-23 20:24:52 -070035import android.view.LayoutInflater;
36import android.view.Menu;
Adam Powell8d02dea2011-05-31 21:35:13 -070037import android.view.MenuItem;
Adam Powell7bc3ca02011-08-26 18:29:58 -070038import android.view.MotionEvent;
Adam Powell89e06452010-06-23 20:24:52 -070039import android.view.View;
40import android.view.ViewGroup;
Adam Powell9ab97872010-10-26 21:47:29 -070041import android.view.ViewParent;
Adam Powell8d12e202010-11-15 16:44:17 -080042import android.view.Window;
Adam Powell7bc3ca02011-08-26 18:29:58 -070043import android.view.accessibility.AccessibilityEvent;
Adam Powellfa18d182014-01-07 15:56:59 -080044import android.widget.ActionMenuPresenter;
45import android.widget.ActionMenuView;
Adam Powella4082912010-06-04 18:34:02 -070046import android.widget.AdapterView;
Adam Powell2b0952b2011-03-09 00:15:38 -080047import android.widget.FrameLayout;
Adam Powell33b97432010-04-20 10:01:14 -070048import android.widget.ImageView;
Adam Powell0e94b512010-06-29 17:58:20 -070049import android.widget.LinearLayout;
Adam Powell6af97e12010-11-11 21:11:53 -080050import android.widget.ProgressBar;
Adam Powella4082912010-06-04 18:34:02 -070051import android.widget.Spinner;
52import android.widget.SpinnerAdapter;
Adam Powell33b97432010-04-20 10:01:14 -070053import android.widget.TextView;
Adam Powell04fe6eb2013-05-31 14:39:48 -070054import com.android.internal.R;
Adam Powellad79b902013-06-19 11:33:28 -070055import com.android.internal.transition.ActionBarTransition;
Adam Powell04fe6eb2013-05-31 14:39:48 -070056import com.android.internal.view.menu.ActionMenuItem;
Adam Powell04fe6eb2013-05-31 14:39:48 -070057import com.android.internal.view.menu.MenuBuilder;
58import com.android.internal.view.menu.MenuItemImpl;
59import com.android.internal.view.menu.MenuPresenter;
60import com.android.internal.view.menu.MenuView;
61import com.android.internal.view.menu.SubMenuBuilder;
Adam Powell33b97432010-04-20 10:01:14 -070062
Adam Powell33b97432010-04-20 10:01:14 -070063/**
64 * @hide
65 */
Adam Powell640a66e2011-04-29 10:18:53 -070066public class ActionBarView extends AbsActionBarView {
Adam Powell33b97432010-04-20 10:01:14 -070067 private static final String TAG = "ActionBarView";
Adam Powellbe4d68e2010-10-08 18:16:34 -070068
Adam Powell33b97432010-04-20 10:01:14 -070069 /**
70 * Display options applied by default
71 */
72 public static final int DISPLAY_DEFAULT = 0;
73
74 /**
75 * Display options that require re-layout as opposed to a simple invalidate
76 */
Adam Powella1700782010-05-13 13:27:35 -070077 private static final int DISPLAY_RELAYOUT_MASK =
Adam Powell9ab97872010-10-26 21:47:29 -070078 ActionBar.DISPLAY_SHOW_HOME |
79 ActionBar.DISPLAY_USE_LOGO |
80 ActionBar.DISPLAY_HOME_AS_UP |
81 ActionBar.DISPLAY_SHOW_CUSTOM |
Adam Powell27cba382013-01-22 18:55:20 -080082 ActionBar.DISPLAY_SHOW_TITLE |
83 ActionBar.DISPLAY_TITLE_MULTIPLE_LINES;
Adam Powell9ab97872010-10-26 21:47:29 -070084
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -070085 private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
Casey Burkhardt8452a7f2013-04-30 15:56:41 -070086
Adam Powell33b97432010-04-20 10:01:14 -070087 private int mNavigationMode;
Adam Powell82f24e82011-08-18 20:15:20 -070088 private int mDisplayOptions = -1;
Adam Powell33b97432010-04-20 10:01:14 -070089 private CharSequence mTitle;
90 private CharSequence mSubtitle;
91 private Drawable mIcon;
92 private Drawable mLogo;
Adam Powelle0e2f4f2013-04-05 16:27:35 -070093 private CharSequence mHomeDescription;
94 private int mHomeDescriptionRes;
Adam Powell33b97432010-04-20 10:01:14 -070095
Adam Powell8d02dea2011-05-31 21:35:13 -070096 private HomeView mHomeLayout;
97 private HomeView mExpandedHomeLayout;
Adam Powell0e94b512010-06-29 17:58:20 -070098 private LinearLayout mTitleLayout;
Adam Powell33b97432010-04-20 10:01:14 -070099 private TextView mTitleView;
100 private TextView mSubtitleView;
Adam Powell27cba382013-01-22 18:55:20 -0800101 private ViewGroup mUpGoerFive;
Adam Powell54c7d7e2011-06-17 20:30:13 -0700102
Adam Powella4082912010-06-04 18:34:02 -0700103 private Spinner mSpinner;
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800104 private LinearLayout mListNavLayout;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700105 private ScrollingTabContainerView mTabScrollView;
Adam Powella4082912010-06-04 18:34:02 -0700106 private View mCustomNavView;
Adam Powell6af97e12010-11-11 21:11:53 -0800107 private ProgressBar mProgressView;
108 private ProgressBar mIndeterminateProgressView;
109
110 private int mProgressBarPadding;
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800111 private int mItemPadding;
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700112
Adam Powelle2194442010-08-12 18:13:03 -0700113 private int mTitleStyleRes;
114 private int mSubtitleStyleRes;
Adam Powell6af97e12010-11-11 21:11:53 -0800115 private int mProgressStyle;
116 private int mIndeterminateProgressStyle;
Adam Powelle2194442010-08-12 18:13:03 -0700117
Adam Powelle92ea342010-07-14 14:45:50 -0700118 private boolean mUserTitle;
Adam Powelldae78242011-04-25 15:23:41 -0700119 private boolean mIncludeTabs;
Adam Powelld21aa122011-05-27 13:09:52 -0700120 private boolean mIsCollapsable;
Adam Powellf6ce6a92011-06-29 10:25:01 -0700121 private boolean mIsCollapsed;
Adam Powell62f33032013-02-04 12:44:34 -0800122 private boolean mWasHomeEnabled; // Was it enabled before action view expansion?
Adam Powell33b97432010-04-20 10:01:14 -0700123
Adam Powell96675b12010-06-10 18:58:59 -0700124 private MenuBuilder mOptionsMenu;
Adam Powell8c16aa92013-04-04 10:47:52 -0700125 private boolean mMenuPrepared;
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700126
Adam Powelle2194442010-08-12 18:13:03 -0700127 private ActionBarContextView mContextView;
128
Adam Powell33b97432010-04-20 10:01:14 -0700129 private ActionMenuItem mLogoNavItem;
Adam Powell9ab97872010-10-26 21:47:29 -0700130
131 private SpinnerAdapter mSpinnerAdapter;
Adam Powell8515ee82010-11-30 14:09:55 -0800132 private OnNavigationListener mCallback;
Adam Powell33b97432010-04-20 10:01:14 -0700133
Adam Powellf8ac6b72011-05-23 18:14:09 -0700134 private Runnable mTabSelector;
135
Adam Powell8d02dea2011-05-31 21:35:13 -0700136 private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
137 View mExpandedActionView;
138
Adam Powell915ce0d2011-09-28 15:52:57 -0700139 Window.Callback mWindowCallback;
140
Adam Powella4082912010-06-04 18:34:02 -0700141 private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
142 new AdapterView.OnItemSelectedListener() {
143 public void onItemSelected(AdapterView parent, View view, int position, long id) {
144 if (mCallback != null) {
145 mCallback.onNavigationItemSelected(position, id);
146 }
147 }
148 public void onNothingSelected(AdapterView parent) {
149 // Do nothing
150 }
151 };
152
Adam Powell8d02dea2011-05-31 21:35:13 -0700153 private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() {
154 @Override
155 public void onClick(View v) {
156 final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem;
157 if (item != null) {
158 item.collapseActionView();
159 }
160 }
161 };
Adam Powell2b6230e2010-09-07 17:55:25 -0700162
Adam Powell54c7d7e2011-06-17 20:30:13 -0700163 private final OnClickListener mUpClickListener = new OnClickListener() {
164 public void onClick(View v) {
Adam Powell8c16aa92013-04-04 10:47:52 -0700165 if (mMenuPrepared) {
166 // Only invoke the window callback if the options menu has been initialized.
167 mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem);
168 }
Adam Powell54c7d7e2011-06-17 20:30:13 -0700169 }
170 };
171
Adam Powell33b97432010-04-20 10:01:14 -0700172 public ActionBarView(Context context, AttributeSet attrs) {
173 super(context, attrs);
174
Adam Powell654e4e42011-01-03 16:33:50 -0800175 // Background is always provided by the container.
176 setBackgroundResource(0);
177
Adam Powell45c0b192011-07-28 15:11:57 -0700178 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
179 com.android.internal.R.attr.actionBarStyle, 0);
Adam Powell33b97432010-04-20 10:01:14 -0700180
Adam Powell9ab97872010-10-26 21:47:29 -0700181 ApplicationInfo appInfo = context.getApplicationInfo();
Adam Powell33b97432010-04-20 10:01:14 -0700182 PackageManager pm = context.getPackageManager();
Adam Powell661c9082010-07-02 10:09:44 -0700183 mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode,
184 ActionBar.NAVIGATION_MODE_STANDARD);
Adam Powell33b97432010-04-20 10:01:14 -0700185 mTitle = a.getText(R.styleable.ActionBar_title);
186 mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
Adam Powell33b97432010-04-20 10:01:14 -0700187 mLogo = a.getDrawable(R.styleable.ActionBar_logo);
Adam Powell33b97432010-04-20 10:01:14 -0700188 mIcon = a.getDrawable(R.styleable.ActionBar_icon);
Adam Powell9ab97872010-10-26 21:47:29 -0700189
Ed Heyl1c603002010-11-18 12:18:23 -0800190 final LayoutInflater inflater = LayoutInflater.from(context);
Adam Powell9ab97872010-10-26 21:47:29 -0700191
Ed Heyl1c603002010-11-18 12:18:23 -0800192 final int homeResId = a.getResourceId(
Adam Powellb33be1c2010-11-18 12:11:40 -0800193 com.android.internal.R.styleable.ActionBar_homeLayout,
194 com.android.internal.R.layout.action_bar_home);
Adam Powell9ab97872010-10-26 21:47:29 -0700195
Adam Powell27cba382013-01-22 18:55:20 -0800196 mUpGoerFive = (ViewGroup) inflater.inflate(
197 com.android.internal.R.layout.action_bar_up_container, this, false);
198 mHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
Ed Heyl1c603002010-11-18 12:18:23 -0800199
Adam Powell27cba382013-01-22 18:55:20 -0800200 mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
Adam Powellad79b902013-06-19 11:33:28 -0700201 mExpandedHomeLayout.setShowUp(true);
Adam Powell8d02dea2011-05-31 21:35:13 -0700202 mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
Adam Powell7bc3ca02011-08-26 18:29:58 -0700203 mExpandedHomeLayout.setContentDescription(getResources().getText(
204 R.string.action_bar_up_description));
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700205
Adam Powell62f33032013-02-04 12:44:34 -0800206 // This needs to highlight/be focusable on its own.
207 // TODO: Clean up the handoff between expanded/normal.
208 final Drawable upBackground = mUpGoerFive.getBackground();
209 if (upBackground != null) {
210 mExpandedHomeLayout.setBackground(upBackground.getConstantState().newDrawable());
211 }
212 mExpandedHomeLayout.setEnabled(true);
213 mExpandedHomeLayout.setFocusable(true);
214
Adam Powelle2194442010-08-12 18:13:03 -0700215 mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
216 mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
Adam Powell6af97e12010-11-11 21:11:53 -0800217 mProgressStyle = a.getResourceId(R.styleable.ActionBar_progressBarStyle, 0);
218 mIndeterminateProgressStyle = a.getResourceId(
219 R.styleable.ActionBar_indeterminateProgressStyle, 0);
220
221 mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_progressBarPadding, 0);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800222 mItemPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_itemPadding, 0);
Adam Powelle2194442010-08-12 18:13:03 -0700223
Adam Powell9ab97872010-10-26 21:47:29 -0700224 setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT));
225
Adam Powell33b97432010-04-20 10:01:14 -0700226 final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
227 if (customNavId != 0) {
Ed Heyl1c603002010-11-18 12:18:23 -0800228 mCustomNavView = (View) inflater.inflate(customNavId, this, false);
Adam Powell9ab97872010-10-26 21:47:29 -0700229 mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
230 setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM);
Adam Powell33b97432010-04-20 10:01:14 -0700231 }
232
Adam Powelle2194442010-08-12 18:13:03 -0700233 mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700234
Adam Powell33b97432010-04-20 10:01:14 -0700235 a.recycle();
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700236
Ben Komaload199ec2010-11-01 12:24:16 -0700237 mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
Adam Powell27cba382013-01-22 18:55:20 -0800238
239 mUpGoerFive.setOnClickListener(mUpClickListener);
240 mUpGoerFive.setClickable(true);
241 mUpGoerFive.setFocusable(true);
Svetoslav Ganov42138042012-03-20 11:51:39 -0700242
243 if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
244 setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
245 }
Adam Powell33b97432010-04-20 10:01:14 -0700246 }
Adam Powella7db0372010-06-30 17:08:47 -0700247
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700248 @Override
Adam Powell45c0b192011-07-28 15:11:57 -0700249 protected void onConfigurationChanged(Configuration newConfig) {
250 super.onConfigurationChanged(newConfig);
251
Adam Powell07a047f2011-08-31 10:33:20 -0700252 mTitleView = null;
253 mSubtitleView = null;
Adam Powell27cba382013-01-22 18:55:20 -0800254 if (mTitleLayout != null && mTitleLayout.getParent() == mUpGoerFive) {
255 mUpGoerFive.removeView(mTitleLayout);
Adam Powell07a047f2011-08-31 10:33:20 -0700256 }
257 mTitleLayout = null;
258 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
259 initTitle();
260 }
Adam Powell425689e2011-09-08 18:09:33 -0700261
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700262 if (mHomeDescriptionRes != 0) {
263 setHomeActionContentDescription(mHomeDescriptionRes);
264 }
265
Adam Powell425689e2011-09-08 18:09:33 -0700266 if (mTabScrollView != null && mIncludeTabs) {
267 ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
Adam Powellb8440112011-09-12 19:14:11 -0700268 if (lp != null) {
269 lp.width = LayoutParams.WRAP_CONTENT;
270 lp.height = LayoutParams.MATCH_PARENT;
271 }
Adam Powell425689e2011-09-08 18:09:33 -0700272 mTabScrollView.setAllowCollapse(true);
273 }
Adam Powell45c0b192011-07-28 15:11:57 -0700274 }
275
Adam Powell915ce0d2011-09-28 15:52:57 -0700276 /**
277 * Set the window callback used to invoke menu items; used for dispatching home button presses.
278 * @param cb Window callback to dispatch to
279 */
280 public void setWindowCallback(Window.Callback cb) {
281 mWindowCallback = cb;
282 }
283
Adam Powell45c0b192011-07-28 15:11:57 -0700284 @Override
Adam Powellf8ac6b72011-05-23 18:14:09 -0700285 public void onDetachedFromWindow() {
286 super.onDetachedFromWindow();
287 removeCallbacks(mTabSelector);
Adam Powell97e18362011-10-20 15:37:18 -0700288 if (mActionMenuPresenter != null) {
289 mActionMenuPresenter.hideOverflowMenu();
290 mActionMenuPresenter.hideSubMenus();
291 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700292 }
293
294 @Override
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700295 public boolean shouldDelayChildPressedState() {
296 return false;
297 }
298
Adam Powell6af97e12010-11-11 21:11:53 -0800299 public void initProgress() {
300 mProgressView = new ProgressBar(mContext, null, 0, mProgressStyle);
301 mProgressView.setId(R.id.progress_horizontal);
302 mProgressView.setMax(10000);
Adam Powell45b075d2012-01-09 15:41:40 -0800303 mProgressView.setVisibility(GONE);
Adam Powell6af97e12010-11-11 21:11:53 -0800304 addView(mProgressView);
305 }
306
307 public void initIndeterminateProgress() {
308 mIndeterminateProgressView = new ProgressBar(mContext, null, 0,
309 mIndeterminateProgressStyle);
310 mIndeterminateProgressView.setId(R.id.progress_circular);
Adam Powell45b075d2012-01-09 15:41:40 -0800311 mIndeterminateProgressView.setVisibility(GONE);
Adam Powell6af97e12010-11-11 21:11:53 -0800312 addView(mIndeterminateProgressView);
313 }
314
Adam Powella05aba92011-09-23 14:22:49 -0700315 @Override
Adam Powell9b4bee02011-04-27 19:24:47 -0700316 public void setSplitActionBar(boolean splitActionBar) {
317 if (mSplitActionBar != splitActionBar) {
318 if (mMenuView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700319 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
320 if (oldParent != null) {
321 oldParent.removeView(mMenuView);
322 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700323 if (splitActionBar) {
Adam Powell9b4bee02011-04-27 19:24:47 -0700324 if (mSplitView != null) {
325 mSplitView.addView(mMenuView);
326 }
Adam Powellf203e0a2012-03-06 17:40:12 -0800327 mMenuView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
Adam Powell9b4bee02011-04-27 19:24:47 -0700328 } else {
329 addView(mMenuView);
Adam Powellf203e0a2012-03-06 17:40:12 -0800330 mMenuView.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
Adam Powell9b4bee02011-04-27 19:24:47 -0700331 }
Adam Powellf203e0a2012-03-06 17:40:12 -0800332 mMenuView.requestLayout();
Adam Powell9b4bee02011-04-27 19:24:47 -0700333 }
Adam Powella05aba92011-09-23 14:22:49 -0700334 if (mSplitView != null) {
335 mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE);
336 }
Adam Powellf203e0a2012-03-06 17:40:12 -0800337
338 if (mActionMenuPresenter != null) {
339 if (!splitActionBar) {
340 mActionMenuPresenter.setExpandedActionViewsExclusive(
341 getResources().getBoolean(
342 com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
343 } else {
344 mActionMenuPresenter.setExpandedActionViewsExclusive(false);
345 // Allow full screen width in split mode.
346 mActionMenuPresenter.setWidthLimit(
347 getContext().getResources().getDisplayMetrics().widthPixels, true);
348 // No limit to the item count; use whatever will fit.
349 mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
350 }
351 }
Adam Powella05aba92011-09-23 14:22:49 -0700352 super.setSplitActionBar(splitActionBar);
Adam Powell9b4bee02011-04-27 19:24:47 -0700353 }
354 }
355
356 public boolean isSplitActionBar() {
357 return mSplitActionBar;
358 }
359
Adam Powelldae78242011-04-25 15:23:41 -0700360 public boolean hasEmbeddedTabs() {
361 return mIncludeTabs;
362 }
363
Adam Powellf8ac6b72011-05-23 18:14:09 -0700364 public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
Adam Powelle0adac02011-06-14 13:46:30 -0700365 if (mTabScrollView != null) {
366 removeView(mTabScrollView);
367 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700368 mTabScrollView = tabs;
369 mIncludeTabs = tabs != null;
Adam Powellc3076422011-06-01 18:19:04 -0700370 if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
Adam Powell39a8dc42011-05-27 18:44:00 -0700371 addView(mTabScrollView);
Adam Powellf5645cb2011-08-10 22:49:02 -0700372 ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
373 lp.width = LayoutParams.WRAP_CONTENT;
374 lp.height = LayoutParams.MATCH_PARENT;
375 tabs.setAllowCollapse(true);
Adam Powell39a8dc42011-05-27 18:44:00 -0700376 }
Adam Powelldae78242011-04-25 15:23:41 -0700377 }
378
Adam Powell8515ee82010-11-30 14:09:55 -0800379 public void setCallback(OnNavigationListener callback) {
Adam Powell96675b12010-06-10 18:58:59 -0700380 mCallback = callback;
Adam Powell33b97432010-04-20 10:01:14 -0700381 }
Adam Powella7db0372010-06-30 17:08:47 -0700382
Adam Powell8c16aa92013-04-04 10:47:52 -0700383 public void setMenuPrepared() {
384 mMenuPrepared = true;
385 }
386
Adam Powell696cba52011-03-29 10:38:16 -0700387 public void setMenu(Menu menu, MenuPresenter.Callback cb) {
Adam Powellf2d7a5d2011-02-07 18:05:24 -0800388 if (menu == mOptionsMenu) return;
389
Adam Powell696cba52011-03-29 10:38:16 -0700390 if (mOptionsMenu != null) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700391 mOptionsMenu.removeMenuPresenter(mActionMenuPresenter);
392 mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter);
Adam Powell696cba52011-03-29 10:38:16 -0700393 }
394
Adam Powell96675b12010-06-10 18:58:59 -0700395 MenuBuilder builder = (MenuBuilder) menu;
396 mOptionsMenu = builder;
397 if (mMenuView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700398 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
399 if (oldParent != null) {
400 oldParent.removeView(mMenuView);
401 }
Adam Powell33b97432010-04-20 10:01:14 -0700402 }
Adam Powell8d02dea2011-05-31 21:35:13 -0700403 if (mActionMenuPresenter == null) {
Adam Powell538e5652011-10-11 13:47:08 -0700404 mActionMenuPresenter = new ActionMenuPresenter(mContext);
Adam Powell8d02dea2011-05-31 21:35:13 -0700405 mActionMenuPresenter.setCallback(cb);
Adam Powell11ed1d62011-07-11 21:19:59 -0700406 mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
Adam Powell8d02dea2011-05-31 21:35:13 -0700407 mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
Adam Powell696cba52011-03-29 10:38:16 -0700408 }
Adam Powell35265562011-05-27 15:29:41 -0700409
Adam Powell1ab418a2011-06-09 20:49:49 -0700410 ActionMenuView menuView;
Adam Powell96675b12010-06-10 18:58:59 -0700411 final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
412 LayoutParams.MATCH_PARENT);
Adam Powell9b4bee02011-04-27 19:24:47 -0700413 if (!mSplitActionBar) {
Adam Powellb187cd92011-07-20 14:17:56 -0700414 mActionMenuPresenter.setExpandedActionViewsExclusive(
415 getResources().getBoolean(
416 com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
Adam Powellf35d0492011-08-17 13:56:47 -0700417 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700418 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell894bf542011-07-22 13:39:08 -0700419 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
420 if (oldParent != null && oldParent != this) {
421 oldParent.removeView(menuView);
422 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700423 addView(menuView, layoutParams);
Adam Powell9b4bee02011-04-27 19:24:47 -0700424 } else {
Adam Powellb187cd92011-07-20 14:17:56 -0700425 mActionMenuPresenter.setExpandedActionViewsExclusive(false);
Adam Powell9b4bee02011-04-27 19:24:47 -0700426 // Allow full screen width in split mode.
Adam Powell8d02dea2011-05-31 21:35:13 -0700427 mActionMenuPresenter.setWidthLimit(
Adam Powell640a66e2011-04-29 10:18:53 -0700428 getContext().getResources().getDisplayMetrics().widthPixels, true);
Adam Powell9b4bee02011-04-27 19:24:47 -0700429 // No limit to the item count; use whatever will fit.
Adam Powell8d02dea2011-05-31 21:35:13 -0700430 mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
Adam Powell640a66e2011-04-29 10:18:53 -0700431 // Span the whole width
432 layoutParams.width = LayoutParams.MATCH_PARENT;
Adam Powellfa18d182014-01-07 15:56:59 -0800433 layoutParams.height = mContentHeight;
Adam Powellf35d0492011-08-17 13:56:47 -0700434 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700435 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell9b4bee02011-04-27 19:24:47 -0700436 if (mSplitView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700437 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
438 if (oldParent != null && oldParent != mSplitView) {
439 oldParent.removeView(menuView);
440 }
Adam Powell9a5cc282011-08-28 16:18:16 -0700441 menuView.setVisibility(getAnimatedVisibility());
Adam Powell1ab418a2011-06-09 20:49:49 -0700442 mSplitView.addView(menuView, layoutParams);
443 } else {
444 // We'll add this later if we missed it this time.
445 menuView.setLayoutParams(layoutParams);
446 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700447 }
Adam Powell96675b12010-06-10 18:58:59 -0700448 mMenuView = menuView;
Adam Powell33b97432010-04-20 10:01:14 -0700449 }
Adam Powella7db0372010-06-30 17:08:47 -0700450
Adam Powellf35d0492011-08-17 13:56:47 -0700451 private void configPresenters(MenuBuilder builder) {
452 if (builder != null) {
453 builder.addMenuPresenter(mActionMenuPresenter);
454 builder.addMenuPresenter(mExpandedMenuPresenter);
455 } else {
456 mActionMenuPresenter.initForMenu(mContext, null);
457 mExpandedMenuPresenter.initForMenu(mContext, null);
458 mActionMenuPresenter.updateMenuView(true);
459 mExpandedMenuPresenter.updateMenuView(true);
460 }
461 }
462
Adam Powellb80d3322011-07-15 21:33:11 -0700463 public boolean hasExpandedActionView() {
464 return mExpandedMenuPresenter != null &&
465 mExpandedMenuPresenter.mCurrentExpandedItem != null;
466 }
467
468 public void collapseActionView() {
469 final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
470 mExpandedMenuPresenter.mCurrentExpandedItem;
471 if (item != null) {
472 item.collapseActionView();
473 }
474 }
475
Adam Powell33b97432010-04-20 10:01:14 -0700476 public void setCustomNavigationView(View view) {
Adam Powell9ab97872010-10-26 21:47:29 -0700477 final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
Adam Powellad79b902013-06-19 11:33:28 -0700478 if (showCustom) {
Chet Haased8d7c382013-09-23 11:26:36 -0700479 ActionBarTransition.beginDelayedTransition(this);
Adam Powellad79b902013-06-19 11:33:28 -0700480 }
Adam Powell9ab97872010-10-26 21:47:29 -0700481 if (mCustomNavView != null && showCustom) {
482 removeView(mCustomNavView);
483 }
Adam Powella4082912010-06-04 18:34:02 -0700484 mCustomNavView = view;
Adam Powell9ab97872010-10-26 21:47:29 -0700485 if (mCustomNavView != null && showCustom) {
486 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700487 }
Adam Powell33b97432010-04-20 10:01:14 -0700488 }
Adam Powella7db0372010-06-30 17:08:47 -0700489
Adam Powell33b97432010-04-20 10:01:14 -0700490 public CharSequence getTitle() {
491 return mTitle;
492 }
Adam Powella7db0372010-06-30 17:08:47 -0700493
Adam Powelle92ea342010-07-14 14:45:50 -0700494 /**
495 * Set the action bar title. This will always replace or override window titles.
496 * @param title Title to set
497 *
498 * @see #setWindowTitle(CharSequence)
499 */
Adam Powell33b97432010-04-20 10:01:14 -0700500 public void setTitle(CharSequence title) {
Adam Powelle92ea342010-07-14 14:45:50 -0700501 mUserTitle = true;
502 setTitleImpl(title);
503 }
504
505 /**
506 * Set the window title. A window title will always be replaced or overridden by a user title.
507 * @param title Title to set
508 *
509 * @see #setTitle(CharSequence)
510 */
511 public void setWindowTitle(CharSequence title) {
512 if (!mUserTitle) {
513 setTitleImpl(title);
514 }
515 }
516
517 private void setTitleImpl(CharSequence title) {
Chet Haased8d7c382013-09-23 11:26:36 -0700518 ActionBarTransition.beginDelayedTransition(this);
Adam Powell33b97432010-04-20 10:01:14 -0700519 mTitle = title;
520 if (mTitleView != null) {
521 mTitleView.setText(title);
Adam Powellb0e217e2011-08-12 11:36:51 -0700522 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700523 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700524 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
525 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700526 }
527 if (mLogoNavItem != null) {
528 mLogoNavItem.setTitle(title);
529 }
Adam Powell2229ca02013-11-12 16:20:46 -0800530 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powell33b97432010-04-20 10:01:14 -0700531 }
Adam Powella7db0372010-06-30 17:08:47 -0700532
Adam Powell33b97432010-04-20 10:01:14 -0700533 public CharSequence getSubtitle() {
534 return mSubtitle;
535 }
Adam Powella7db0372010-06-30 17:08:47 -0700536
Adam Powell33b97432010-04-20 10:01:14 -0700537 public void setSubtitle(CharSequence subtitle) {
Chet Haased8d7c382013-09-23 11:26:36 -0700538 ActionBarTransition.beginDelayedTransition(this);
Adam Powell33b97432010-04-20 10:01:14 -0700539 mSubtitle = subtitle;
540 if (mSubtitleView != null) {
541 mSubtitleView.setText(subtitle);
Adam Powell04587962010-11-11 22:15:07 -0800542 mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE);
Adam Powellb0e217e2011-08-12 11:36:51 -0700543 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700544 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700545 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
546 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700547 }
Adam Powell2229ca02013-11-12 16:20:46 -0800548 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powell33b97432010-04-20 10:01:14 -0700549 }
Adam Powella7db0372010-06-30 17:08:47 -0700550
Adam Powellc29f4e52011-07-13 20:40:52 -0700551 public void setHomeButtonEnabled(boolean enable) {
Adam Powell07cf9712013-02-05 16:13:57 -0800552 setHomeButtonEnabled(enable, true);
553 }
554
555 private void setHomeButtonEnabled(boolean enable, boolean recordState) {
556 if (recordState) {
557 mWasHomeEnabled = enable;
558 }
559
560 if (mExpandedActionView != null) {
561 // There's an action view currently showing and we want to keep the state
562 // configured for the action view at the moment. If we needed to record the
563 // new state for later we will have done so above.
564 return;
565 }
566
Adam Powell27cba382013-01-22 18:55:20 -0800567 mUpGoerFive.setEnabled(enable);
568 mUpGoerFive.setFocusable(enable);
Adam Powellc29f4e52011-07-13 20:40:52 -0700569 // Make sure the home button has an accurate content description for accessibility.
Adam Powellf37a5132013-11-01 16:32:37 -0700570 updateHomeAccessibility(enable);
571 }
572
573 private void updateHomeAccessibility(boolean homeEnabled) {
574 if (!homeEnabled) {
Adam Powell27cba382013-01-22 18:55:20 -0800575 mUpGoerFive.setContentDescription(null);
576 mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
Adam Powellc29f4e52011-07-13 20:40:52 -0700577 } else {
Adam Powell27cba382013-01-22 18:55:20 -0800578 mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700579 mUpGoerFive.setContentDescription(buildHomeContentDescription());
580 }
581 }
582
583 /**
584 * Compose a content description for the Home/Up affordance.
585 *
586 * <p>As this encompasses the icon/logo, title and subtitle all in one, we need
587 * a description for the whole wad of stuff that can be localized properly.</p>
588 */
589 private CharSequence buildHomeContentDescription() {
590 final CharSequence homeDesc;
591 if (mHomeDescription != null) {
592 homeDesc = mHomeDescription;
593 } else {
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700594 if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700595 homeDesc = mContext.getResources().getText(R.string.action_bar_up_description);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700596 } else {
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700597 homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700598 }
Adam Powellc29f4e52011-07-13 20:40:52 -0700599 }
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700600
601 final CharSequence title = getTitle();
602 final CharSequence subtitle = getSubtitle();
603 if (!TextUtils.isEmpty(title)) {
604 final String result;
605 if (!TextUtils.isEmpty(subtitle)) {
606 result = getResources().getString(
607 R.string.action_bar_home_subtitle_description_format,
608 title, subtitle, homeDesc);
609 } else {
610 result = getResources().getString(R.string.action_bar_home_description_format,
611 title, homeDesc);
612 }
613 return result;
614 }
615 return homeDesc;
Adam Powellc29f4e52011-07-13 20:40:52 -0700616 }
617
Adam Powell33b97432010-04-20 10:01:14 -0700618 public void setDisplayOptions(int options) {
Adam Powell82f24e82011-08-18 20:15:20 -0700619 final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions;
Adam Powell33b97432010-04-20 10:01:14 -0700620 mDisplayOptions = options;
Adam Powelldae78242011-04-25 15:23:41 -0700621
Adam Powell33b97432010-04-20 10:01:14 -0700622 if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
Chet Haased8d7c382013-09-23 11:26:36 -0700623 ActionBarTransition.beginDelayedTransition(this);
Adam Powell9ab97872010-10-26 21:47:29 -0700624
625 if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powellc29f4e52011-07-13 20:40:52 -0700626 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
Adam Powellad79b902013-06-19 11:33:28 -0700627 mHomeLayout.setShowUp(setUp);
Adam Powellc29f4e52011-07-13 20:40:52 -0700628
629 // Showing home as up implicitly enables interaction with it.
630 // In honeycomb it was always enabled, so make this transition
631 // a bit easier for developers in the common case.
632 // (It would be silly to show it as up without responding to it.)
633 if (setUp) {
634 setHomeButtonEnabled(true);
635 }
Adam Powella1700782010-05-13 13:27:35 -0700636 }
Adam Powell9ab97872010-10-26 21:47:29 -0700637
Ed Heyl1c603002010-11-18 12:18:23 -0800638 if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
639 final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0;
Adam Powell8d02dea2011-05-31 21:35:13 -0700640 mHomeLayout.setIcon(logoVis ? mLogo : mIcon);
Adam Powell9ab97872010-10-26 21:47:29 -0700641 }
642
643 if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
644 if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
645 initTitle();
646 } else {
Adam Powell27cba382013-01-22 18:55:20 -0800647 mUpGoerFive.removeView(mTitleLayout);
Adam Powell9ab97872010-10-26 21:47:29 -0700648 }
649 }
650
Adam Powellad79b902013-06-19 11:33:28 -0700651 final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
652 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
653 final boolean titleUp = !showHome && homeAsUp;
654 mHomeLayout.setShowIcon(showHome);
655
656 final int homeVis = (showHome || titleUp) && mExpandedActionView == null ?
657 VISIBLE : GONE;
658 mHomeLayout.setVisibility(homeVis);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700659
Adam Powell9ab97872010-10-26 21:47:29 -0700660 if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
661 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
662 addView(mCustomNavView);
663 } else {
664 removeView(mCustomNavView);
665 }
Adam Powella1700782010-05-13 13:27:35 -0700666 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700667
Adam Powell27cba382013-01-22 18:55:20 -0800668 if (mTitleLayout != null &&
669 (flagsChanged & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
670 if ((options & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
671 mTitleView.setSingleLine(false);
672 mTitleView.setMaxLines(2);
673 } else {
674 mTitleView.setMaxLines(1);
675 mTitleView.setSingleLine(true);
676 }
677 }
678
Adam Powell33b97432010-04-20 10:01:14 -0700679 requestLayout();
680 } else {
681 invalidate();
682 }
Adam Powellf3cd1d92011-04-26 17:31:52 -0700683
684 // Make sure the home button has an accurate content description for accessibility.
Adam Powell2229ca02013-11-12 16:20:46 -0800685 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powell33b97432010-04-20 10:01:14 -0700686 }
687
Adam Powell1969b872011-03-22 11:52:48 -0700688 public void setIcon(Drawable icon) {
689 mIcon = icon;
690 if (icon != null &&
691 ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700692 mHomeLayout.setIcon(icon);
Adam Powell1969b872011-03-22 11:52:48 -0700693 }
Adam Powellf8218192012-02-21 17:10:10 -0800694 if (mExpandedActionView != null) {
695 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
696 }
Adam Powell1969b872011-03-22 11:52:48 -0700697 }
698
Adam Powell45c515b2011-04-21 18:50:20 -0700699 public void setIcon(int resId) {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800700 setIcon(resId != 0 ? mContext.getDrawable(resId) : null);
Adam Powell04fe6eb2013-05-31 14:39:48 -0700701 }
702
703 public boolean hasIcon() {
704 return mIcon != null;
Adam Powell45c515b2011-04-21 18:50:20 -0700705 }
706
Adam Powell1969b872011-03-22 11:52:48 -0700707 public void setLogo(Drawable logo) {
708 mLogo = logo;
709 if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700710 mHomeLayout.setIcon(logo);
Adam Powell1969b872011-03-22 11:52:48 -0700711 }
712 }
713
Adam Powell45c515b2011-04-21 18:50:20 -0700714 public void setLogo(int resId) {
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800715 setLogo(resId != 0 ? mContext.getDrawable(resId) : null);
Adam Powell04fe6eb2013-05-31 14:39:48 -0700716 }
717
718 public boolean hasLogo() {
719 return mLogo != null;
Adam Powell45c515b2011-04-21 18:50:20 -0700720 }
721
Adam Powell33b97432010-04-20 10:01:14 -0700722 public void setNavigationMode(int mode) {
Adam Powella1700782010-05-13 13:27:35 -0700723 final int oldMode = mNavigationMode;
724 if (mode != oldMode) {
Chet Haased8d7c382013-09-23 11:26:36 -0700725 ActionBarTransition.beginDelayedTransition(this);
Adam Powella1700782010-05-13 13:27:35 -0700726 switch (oldMode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700727 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powellc3076422011-06-01 18:19:04 -0700728 if (mListNavLayout != null) {
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800729 removeView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700730 }
731 break;
Adam Powell661c9082010-07-02 10:09:44 -0700732 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700733 if (mTabScrollView != null && mIncludeTabs) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700734 removeView(mTabScrollView);
Adam Powell661c9082010-07-02 10:09:44 -0700735 }
Adam Powella1700782010-05-13 13:27:35 -0700736 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700737
Adam Powella1700782010-05-13 13:27:35 -0700738 switch (mode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700739 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800740 if (mSpinner == null) {
741 mSpinner = new Spinner(mContext, null,
742 com.android.internal.R.attr.actionDropDownStyle);
Adam Powell29c04ef2012-12-10 15:42:22 -0800743 mSpinner.setId(com.android.internal.R.id.action_bar_spinner);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800744 mListNavLayout = new LinearLayout(mContext, null,
745 com.android.internal.R.attr.actionBarTabBarStyle);
746 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
Adam Powelle7d46842011-01-13 21:36:09 -0800747 LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800748 params.gravity = Gravity.CENTER;
749 mListNavLayout.addView(mSpinner, params);
750 }
751 if (mSpinner.getAdapter() != mSpinnerAdapter) {
752 mSpinner.setAdapter(mSpinnerAdapter);
753 }
Adam Powella4082912010-06-04 18:34:02 -0700754 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800755 addView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700756 break;
Adam Powell661c9082010-07-02 10:09:44 -0700757 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700758 if (mTabScrollView != null && mIncludeTabs) {
Adam Powelldae78242011-04-25 15:23:41 -0700759 addView(mTabScrollView);
760 }
Adam Powell661c9082010-07-02 10:09:44 -0700761 break;
Adam Powella1700782010-05-13 13:27:35 -0700762 }
Adam Powell33b97432010-04-20 10:01:14 -0700763 mNavigationMode = mode;
764 requestLayout();
765 }
766 }
Adam Powelldae78242011-04-25 15:23:41 -0700767
Adam Powella4082912010-06-04 18:34:02 -0700768 public void setDropdownAdapter(SpinnerAdapter adapter) {
Adam Powell9ab97872010-10-26 21:47:29 -0700769 mSpinnerAdapter = adapter;
770 if (mSpinner != null) {
771 mSpinner.setAdapter(adapter);
772 }
773 }
774
775 public SpinnerAdapter getDropdownAdapter() {
776 return mSpinnerAdapter;
Adam Powella4082912010-06-04 18:34:02 -0700777 }
Adam Powell17809772010-07-21 13:25:11 -0700778
779 public void setDropdownSelectedPosition(int position) {
780 mSpinner.setSelection(position);
781 }
782
783 public int getDropdownSelectedPosition() {
784 return mSpinner.getSelectedItemPosition();
785 }
786
Adam Powell33b97432010-04-20 10:01:14 -0700787 public View getCustomNavigationView() {
Adam Powella4082912010-06-04 18:34:02 -0700788 return mCustomNavView;
Adam Powell33b97432010-04-20 10:01:14 -0700789 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700790
Adam Powell33b97432010-04-20 10:01:14 -0700791 public int getNavigationMode() {
792 return mNavigationMode;
793 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700794
Adam Powell33b97432010-04-20 10:01:14 -0700795 public int getDisplayOptions() {
796 return mDisplayOptions;
797 }
Adam Powella7db0372010-06-30 17:08:47 -0700798
799 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -0700800 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
Adam Powella7db0372010-06-30 17:08:47 -0700801 // Used by custom nav views if they don't supply layout params. Everything else
802 // added to an ActionBarView should have them already.
Adam Powell9ab97872010-10-26 21:47:29 -0700803 return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY);
Adam Powella7db0372010-06-30 17:08:47 -0700804 }
805
Adam Powell33b97432010-04-20 10:01:14 -0700806 @Override
807 protected void onFinishInflate() {
808 super.onFinishInflate();
809
Adam Powell27cba382013-01-22 18:55:20 -0800810 mUpGoerFive.addView(mHomeLayout, 0);
811 addView(mUpGoerFive);
Adam Powell9ab97872010-10-26 21:47:29 -0700812
Adam Powell9ab97872010-10-26 21:47:29 -0700813 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
814 final ViewParent parent = mCustomNavView.getParent();
815 if (parent != this) {
816 if (parent instanceof ViewGroup) {
817 ((ViewGroup) parent).removeView(mCustomNavView);
818 }
Adam Powella4082912010-06-04 18:34:02 -0700819 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700820 }
Adam Powell33b97432010-04-20 10:01:14 -0700821 }
822 }
Adam Powellc8b0b002011-06-23 14:39:05 -0700823
Adam Powella1700782010-05-13 13:27:35 -0700824 private void initTitle() {
Adam Powell15a16a82011-06-20 10:35:27 -0700825 if (mTitleLayout == null) {
826 LayoutInflater inflater = LayoutInflater.from(getContext());
Adam Powell9e58df52011-08-15 17:06:49 -0700827 mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item,
828 this, false);
Adam Powell15a16a82011-06-20 10:35:27 -0700829 mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
830 mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700831
Adam Powell15a16a82011-06-20 10:35:27 -0700832 if (mTitleStyleRes != 0) {
833 mTitleView.setTextAppearance(mContext, mTitleStyleRes);
834 }
835 if (mTitle != null) {
836 mTitleView.setText(mTitle);
837 }
Adam Powelle2194442010-08-12 18:13:03 -0700838
Adam Powell15a16a82011-06-20 10:35:27 -0700839 if (mSubtitleStyleRes != 0) {
840 mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
841 }
842 if (mSubtitle != null) {
843 mSubtitleView.setText(mSubtitle);
844 mSubtitleView.setVisibility(VISIBLE);
845 }
Adam Powell0e94b512010-06-29 17:58:20 -0700846 }
Adam Powelle2194442010-08-12 18:13:03 -0700847
Chet Haased8d7c382013-09-23 11:26:36 -0700848 ActionBarTransition.beginDelayedTransition(this);
Adam Powell27cba382013-01-22 18:55:20 -0800849 mUpGoerFive.addView(mTitleLayout);
Adam Powell82f24e82011-08-18 20:15:20 -0700850 if (mExpandedActionView != null ||
851 (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
852 // Don't show while in expanded mode or with empty text
Adam Powell71f34172011-08-11 20:07:11 -0700853 mTitleLayout.setVisibility(GONE);
Adam Powell6684e922013-03-26 15:38:26 -0700854 } else {
855 mTitleLayout.setVisibility(VISIBLE);
Adam Powell71f34172011-08-11 20:07:11 -0700856 }
Adam Powella1700782010-05-13 13:27:35 -0700857 }
Adam Powell33b97432010-04-20 10:01:14 -0700858
Adam Powelle2194442010-08-12 18:13:03 -0700859 public void setContextView(ActionBarContextView view) {
860 mContextView = view;
861 }
862
Adam Powelld21aa122011-05-27 13:09:52 -0700863 public void setCollapsable(boolean collapsable) {
864 mIsCollapsable = collapsable;
865 }
866
Adam Powellf6ce6a92011-06-29 10:25:01 -0700867 public boolean isCollapsed() {
868 return mIsCollapsed;
869 }
870
Adam Powell27cba382013-01-22 18:55:20 -0800871 /**
872 * @return True if any characters in the title were truncated
873 */
874 public boolean isTitleTruncated() {
875 if (mTitleView == null) {
876 return false;
877 }
878
879 final Layout titleLayout = mTitleView.getLayout();
880 if (titleLayout == null) {
881 return false;
882 }
883
884 final int lineCount = titleLayout.getLineCount();
885 for (int i = 0; i < lineCount; i++) {
886 if (titleLayout.getEllipsisCount(i) > 0) {
887 return true;
888 }
889 }
890 return false;
891 }
892
Adam Powell33b97432010-04-20 10:01:14 -0700893 @Override
894 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Adam Powelld21aa122011-05-27 13:09:52 -0700895 final int childCount = getChildCount();
896 if (mIsCollapsable) {
897 int visibleChildren = 0;
898 for (int i = 0; i < childCount; i++) {
899 final View child = getChildAt(i);
900 if (child.getVisibility() != GONE &&
Adam Powell27cba382013-01-22 18:55:20 -0800901 !(child == mMenuView && mMenuView.getChildCount() == 0) &&
902 child != mUpGoerFive) {
903 visibleChildren++;
904 }
905 }
906
907 final int upChildCount = mUpGoerFive.getChildCount();
908 for (int i = 0; i < upChildCount; i++) {
909 final View child = mUpGoerFive.getChildAt(i);
910 if (child.getVisibility() != GONE) {
Adam Powelld21aa122011-05-27 13:09:52 -0700911 visibleChildren++;
912 }
913 }
914
915 if (visibleChildren == 0) {
916 // No size for an empty action bar when collapsable.
917 setMeasuredDimension(0, 0);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700918 mIsCollapsed = true;
Adam Powelld21aa122011-05-27 13:09:52 -0700919 return;
920 }
921 }
Adam Powellf6ce6a92011-06-29 10:25:01 -0700922 mIsCollapsed = false;
Adam Powelld21aa122011-05-27 13:09:52 -0700923
Adam Powell33b97432010-04-20 10:01:14 -0700924 int widthMode = MeasureSpec.getMode(widthMeasureSpec);
925 if (widthMode != MeasureSpec.EXACTLY) {
926 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
927 "with android:layout_width=\"match_parent\" (or fill_parent)");
928 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700929
Adam Powell33b97432010-04-20 10:01:14 -0700930 int heightMode = MeasureSpec.getMode(heightMeasureSpec);
931 if (heightMode != MeasureSpec.AT_MOST) {
932 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
933 "with android:layout_height=\"wrap_content\"");
934 }
935
936 int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
Adam Powelle2194442010-08-12 18:13:03 -0700937
Adam Powell570470a2012-08-06 17:00:17 -0700938 int maxHeight = mContentHeight >= 0 ?
Adam Powelle2194442010-08-12 18:13:03 -0700939 mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700940
Adam Powelle2194442010-08-12 18:13:03 -0700941 final int verticalPadding = getPaddingTop() + getPaddingBottom();
Adam Powell9ab97872010-10-26 21:47:29 -0700942 final int paddingLeft = getPaddingLeft();
943 final int paddingRight = getPaddingRight();
Adam Powelle2194442010-08-12 18:13:03 -0700944 final int height = maxHeight - verticalPadding;
Adam Powella1700782010-05-13 13:27:35 -0700945 final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
Adam Powell6322af52012-08-08 15:59:12 -0700946 final int exactHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
Adam Powell33b97432010-04-20 10:01:14 -0700947
Adam Powell9ab97872010-10-26 21:47:29 -0700948 int availableWidth = contentWidth - paddingLeft - paddingRight;
949 int leftOfCenter = availableWidth / 2;
950 int rightOfCenter = leftOfCenter;
951
Adam Powellad79b902013-06-19 11:33:28 -0700952 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
953 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
954
Adam Powellb1e2f252011-08-22 17:42:12 -0700955 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powell8d02dea2011-05-31 21:35:13 -0700956
Adam Powellad79b902013-06-19 11:33:28 -0700957 final ViewGroup.LayoutParams homeLp = homeLayout.getLayoutParams();
958 int homeWidthSpec;
959 if (homeLp.width < 0) {
960 homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
961 } else {
962 homeWidthSpec = MeasureSpec.makeMeasureSpec(homeLp.width, MeasureSpec.EXACTLY);
963 }
Adam Powell27cba382013-01-22 18:55:20 -0800964
Adam Powellad79b902013-06-19 11:33:28 -0700965 /*
966 * This is a little weird.
967 * We're only measuring the *home* affordance within the Up container here
968 * on purpose, because we want to give the available space to all other views before
969 * the title text. We'll remeasure the whole up container again later.
970 * We need to measure this container so we know the right offset for the up affordance
971 * no matter what.
972 */
973 homeLayout.measure(homeWidthSpec, exactHeightSpec);
974
975 int homeWidth = 0;
976 if ((homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive)
977 || showTitle) {
Adam Powell27cba382013-01-22 18:55:20 -0800978 homeWidth = homeLayout.getMeasuredWidth();
979 final int homeOffsetWidth = homeWidth + homeLayout.getStartOffset();
980 availableWidth = Math.max(0, availableWidth - homeOffsetWidth);
981 leftOfCenter = Math.max(0, availableWidth - homeOffsetWidth);
Adam Powell33b97432010-04-20 10:01:14 -0700982 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700983
Adam Powell9b4bee02011-04-27 19:24:47 -0700984 if (mMenuView != null && mMenuView.getParent() == this) {
Adam Powell6322af52012-08-08 15:59:12 -0700985 availableWidth = measureChildView(mMenuView, availableWidth, exactHeightSpec, 0);
Adam Powell1b4a1622011-05-17 12:13:13 -0700986 rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
Adam Powell33b97432010-04-20 10:01:14 -0700987 }
Adam Powell9ab97872010-10-26 21:47:29 -0700988
Adam Powellaa8e509b2011-08-25 09:29:21 -0700989 if (mIndeterminateProgressView != null &&
990 mIndeterminateProgressView.getVisibility() != GONE) {
991 availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
992 childSpecHeight, 0);
993 rightOfCenter = Math.max(0,
994 rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
995 }
Adam Powell9ab97872010-10-26 21:47:29 -0700996
Adam Powellaa8e509b2011-08-25 09:29:21 -0700997 if (mExpandedActionView == null) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700998 switch (mNavigationMode) {
999 case ActionBar.NAVIGATION_MODE_LIST:
1000 if (mListNavLayout != null) {
1001 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
1002 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
1003 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
1004 mListNavLayout.measure(
1005 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
1006 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1007 final int listNavWidth = mListNavLayout.getMeasuredWidth();
1008 availableWidth = Math.max(0, availableWidth - listNavWidth);
1009 leftOfCenter = Math.max(0, leftOfCenter - listNavWidth);
1010 }
1011 break;
1012 case ActionBar.NAVIGATION_MODE_TABS:
1013 if (mTabScrollView != null) {
1014 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
1015 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
1016 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
1017 mTabScrollView.measure(
1018 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
1019 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1020 final int tabWidth = mTabScrollView.getMeasuredWidth();
1021 availableWidth = Math.max(0, availableWidth - tabWidth);
1022 leftOfCenter = Math.max(0, leftOfCenter - tabWidth);
1023 }
1024 break;
Adam Powell33b97432010-04-20 10:01:14 -07001025 }
Adam Powell33b97432010-04-20 10:01:14 -07001026 }
1027
Adam Powell8d02dea2011-05-31 21:35:13 -07001028 View customView = null;
1029 if (mExpandedActionView != null) {
1030 customView = mExpandedActionView;
1031 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1032 mCustomNavView != null) {
1033 customView = mCustomNavView;
1034 }
1035
1036 if (customView != null) {
Adam Powell9a5cc282011-08-28 16:18:16 -07001037 final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams());
Adam Powell9ab97872010-10-26 21:47:29 -07001038 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1039 (ActionBar.LayoutParams) lp : null;
1040
1041 int horizontalMargin = 0;
1042 int verticalMargin = 0;
1043 if (ablp != null) {
1044 horizontalMargin = ablp.leftMargin + ablp.rightMargin;
1045 verticalMargin = ablp.topMargin + ablp.bottomMargin;
1046 }
1047
1048 // If the action bar is wrapping to its content height, don't allow a custom
1049 // view to MATCH_PARENT.
1050 int customNavHeightMode;
1051 if (mContentHeight <= 0) {
1052 customNavHeightMode = MeasureSpec.AT_MOST;
1053 } else {
1054 customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
1055 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
1056 }
1057 final int customNavHeight = Math.max(0,
1058 (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin);
1059
1060 final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
1061 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
1062 int customNavWidth = Math.max(0,
1063 (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth)
1064 - horizontalMargin);
1065 final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) &
1066 Gravity.HORIZONTAL_GRAVITY_MASK;
1067
1068 // Centering a custom view is treated specially; we try to center within the whole
1069 // action bar rather than in the available space.
1070 if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) {
1071 customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2;
1072 }
1073
Adam Powell8d02dea2011-05-31 21:35:13 -07001074 customView.measure(
Adam Powell9ab97872010-10-26 21:47:29 -07001075 MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
1076 MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
Adam Powellaa8e509b2011-08-25 09:29:21 -07001077 availableWidth -= horizontalMargin + customView.getMeasuredWidth();
1078 }
1079
Adam Powell27cba382013-01-22 18:55:20 -08001080 /*
1081 * Measure the whole up container now, allowing for the full home+title sections.
1082 * (This will re-measure the home view.)
1083 */
1084 availableWidth = measureChildView(mUpGoerFive, availableWidth + homeWidth,
1085 MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
1086 if (mTitleLayout != null) {
Adam Powellaa8e509b2011-08-25 09:29:21 -07001087 leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
Adam Powell9ab97872010-10-26 21:47:29 -07001088 }
1089
Adam Powelle2194442010-08-12 18:13:03 -07001090 if (mContentHeight <= 0) {
1091 int measuredHeight = 0;
Adam Powelld21aa122011-05-27 13:09:52 -07001092 for (int i = 0; i < childCount; i++) {
Adam Powelle2194442010-08-12 18:13:03 -07001093 View v = getChildAt(i);
1094 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
1095 if (paddedViewHeight > measuredHeight) {
1096 measuredHeight = paddedViewHeight;
1097 }
1098 }
1099 setMeasuredDimension(contentWidth, measuredHeight);
1100 } else {
1101 setMeasuredDimension(contentWidth, maxHeight);
1102 }
1103
1104 if (mContextView != null) {
Adam Powell425689e2011-09-08 18:09:33 -07001105 mContextView.setContentHeight(getMeasuredHeight());
Adam Powelle2194442010-08-12 18:13:03 -07001106 }
Adam Powell6af97e12010-11-11 21:11:53 -08001107
1108 if (mProgressView != null && mProgressView.getVisibility() != GONE) {
1109 mProgressView.measure(MeasureSpec.makeMeasureSpec(
1110 contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY),
1111 MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
1112 }
Adam Powell33b97432010-04-20 10:01:14 -07001113 }
1114
Adam Powell33b97432010-04-20 10:01:14 -07001115 @Override
1116 protected void onLayout(boolean changed, int l, int t, int r, int b) {
Adam Powell33b97432010-04-20 10:01:14 -07001117 final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
1118
Adam Powelld21aa122011-05-27 13:09:52 -07001119 if (contentHeight <= 0) {
1120 // Nothing to do if we can't see anything.
1121 return;
1122 }
1123
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001124 final boolean isLayoutRtl = isLayoutRtl();
Adam Powellad79b902013-06-19 11:33:28 -07001125 final int direction = isLayoutRtl ? 1 : -1;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001126 int menuStart = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
1127 // In LTR mode, we start from left padding and go to the right; in RTL mode, we start
1128 // from the padding right and go to the left (in reverse way)
1129 int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
1130 final int y = getPaddingTop();
1131
Adam Powellb1e2f252011-08-22 17:42:12 -07001132 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powellad79b902013-06-19 11:33:28 -07001133 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
1134 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
1135 int startOffset = 0;
1136 if (homeLayout.getParent() == mUpGoerFive) {
1137 if (homeLayout.getVisibility() != GONE) {
1138 startOffset = homeLayout.getStartOffset();
1139 } else if (showTitle) {
1140 startOffset = homeLayout.getUpWidth();
1141 }
1142 }
Adam Powell27cba382013-01-22 18:55:20 -08001143
1144 // Position the up container based on where the edge of the home layout should go.
1145 x += positionChild(mUpGoerFive,
1146 next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
1147 x = next(x, startOffset, isLayoutRtl);
Adam Powell9ab97872010-10-26 21:47:29 -07001148
Adam Powell8d02dea2011-05-31 21:35:13 -07001149 if (mExpandedActionView == null) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001150 switch (mNavigationMode) {
1151 case ActionBar.NAVIGATION_MODE_STANDARD:
1152 break;
1153 case ActionBar.NAVIGATION_MODE_LIST:
1154 if (mListNavLayout != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001155 if (showTitle) {
1156 x = next(x, mItemPadding, isLayoutRtl);
1157 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001158 x += positionChild(mListNavLayout, x, y, contentHeight, isLayoutRtl);
1159 x = next(x, mItemPadding, isLayoutRtl);
Adam Powell8d02dea2011-05-31 21:35:13 -07001160 }
1161 break;
1162 case ActionBar.NAVIGATION_MODE_TABS:
1163 if (mTabScrollView != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001164 if (showTitle) x = next(x, mItemPadding, isLayoutRtl);
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001165 x += positionChild(mTabScrollView, x, y, contentHeight, isLayoutRtl);
1166 x = next(x, mItemPadding, isLayoutRtl);
Adam Powell8d02dea2011-05-31 21:35:13 -07001167 }
1168 break;
Adam Powell661c9082010-07-02 10:09:44 -07001169 }
Adam Powell33b97432010-04-20 10:01:14 -07001170 }
1171
Adam Powell9b4bee02011-04-27 19:24:47 -07001172 if (mMenuView != null && mMenuView.getParent() == this) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001173 positionChild(mMenuView, menuStart, y, contentHeight, !isLayoutRtl);
1174 menuStart += direction * mMenuView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001175 }
1176
Adam Powell6af97e12010-11-11 21:11:53 -08001177 if (mIndeterminateProgressView != null &&
1178 mIndeterminateProgressView.getVisibility() != GONE) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001179 positionChild(mIndeterminateProgressView, menuStart, y, contentHeight, !isLayoutRtl);
1180 menuStart += direction * mIndeterminateProgressView.getMeasuredWidth();
Adam Powell6af97e12010-11-11 21:11:53 -08001181 }
1182
Adam Powell8d02dea2011-05-31 21:35:13 -07001183 View customView = null;
1184 if (mExpandedActionView != null) {
1185 customView = mExpandedActionView;
1186 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1187 mCustomNavView != null) {
1188 customView = mCustomNavView;
1189 }
1190 if (customView != null) {
Fabrice Di Meglio6bf6eb72012-10-10 15:30:28 -07001191 final int layoutDirection = getLayoutDirection();
Fabrice Di Megliobb4b6012012-10-26 16:27:55 -07001192 ViewGroup.LayoutParams lp = customView.getLayoutParams();
Adam Powell9ab97872010-10-26 21:47:29 -07001193 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1194 (ActionBar.LayoutParams) lp : null;
Adam Powell9ab97872010-10-26 21:47:29 -07001195 final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY;
Adam Powell8d02dea2011-05-31 21:35:13 -07001196 final int navWidth = customView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001197
1198 int topMargin = 0;
1199 int bottomMargin = 0;
1200 if (ablp != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001201 x = next(x, ablp.getMarginStart(), isLayoutRtl);
1202 menuStart += direction * ablp.getMarginEnd();
Adam Powell9ab97872010-10-26 21:47:29 -07001203 topMargin = ablp.topMargin;
1204 bottomMargin = ablp.bottomMargin;
1205 }
1206
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001207 int hgravity = gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
Adam Powell9ab97872010-10-26 21:47:29 -07001208 // See if we actually have room to truly center; if not push against left or right.
1209 if (hgravity == Gravity.CENTER_HORIZONTAL) {
1210 final int centeredLeft = ((mRight - mLeft) - navWidth) / 2;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001211 if (isLayoutRtl) {
1212 final int centeredStart = centeredLeft + navWidth;
1213 final int centeredEnd = centeredLeft;
1214 if (centeredStart > x) {
1215 hgravity = Gravity.RIGHT;
1216 } else if (centeredEnd < menuStart) {
1217 hgravity = Gravity.LEFT;
1218 }
1219 } else {
1220 final int centeredStart = centeredLeft;
1221 final int centeredEnd = centeredLeft + navWidth;
1222 if (centeredStart < x) {
1223 hgravity = Gravity.LEFT;
1224 } else if (centeredEnd > menuStart) {
1225 hgravity = Gravity.RIGHT;
1226 }
Adam Powell9ab97872010-10-26 21:47:29 -07001227 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001228 } else if (gravity == Gravity.NO_GRAVITY) {
1229 hgravity = Gravity.START;
Adam Powell9ab97872010-10-26 21:47:29 -07001230 }
1231
1232 int xpos = 0;
Fabrice Di Meglio6bf6eb72012-10-10 15:30:28 -07001233 switch (Gravity.getAbsoluteGravity(hgravity, layoutDirection)) {
Adam Powell9ab97872010-10-26 21:47:29 -07001234 case Gravity.CENTER_HORIZONTAL:
1235 xpos = ((mRight - mLeft) - navWidth) / 2;
1236 break;
1237 case Gravity.LEFT:
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001238 xpos = isLayoutRtl ? menuStart : x;
Adam Powell9ab97872010-10-26 21:47:29 -07001239 break;
1240 case Gravity.RIGHT:
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001241 xpos = isLayoutRtl ? x - navWidth : menuStart - navWidth;
Adam Powell9ab97872010-10-26 21:47:29 -07001242 break;
1243 }
1244
Adam Powell7a2424d2011-08-18 11:59:11 -07001245 int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
1246
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001247 if (gravity == Gravity.NO_GRAVITY) {
Adam Powell7a2424d2011-08-18 11:59:11 -07001248 vgravity = Gravity.CENTER_VERTICAL;
1249 }
1250
Adam Powell9ab97872010-10-26 21:47:29 -07001251 int ypos = 0;
Adam Powell7a2424d2011-08-18 11:59:11 -07001252 switch (vgravity) {
Adam Powell9ab97872010-10-26 21:47:29 -07001253 case Gravity.CENTER_VERTICAL:
Adam Powell6556c072011-06-24 17:16:57 -07001254 final int paddedTop = getPaddingTop();
1255 final int paddedBottom = mBottom - mTop - getPaddingBottom();
Adam Powell8d02dea2011-05-31 21:35:13 -07001256 ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2;
Adam Powell9ab97872010-10-26 21:47:29 -07001257 break;
1258 case Gravity.TOP:
1259 ypos = getPaddingTop() + topMargin;
1260 break;
1261 case Gravity.BOTTOM:
Adam Powell8d02dea2011-05-31 21:35:13 -07001262 ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight()
Adam Powell9ab97872010-10-26 21:47:29 -07001263 - bottomMargin;
1264 break;
1265 }
Adam Powell6556c072011-06-24 17:16:57 -07001266 final int customWidth = customView.getMeasuredWidth();
1267 customView.layout(xpos, ypos, xpos + customWidth,
1268 ypos + customView.getMeasuredHeight());
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001269 x = next(x, customWidth, isLayoutRtl);
Adam Powell33b97432010-04-20 10:01:14 -07001270 }
Adam Powell6af97e12010-11-11 21:11:53 -08001271
1272 if (mProgressView != null) {
1273 mProgressView.bringToFront();
1274 final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2;
1275 mProgressView.layout(mProgressBarPadding, -halfProgressHeight,
1276 mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight);
1277 }
Adam Powell33b97432010-04-20 10:01:14 -07001278 }
1279
Adam Powell8d02dea2011-05-31 21:35:13 -07001280 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001281 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
Adam Powellaad47fd2011-08-17 17:33:33 -07001282 return new ActionBar.LayoutParams(getContext(), attrs);
1283 }
1284
1285 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001286 public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001287 if (lp == null) {
1288 lp = generateDefaultLayoutParams();
1289 }
1290 return lp;
1291 }
1292
1293 @Override
1294 public Parcelable onSaveInstanceState() {
1295 Parcelable superState = super.onSaveInstanceState();
1296 SavedState state = new SavedState(superState);
1297
1298 if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
1299 state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
1300 }
1301
1302 state.isOverflowOpen = isOverflowMenuShowing();
1303
1304 return state;
1305 }
1306
1307 @Override
1308 public void onRestoreInstanceState(Parcelable p) {
1309 SavedState state = (SavedState) p;
1310
1311 super.onRestoreInstanceState(state.getSuperState());
1312
1313 if (state.expandedMenuItemId != 0 &&
1314 mExpandedMenuPresenter != null && mOptionsMenu != null) {
1315 final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId);
1316 if (item != null) {
1317 item.expandActionView();
1318 }
1319 }
1320
1321 if (state.isOverflowOpen) {
1322 postShowOverflowMenu();
1323 }
1324 }
1325
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001326 public void setHomeAsUpIndicator(Drawable indicator) {
1327 mHomeLayout.setUpIndicator(indicator);
1328 }
1329
1330 public void setHomeAsUpIndicator(int resId) {
1331 mHomeLayout.setUpIndicator(resId);
1332 }
1333
1334 public void setHomeActionContentDescription(CharSequence description) {
1335 mHomeDescription = description;
Adam Powell2229ca02013-11-12 16:20:46 -08001336 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001337 }
1338
1339 public void setHomeActionContentDescription(int resId) {
1340 mHomeDescriptionRes = resId;
Adam Powell2eeb4192013-04-18 13:53:27 -07001341 mHomeDescription = resId != 0 ? getResources().getText(resId) : null;
Adam Powell2229ca02013-11-12 16:20:46 -08001342 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001343 }
1344
Adam Powell8d02dea2011-05-31 21:35:13 -07001345 static class SavedState extends BaseSavedState {
1346 int expandedMenuItemId;
1347 boolean isOverflowOpen;
1348
1349 SavedState(Parcelable superState) {
1350 super(superState);
1351 }
1352
1353 private SavedState(Parcel in) {
1354 super(in);
1355 expandedMenuItemId = in.readInt();
1356 isOverflowOpen = in.readInt() != 0;
1357 }
1358
1359 @Override
1360 public void writeToParcel(Parcel out, int flags) {
1361 super.writeToParcel(out, flags);
1362 out.writeInt(expandedMenuItemId);
1363 out.writeInt(isOverflowOpen ? 1 : 0);
1364 }
1365
1366 public static final Parcelable.Creator<SavedState> CREATOR =
1367 new Parcelable.Creator<SavedState>() {
1368 public SavedState createFromParcel(Parcel in) {
1369 return new SavedState(in);
1370 }
1371
1372 public SavedState[] newArray(int size) {
1373 return new SavedState[size];
1374 }
1375 };
1376 }
1377
Adam Powell2b0952b2011-03-09 00:15:38 -08001378 private static class HomeView extends FrameLayout {
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001379 private ImageView mUpView;
Adam Powell8d02dea2011-05-31 21:35:13 -07001380 private ImageView mIconView;
Adam Powellb1e2f252011-08-22 17:42:12 -07001381 private int mUpWidth;
Adam Powellad79b902013-06-19 11:33:28 -07001382 private int mStartOffset;
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001383 private int mUpIndicatorRes;
1384 private Drawable mDefaultUpIndicator;
Adam Powell2b0952b2011-03-09 00:15:38 -08001385
Adam Powellfd75eef2012-08-02 10:27:31 -07001386 private static final long DEFAULT_TRANSITION_DURATION = 150;
1387
Adam Powell2b0952b2011-03-09 00:15:38 -08001388 public HomeView(Context context) {
1389 this(context, null);
1390 }
1391
1392 public HomeView(Context context, AttributeSet attrs) {
1393 super(context, attrs);
Adam Powellfd75eef2012-08-02 10:27:31 -07001394 LayoutTransition t = getLayoutTransition();
1395 if (t != null) {
1396 // Set a lower duration than the default
1397 t.setDuration(DEFAULT_TRANSITION_DURATION);
1398 }
Adam Powell2b0952b2011-03-09 00:15:38 -08001399 }
1400
Adam Powellad79b902013-06-19 11:33:28 -07001401 public void setShowUp(boolean isUp) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001402 mUpView.setVisibility(isUp ? VISIBLE : GONE);
1403 }
1404
Adam Powellad79b902013-06-19 11:33:28 -07001405 public void setShowIcon(boolean showIcon) {
1406 mIconView.setVisibility(showIcon ? VISIBLE : GONE);
1407 }
1408
Adam Powell8d02dea2011-05-31 21:35:13 -07001409 public void setIcon(Drawable icon) {
1410 mIconView.setImageDrawable(icon);
1411 }
1412
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001413 public void setUpIndicator(Drawable d) {
1414 mUpView.setImageDrawable(d != null ? d : mDefaultUpIndicator);
1415 mUpIndicatorRes = 0;
1416 }
1417
1418 public void setUpIndicator(int resId) {
1419 mUpIndicatorRes = resId;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001420 mUpView.setImageDrawable(resId != 0 ? getContext().getDrawable(resId) : null);
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001421 }
1422
1423 @Override
1424 protected void onConfigurationChanged(Configuration newConfig) {
1425 super.onConfigurationChanged(newConfig);
1426 if (mUpIndicatorRes != 0) {
1427 // Reload for config change
1428 setUpIndicator(mUpIndicatorRes);
1429 }
1430 }
1431
Adam Powell2b0952b2011-03-09 00:15:38 -08001432 @Override
Adam Powell7bc3ca02011-08-26 18:29:58 -07001433 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
1434 onPopulateAccessibilityEvent(event);
1435 return true;
1436 }
1437
1438 @Override
1439 public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1440 super.onPopulateAccessibilityEvent(event);
1441 final CharSequence cdesc = getContentDescription();
1442 if (!TextUtils.isEmpty(cdesc)) {
1443 event.getText().add(cdesc);
1444 }
1445 }
1446
1447 @Override
1448 public boolean dispatchHoverEvent(MotionEvent event) {
1449 // Don't allow children to hover; we want this to be treated as a single component.
1450 return onHoverEvent(event);
1451 }
1452
1453 @Override
Adam Powell2b0952b2011-03-09 00:15:38 -08001454 protected void onFinishInflate() {
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001455 mUpView = (ImageView) findViewById(com.android.internal.R.id.up);
Adam Powell2b0952b2011-03-09 00:15:38 -08001456 mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001457 mDefaultUpIndicator = mUpView.getDrawable();
Adam Powell2b0952b2011-03-09 00:15:38 -08001458 }
1459
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001460 public int getStartOffset() {
Adam Powellad79b902013-06-19 11:33:28 -07001461 return mUpView.getVisibility() == GONE ? mStartOffset : 0;
1462 }
1463
1464 public int getUpWidth() {
1465 return mUpWidth;
Adam Powell8d02dea2011-05-31 21:35:13 -07001466 }
1467
Adam Powell2b0952b2011-03-09 00:15:38 -08001468 @Override
1469 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1470 measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
1471 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
Adam Powellad79b902013-06-19 11:33:28 -07001472 final int upMargins = upLp.leftMargin + upLp.rightMargin;
1473 mUpWidth = mUpView.getMeasuredWidth();
1474 mStartOffset = mUpWidth + upMargins;
1475 int width = mUpView.getVisibility() == GONE ? 0 : mStartOffset;
Adam Powell2b0952b2011-03-09 00:15:38 -08001476 int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
Adam Powellad79b902013-06-19 11:33:28 -07001477
1478 if (mIconView.getVisibility() != GONE) {
1479 measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
1480 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1481 width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
1482 height = Math.max(height,
1483 iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
1484 } else if (upMargins < 0) {
1485 // Remove the measurement effects of negative margins used for offsets
1486 width -= upMargins;
1487 }
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) {
Chet Haased8d7c382013-09-23 11:26:36 -07001629 ActionBarTransition.beginDelayedTransition(ActionBarView.this);
Adam Powellc46d3332013-09-17 10:08:41 -07001630
Adam Powell8d02dea2011-05-31 21:35:13 -07001631 mExpandedActionView = item.getActionView();
Adam Powell28fa07e2011-07-15 20:17:25 -07001632 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
Adam Powell8d02dea2011-05-31 21:35:13 -07001633 mCurrentExpandedItem = item;
1634 if (mExpandedActionView.getParent() != ActionBarView.this) {
1635 addView(mExpandedActionView);
1636 }
Adam Powell27cba382013-01-22 18:55:20 -08001637 if (mExpandedHomeLayout.getParent() != mUpGoerFive) {
1638 mUpGoerFive.addView(mExpandedHomeLayout);
Adam Powell8d02dea2011-05-31 21:35:13 -07001639 }
1640 mHomeLayout.setVisibility(GONE);
Adam Powell15a16a82011-06-20 10:35:27 -07001641 if (mTitleLayout != null) mTitleLayout.setVisibility(GONE);
Adam Powell8d02dea2011-05-31 21:35:13 -07001642 if (mTabScrollView != null) mTabScrollView.setVisibility(GONE);
1643 if (mSpinner != null) mSpinner.setVisibility(GONE);
1644 if (mCustomNavView != null) mCustomNavView.setVisibility(GONE);
Adam Powell07cf9712013-02-05 16:13:57 -08001645 setHomeButtonEnabled(false, false);
Adam Powell8d02dea2011-05-31 21:35:13 -07001646 requestLayout();
1647 item.setActionViewExpanded(true);
Adam Powell038f1c82011-07-21 14:28:10 -07001648
1649 if (mExpandedActionView instanceof CollapsibleActionView) {
1650 ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
1651 }
Amith Yamasani10da5902011-07-26 16:14:26 -07001652
Adam Powell8d02dea2011-05-31 21:35:13 -07001653 return true;
1654 }
1655
1656 @Override
1657 public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
Chet Haased8d7c382013-09-23 11:26:36 -07001658 ActionBarTransition.beginDelayedTransition(ActionBarView.this);
Adam Powellc46d3332013-09-17 10:08:41 -07001659
Amith Yamasani10da5902011-07-26 16:14:26 -07001660 // Do this before detaching the actionview from the hierarchy, in case
1661 // it needs to dismiss the soft keyboard, etc.
1662 if (mExpandedActionView instanceof CollapsibleActionView) {
1663 ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
1664 }
1665
Adam Powell8d02dea2011-05-31 21:35:13 -07001666 removeView(mExpandedActionView);
Adam Powell27cba382013-01-22 18:55:20 -08001667 mUpGoerFive.removeView(mExpandedHomeLayout);
Adam Powellb0e217e2011-08-12 11:36:51 -07001668 mExpandedActionView = null;
Adam Powell8d02dea2011-05-31 21:35:13 -07001669 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
1670 mHomeLayout.setVisibility(VISIBLE);
1671 }
1672 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
Adam Powell15a16a82011-06-20 10:35:27 -07001673 if (mTitleLayout == null) {
1674 initTitle();
1675 } else {
1676 mTitleLayout.setVisibility(VISIBLE);
1677 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001678 }
Adam Powell6684e922013-03-26 15:38:26 -07001679 if (mTabScrollView != null) mTabScrollView.setVisibility(VISIBLE);
1680 if (mSpinner != null) mSpinner.setVisibility(VISIBLE);
1681 if (mCustomNavView != null) mCustomNavView.setVisibility(VISIBLE);
1682
Adam Powell8d02dea2011-05-31 21:35:13 -07001683 mExpandedHomeLayout.setIcon(null);
1684 mCurrentExpandedItem = null;
Adam Powell62f33032013-02-04 12:44:34 -08001685 setHomeButtonEnabled(mWasHomeEnabled); // Set by expandItemActionView above
Adam Powell8d02dea2011-05-31 21:35:13 -07001686 requestLayout();
1687 item.setActionViewExpanded(false);
Adam Powell038f1c82011-07-21 14:28:10 -07001688
Adam Powell8d02dea2011-05-31 21:35:13 -07001689 return true;
1690 }
Adam Powell11ed1d62011-07-11 21:19:59 -07001691
1692 @Override
1693 public int getId() {
1694 return 0;
1695 }
1696
1697 @Override
1698 public Parcelable onSaveInstanceState() {
1699 return null;
1700 }
1701
1702 @Override
1703 public void onRestoreInstanceState(Parcelable state) {
1704 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001705 }
Adam Powell33b97432010-04-20 10:01:14 -07001706}