blob: 786f5cfa2e5c5f36636297317038b564e33c8ede [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 Powella4082912010-06-04 18:34:02 -070044import android.widget.AdapterView;
Adam Powell2b0952b2011-03-09 00:15:38 -080045import android.widget.FrameLayout;
Adam Powell33b97432010-04-20 10:01:14 -070046import android.widget.ImageView;
Adam Powell0e94b512010-06-29 17:58:20 -070047import android.widget.LinearLayout;
Adam Powell6af97e12010-11-11 21:11:53 -080048import android.widget.ProgressBar;
Adam Powella4082912010-06-04 18:34:02 -070049import android.widget.Spinner;
50import android.widget.SpinnerAdapter;
Adam Powell33b97432010-04-20 10:01:14 -070051import android.widget.TextView;
Adam Powell04fe6eb2013-05-31 14:39:48 -070052import com.android.internal.R;
Adam Powellad79b902013-06-19 11:33:28 -070053import com.android.internal.transition.ActionBarTransition;
Adam Powell04fe6eb2013-05-31 14:39:48 -070054import com.android.internal.view.menu.ActionMenuItem;
55import com.android.internal.view.menu.ActionMenuPresenter;
56import com.android.internal.view.menu.ActionMenuView;
57import 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 Powellf35d0492011-08-17 13:56:47 -0700433 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700434 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell9b4bee02011-04-27 19:24:47 -0700435 if (mSplitView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700436 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
437 if (oldParent != null && oldParent != mSplitView) {
438 oldParent.removeView(menuView);
439 }
Adam Powell9a5cc282011-08-28 16:18:16 -0700440 menuView.setVisibility(getAnimatedVisibility());
Adam Powell1ab418a2011-06-09 20:49:49 -0700441 mSplitView.addView(menuView, layoutParams);
442 } else {
443 // We'll add this later if we missed it this time.
444 menuView.setLayoutParams(layoutParams);
445 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700446 }
Adam Powell96675b12010-06-10 18:58:59 -0700447 mMenuView = menuView;
Adam Powell33b97432010-04-20 10:01:14 -0700448 }
Adam Powella7db0372010-06-30 17:08:47 -0700449
Adam Powellf35d0492011-08-17 13:56:47 -0700450 private void configPresenters(MenuBuilder builder) {
451 if (builder != null) {
452 builder.addMenuPresenter(mActionMenuPresenter);
453 builder.addMenuPresenter(mExpandedMenuPresenter);
454 } else {
455 mActionMenuPresenter.initForMenu(mContext, null);
456 mExpandedMenuPresenter.initForMenu(mContext, null);
457 mActionMenuPresenter.updateMenuView(true);
458 mExpandedMenuPresenter.updateMenuView(true);
459 }
460 }
461
Adam Powellb80d3322011-07-15 21:33:11 -0700462 public boolean hasExpandedActionView() {
463 return mExpandedMenuPresenter != null &&
464 mExpandedMenuPresenter.mCurrentExpandedItem != null;
465 }
466
467 public void collapseActionView() {
468 final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
469 mExpandedMenuPresenter.mCurrentExpandedItem;
470 if (item != null) {
471 item.collapseActionView();
472 }
473 }
474
Adam Powell33b97432010-04-20 10:01:14 -0700475 public void setCustomNavigationView(View view) {
Adam Powell9ab97872010-10-26 21:47:29 -0700476 final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
Adam Powellad79b902013-06-19 11:33:28 -0700477 if (showCustom) {
Chet Haased8d7c382013-09-23 11:26:36 -0700478 ActionBarTransition.beginDelayedTransition(this);
Adam Powellad79b902013-06-19 11:33:28 -0700479 }
Adam Powell9ab97872010-10-26 21:47:29 -0700480 if (mCustomNavView != null && showCustom) {
481 removeView(mCustomNavView);
482 }
Adam Powella4082912010-06-04 18:34:02 -0700483 mCustomNavView = view;
Adam Powell9ab97872010-10-26 21:47:29 -0700484 if (mCustomNavView != null && showCustom) {
485 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700486 }
Adam Powell33b97432010-04-20 10:01:14 -0700487 }
Adam Powella7db0372010-06-30 17:08:47 -0700488
Adam Powell33b97432010-04-20 10:01:14 -0700489 public CharSequence getTitle() {
490 return mTitle;
491 }
Adam Powella7db0372010-06-30 17:08:47 -0700492
Adam Powelle92ea342010-07-14 14:45:50 -0700493 /**
494 * Set the action bar title. This will always replace or override window titles.
495 * @param title Title to set
496 *
497 * @see #setWindowTitle(CharSequence)
498 */
Adam Powell33b97432010-04-20 10:01:14 -0700499 public void setTitle(CharSequence title) {
Adam Powelle92ea342010-07-14 14:45:50 -0700500 mUserTitle = true;
501 setTitleImpl(title);
502 }
503
504 /**
505 * Set the window title. A window title will always be replaced or overridden by a user title.
506 * @param title Title to set
507 *
508 * @see #setTitle(CharSequence)
509 */
510 public void setWindowTitle(CharSequence title) {
511 if (!mUserTitle) {
512 setTitleImpl(title);
513 }
514 }
515
516 private void setTitleImpl(CharSequence title) {
Chet Haased8d7c382013-09-23 11:26:36 -0700517 ActionBarTransition.beginDelayedTransition(this);
Adam Powell33b97432010-04-20 10:01:14 -0700518 mTitle = title;
519 if (mTitleView != null) {
520 mTitleView.setText(title);
Adam Powellb0e217e2011-08-12 11:36:51 -0700521 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700522 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700523 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
524 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700525 }
526 if (mLogoNavItem != null) {
527 mLogoNavItem.setTitle(title);
528 }
Adam Powell2229ca02013-11-12 16:20:46 -0800529 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powell33b97432010-04-20 10:01:14 -0700530 }
Adam Powella7db0372010-06-30 17:08:47 -0700531
Adam Powell33b97432010-04-20 10:01:14 -0700532 public CharSequence getSubtitle() {
533 return mSubtitle;
534 }
Adam Powella7db0372010-06-30 17:08:47 -0700535
Adam Powell33b97432010-04-20 10:01:14 -0700536 public void setSubtitle(CharSequence subtitle) {
Chet Haased8d7c382013-09-23 11:26:36 -0700537 ActionBarTransition.beginDelayedTransition(this);
Adam Powell33b97432010-04-20 10:01:14 -0700538 mSubtitle = subtitle;
539 if (mSubtitleView != null) {
540 mSubtitleView.setText(subtitle);
Adam Powell04587962010-11-11 22:15:07 -0800541 mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE);
Adam Powellb0e217e2011-08-12 11:36:51 -0700542 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700543 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700544 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
545 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700546 }
Adam Powell2229ca02013-11-12 16:20:46 -0800547 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powell33b97432010-04-20 10:01:14 -0700548 }
Adam Powella7db0372010-06-30 17:08:47 -0700549
Adam Powellc29f4e52011-07-13 20:40:52 -0700550 public void setHomeButtonEnabled(boolean enable) {
Adam Powell07cf9712013-02-05 16:13:57 -0800551 setHomeButtonEnabled(enable, true);
552 }
553
554 private void setHomeButtonEnabled(boolean enable, boolean recordState) {
555 if (recordState) {
556 mWasHomeEnabled = enable;
557 }
558
559 if (mExpandedActionView != null) {
560 // There's an action view currently showing and we want to keep the state
561 // configured for the action view at the moment. If we needed to record the
562 // new state for later we will have done so above.
563 return;
564 }
565
Adam Powell27cba382013-01-22 18:55:20 -0800566 mUpGoerFive.setEnabled(enable);
567 mUpGoerFive.setFocusable(enable);
Adam Powellc29f4e52011-07-13 20:40:52 -0700568 // Make sure the home button has an accurate content description for accessibility.
Adam Powellf37a5132013-11-01 16:32:37 -0700569 updateHomeAccessibility(enable);
570 }
571
572 private void updateHomeAccessibility(boolean homeEnabled) {
573 if (!homeEnabled) {
Adam Powell27cba382013-01-22 18:55:20 -0800574 mUpGoerFive.setContentDescription(null);
575 mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
Adam Powellc29f4e52011-07-13 20:40:52 -0700576 } else {
Adam Powell27cba382013-01-22 18:55:20 -0800577 mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700578 mUpGoerFive.setContentDescription(buildHomeContentDescription());
579 }
580 }
581
582 /**
583 * Compose a content description for the Home/Up affordance.
584 *
585 * <p>As this encompasses the icon/logo, title and subtitle all in one, we need
586 * a description for the whole wad of stuff that can be localized properly.</p>
587 */
588 private CharSequence buildHomeContentDescription() {
589 final CharSequence homeDesc;
590 if (mHomeDescription != null) {
591 homeDesc = mHomeDescription;
592 } else {
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700593 if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700594 homeDesc = mContext.getResources().getText(R.string.action_bar_up_description);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700595 } else {
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700596 homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
Casey Burkhardt4aeb9612012-10-01 14:13:41 -0700597 }
Adam Powellc29f4e52011-07-13 20:40:52 -0700598 }
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700599
600 final CharSequence title = getTitle();
601 final CharSequence subtitle = getSubtitle();
602 if (!TextUtils.isEmpty(title)) {
603 final String result;
604 if (!TextUtils.isEmpty(subtitle)) {
605 result = getResources().getString(
606 R.string.action_bar_home_subtitle_description_format,
607 title, subtitle, homeDesc);
608 } else {
609 result = getResources().getString(R.string.action_bar_home_description_format,
610 title, homeDesc);
611 }
612 return result;
613 }
614 return homeDesc;
Adam Powellc29f4e52011-07-13 20:40:52 -0700615 }
616
Adam Powell33b97432010-04-20 10:01:14 -0700617 public void setDisplayOptions(int options) {
Adam Powell82f24e82011-08-18 20:15:20 -0700618 final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions;
Adam Powell33b97432010-04-20 10:01:14 -0700619 mDisplayOptions = options;
Adam Powelldae78242011-04-25 15:23:41 -0700620
Adam Powell33b97432010-04-20 10:01:14 -0700621 if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
Chet Haased8d7c382013-09-23 11:26:36 -0700622 ActionBarTransition.beginDelayedTransition(this);
Adam Powell9ab97872010-10-26 21:47:29 -0700623
624 if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powellc29f4e52011-07-13 20:40:52 -0700625 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
Adam Powellad79b902013-06-19 11:33:28 -0700626 mHomeLayout.setShowUp(setUp);
Adam Powellc29f4e52011-07-13 20:40:52 -0700627
628 // Showing home as up implicitly enables interaction with it.
629 // In honeycomb it was always enabled, so make this transition
630 // a bit easier for developers in the common case.
631 // (It would be silly to show it as up without responding to it.)
632 if (setUp) {
633 setHomeButtonEnabled(true);
634 }
Adam Powella1700782010-05-13 13:27:35 -0700635 }
Adam Powell9ab97872010-10-26 21:47:29 -0700636
Ed Heyl1c603002010-11-18 12:18:23 -0800637 if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
638 final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0;
Adam Powell8d02dea2011-05-31 21:35:13 -0700639 mHomeLayout.setIcon(logoVis ? mLogo : mIcon);
Adam Powell9ab97872010-10-26 21:47:29 -0700640 }
641
642 if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
643 if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
644 initTitle();
645 } else {
Adam Powell27cba382013-01-22 18:55:20 -0800646 mUpGoerFive.removeView(mTitleLayout);
Adam Powell9ab97872010-10-26 21:47:29 -0700647 }
648 }
649
Adam Powellad79b902013-06-19 11:33:28 -0700650 final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
651 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
652 final boolean titleUp = !showHome && homeAsUp;
653 mHomeLayout.setShowIcon(showHome);
654
655 final int homeVis = (showHome || titleUp) && mExpandedActionView == null ?
656 VISIBLE : GONE;
657 mHomeLayout.setVisibility(homeVis);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700658
Adam Powell9ab97872010-10-26 21:47:29 -0700659 if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
660 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
661 addView(mCustomNavView);
662 } else {
663 removeView(mCustomNavView);
664 }
Adam Powella1700782010-05-13 13:27:35 -0700665 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700666
Adam Powell27cba382013-01-22 18:55:20 -0800667 if (mTitleLayout != null &&
668 (flagsChanged & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
669 if ((options & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
670 mTitleView.setSingleLine(false);
671 mTitleView.setMaxLines(2);
672 } else {
673 mTitleView.setMaxLines(1);
674 mTitleView.setSingleLine(true);
675 }
676 }
677
Adam Powell33b97432010-04-20 10:01:14 -0700678 requestLayout();
679 } else {
680 invalidate();
681 }
Adam Powellf3cd1d92011-04-26 17:31:52 -0700682
683 // Make sure the home button has an accurate content description for accessibility.
Adam Powell2229ca02013-11-12 16:20:46 -0800684 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powell33b97432010-04-20 10:01:14 -0700685 }
686
Adam Powell1969b872011-03-22 11:52:48 -0700687 public void setIcon(Drawable icon) {
688 mIcon = icon;
689 if (icon != null &&
690 ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700691 mHomeLayout.setIcon(icon);
Adam Powell1969b872011-03-22 11:52:48 -0700692 }
Adam Powellf8218192012-02-21 17:10:10 -0800693 if (mExpandedActionView != null) {
694 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
695 }
Adam Powell1969b872011-03-22 11:52:48 -0700696 }
697
Adam Powell45c515b2011-04-21 18:50:20 -0700698 public void setIcon(int resId) {
Adam Powell04fe6eb2013-05-31 14:39:48 -0700699 setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
700 }
701
702 public boolean hasIcon() {
703 return mIcon != null;
Adam Powell45c515b2011-04-21 18:50:20 -0700704 }
705
Adam Powell1969b872011-03-22 11:52:48 -0700706 public void setLogo(Drawable logo) {
707 mLogo = logo;
708 if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700709 mHomeLayout.setIcon(logo);
Adam Powell1969b872011-03-22 11:52:48 -0700710 }
711 }
712
Adam Powell45c515b2011-04-21 18:50:20 -0700713 public void setLogo(int resId) {
Adam Powell04fe6eb2013-05-31 14:39:48 -0700714 setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
715 }
716
717 public boolean hasLogo() {
718 return mLogo != null;
Adam Powell45c515b2011-04-21 18:50:20 -0700719 }
720
Adam Powell33b97432010-04-20 10:01:14 -0700721 public void setNavigationMode(int mode) {
Adam Powella1700782010-05-13 13:27:35 -0700722 final int oldMode = mNavigationMode;
723 if (mode != oldMode) {
Chet Haased8d7c382013-09-23 11:26:36 -0700724 ActionBarTransition.beginDelayedTransition(this);
Adam Powella1700782010-05-13 13:27:35 -0700725 switch (oldMode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700726 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powellc3076422011-06-01 18:19:04 -0700727 if (mListNavLayout != null) {
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800728 removeView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700729 }
730 break;
Adam Powell661c9082010-07-02 10:09:44 -0700731 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700732 if (mTabScrollView != null && mIncludeTabs) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700733 removeView(mTabScrollView);
Adam Powell661c9082010-07-02 10:09:44 -0700734 }
Adam Powella1700782010-05-13 13:27:35 -0700735 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700736
Adam Powella1700782010-05-13 13:27:35 -0700737 switch (mode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700738 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800739 if (mSpinner == null) {
740 mSpinner = new Spinner(mContext, null,
741 com.android.internal.R.attr.actionDropDownStyle);
Adam Powell29c04ef2012-12-10 15:42:22 -0800742 mSpinner.setId(com.android.internal.R.id.action_bar_spinner);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800743 mListNavLayout = new LinearLayout(mContext, null,
744 com.android.internal.R.attr.actionBarTabBarStyle);
745 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
Adam Powelle7d46842011-01-13 21:36:09 -0800746 LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800747 params.gravity = Gravity.CENTER;
748 mListNavLayout.addView(mSpinner, params);
749 }
750 if (mSpinner.getAdapter() != mSpinnerAdapter) {
751 mSpinner.setAdapter(mSpinnerAdapter);
752 }
Adam Powella4082912010-06-04 18:34:02 -0700753 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800754 addView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700755 break;
Adam Powell661c9082010-07-02 10:09:44 -0700756 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700757 if (mTabScrollView != null && mIncludeTabs) {
Adam Powelldae78242011-04-25 15:23:41 -0700758 addView(mTabScrollView);
759 }
Adam Powell661c9082010-07-02 10:09:44 -0700760 break;
Adam Powella1700782010-05-13 13:27:35 -0700761 }
Adam Powell33b97432010-04-20 10:01:14 -0700762 mNavigationMode = mode;
763 requestLayout();
764 }
765 }
Adam Powelldae78242011-04-25 15:23:41 -0700766
Adam Powella4082912010-06-04 18:34:02 -0700767 public void setDropdownAdapter(SpinnerAdapter adapter) {
Adam Powell9ab97872010-10-26 21:47:29 -0700768 mSpinnerAdapter = adapter;
769 if (mSpinner != null) {
770 mSpinner.setAdapter(adapter);
771 }
772 }
773
774 public SpinnerAdapter getDropdownAdapter() {
775 return mSpinnerAdapter;
Adam Powella4082912010-06-04 18:34:02 -0700776 }
Adam Powell17809772010-07-21 13:25:11 -0700777
778 public void setDropdownSelectedPosition(int position) {
779 mSpinner.setSelection(position);
780 }
781
782 public int getDropdownSelectedPosition() {
783 return mSpinner.getSelectedItemPosition();
784 }
785
Adam Powell33b97432010-04-20 10:01:14 -0700786 public View getCustomNavigationView() {
Adam Powella4082912010-06-04 18:34:02 -0700787 return mCustomNavView;
Adam Powell33b97432010-04-20 10:01:14 -0700788 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700789
Adam Powell33b97432010-04-20 10:01:14 -0700790 public int getNavigationMode() {
791 return mNavigationMode;
792 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700793
Adam Powell33b97432010-04-20 10:01:14 -0700794 public int getDisplayOptions() {
795 return mDisplayOptions;
796 }
Adam Powella7db0372010-06-30 17:08:47 -0700797
798 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -0700799 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
Adam Powella7db0372010-06-30 17:08:47 -0700800 // Used by custom nav views if they don't supply layout params. Everything else
801 // added to an ActionBarView should have them already.
Adam Powell9ab97872010-10-26 21:47:29 -0700802 return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY);
Adam Powella7db0372010-06-30 17:08:47 -0700803 }
804
Adam Powell33b97432010-04-20 10:01:14 -0700805 @Override
806 protected void onFinishInflate() {
807 super.onFinishInflate();
808
Adam Powell27cba382013-01-22 18:55:20 -0800809 mUpGoerFive.addView(mHomeLayout, 0);
810 addView(mUpGoerFive);
Adam Powell9ab97872010-10-26 21:47:29 -0700811
Adam Powell9ab97872010-10-26 21:47:29 -0700812 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
813 final ViewParent parent = mCustomNavView.getParent();
814 if (parent != this) {
815 if (parent instanceof ViewGroup) {
816 ((ViewGroup) parent).removeView(mCustomNavView);
817 }
Adam Powella4082912010-06-04 18:34:02 -0700818 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700819 }
Adam Powell33b97432010-04-20 10:01:14 -0700820 }
821 }
Adam Powellc8b0b002011-06-23 14:39:05 -0700822
Adam Powella1700782010-05-13 13:27:35 -0700823 private void initTitle() {
Adam Powell15a16a82011-06-20 10:35:27 -0700824 if (mTitleLayout == null) {
825 LayoutInflater inflater = LayoutInflater.from(getContext());
Adam Powell9e58df52011-08-15 17:06:49 -0700826 mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item,
827 this, false);
Adam Powell15a16a82011-06-20 10:35:27 -0700828 mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
829 mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700830
Adam Powell15a16a82011-06-20 10:35:27 -0700831 if (mTitleStyleRes != 0) {
832 mTitleView.setTextAppearance(mContext, mTitleStyleRes);
833 }
834 if (mTitle != null) {
835 mTitleView.setText(mTitle);
836 }
Adam Powelle2194442010-08-12 18:13:03 -0700837
Adam Powell15a16a82011-06-20 10:35:27 -0700838 if (mSubtitleStyleRes != 0) {
839 mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
840 }
841 if (mSubtitle != null) {
842 mSubtitleView.setText(mSubtitle);
843 mSubtitleView.setVisibility(VISIBLE);
844 }
Adam Powell0e94b512010-06-29 17:58:20 -0700845 }
Adam Powelle2194442010-08-12 18:13:03 -0700846
Chet Haased8d7c382013-09-23 11:26:36 -0700847 ActionBarTransition.beginDelayedTransition(this);
Adam Powell27cba382013-01-22 18:55:20 -0800848 mUpGoerFive.addView(mTitleLayout);
Adam Powell82f24e82011-08-18 20:15:20 -0700849 if (mExpandedActionView != null ||
850 (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
851 // Don't show while in expanded mode or with empty text
Adam Powell71f34172011-08-11 20:07:11 -0700852 mTitleLayout.setVisibility(GONE);
Adam Powell6684e922013-03-26 15:38:26 -0700853 } else {
854 mTitleLayout.setVisibility(VISIBLE);
Adam Powell71f34172011-08-11 20:07:11 -0700855 }
Adam Powella1700782010-05-13 13:27:35 -0700856 }
Adam Powell33b97432010-04-20 10:01:14 -0700857
Adam Powelle2194442010-08-12 18:13:03 -0700858 public void setContextView(ActionBarContextView view) {
859 mContextView = view;
860 }
861
Adam Powelld21aa122011-05-27 13:09:52 -0700862 public void setCollapsable(boolean collapsable) {
863 mIsCollapsable = collapsable;
864 }
865
Adam Powellf6ce6a92011-06-29 10:25:01 -0700866 public boolean isCollapsed() {
867 return mIsCollapsed;
868 }
869
Adam Powell27cba382013-01-22 18:55:20 -0800870 /**
871 * @return True if any characters in the title were truncated
872 */
873 public boolean isTitleTruncated() {
874 if (mTitleView == null) {
875 return false;
876 }
877
878 final Layout titleLayout = mTitleView.getLayout();
879 if (titleLayout == null) {
880 return false;
881 }
882
883 final int lineCount = titleLayout.getLineCount();
884 for (int i = 0; i < lineCount; i++) {
885 if (titleLayout.getEllipsisCount(i) > 0) {
886 return true;
887 }
888 }
889 return false;
890 }
891
Adam Powell33b97432010-04-20 10:01:14 -0700892 @Override
893 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Adam Powelld21aa122011-05-27 13:09:52 -0700894 final int childCount = getChildCount();
895 if (mIsCollapsable) {
896 int visibleChildren = 0;
897 for (int i = 0; i < childCount; i++) {
898 final View child = getChildAt(i);
899 if (child.getVisibility() != GONE &&
Adam Powell27cba382013-01-22 18:55:20 -0800900 !(child == mMenuView && mMenuView.getChildCount() == 0) &&
901 child != mUpGoerFive) {
902 visibleChildren++;
903 }
904 }
905
906 final int upChildCount = mUpGoerFive.getChildCount();
907 for (int i = 0; i < upChildCount; i++) {
908 final View child = mUpGoerFive.getChildAt(i);
909 if (child.getVisibility() != GONE) {
Adam Powelld21aa122011-05-27 13:09:52 -0700910 visibleChildren++;
911 }
912 }
913
914 if (visibleChildren == 0) {
915 // No size for an empty action bar when collapsable.
916 setMeasuredDimension(0, 0);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700917 mIsCollapsed = true;
Adam Powelld21aa122011-05-27 13:09:52 -0700918 return;
919 }
920 }
Adam Powellf6ce6a92011-06-29 10:25:01 -0700921 mIsCollapsed = false;
Adam Powelld21aa122011-05-27 13:09:52 -0700922
Adam Powell33b97432010-04-20 10:01:14 -0700923 int widthMode = MeasureSpec.getMode(widthMeasureSpec);
924 if (widthMode != MeasureSpec.EXACTLY) {
925 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
926 "with android:layout_width=\"match_parent\" (or fill_parent)");
927 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700928
Adam Powell33b97432010-04-20 10:01:14 -0700929 int heightMode = MeasureSpec.getMode(heightMeasureSpec);
930 if (heightMode != MeasureSpec.AT_MOST) {
931 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
932 "with android:layout_height=\"wrap_content\"");
933 }
934
935 int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
Adam Powelle2194442010-08-12 18:13:03 -0700936
Adam Powell570470a2012-08-06 17:00:17 -0700937 int maxHeight = mContentHeight >= 0 ?
Adam Powelle2194442010-08-12 18:13:03 -0700938 mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700939
Adam Powelle2194442010-08-12 18:13:03 -0700940 final int verticalPadding = getPaddingTop() + getPaddingBottom();
Adam Powell9ab97872010-10-26 21:47:29 -0700941 final int paddingLeft = getPaddingLeft();
942 final int paddingRight = getPaddingRight();
Adam Powelle2194442010-08-12 18:13:03 -0700943 final int height = maxHeight - verticalPadding;
Adam Powella1700782010-05-13 13:27:35 -0700944 final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
Adam Powell6322af52012-08-08 15:59:12 -0700945 final int exactHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
Adam Powell33b97432010-04-20 10:01:14 -0700946
Adam Powell9ab97872010-10-26 21:47:29 -0700947 int availableWidth = contentWidth - paddingLeft - paddingRight;
948 int leftOfCenter = availableWidth / 2;
949 int rightOfCenter = leftOfCenter;
950
Adam Powellad79b902013-06-19 11:33:28 -0700951 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
952 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
953
Adam Powellb1e2f252011-08-22 17:42:12 -0700954 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powell8d02dea2011-05-31 21:35:13 -0700955
Adam Powellad79b902013-06-19 11:33:28 -0700956 final ViewGroup.LayoutParams homeLp = homeLayout.getLayoutParams();
957 int homeWidthSpec;
958 if (homeLp.width < 0) {
959 homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
960 } else {
961 homeWidthSpec = MeasureSpec.makeMeasureSpec(homeLp.width, MeasureSpec.EXACTLY);
962 }
Adam Powell27cba382013-01-22 18:55:20 -0800963
Adam Powellad79b902013-06-19 11:33:28 -0700964 /*
965 * This is a little weird.
966 * We're only measuring the *home* affordance within the Up container here
967 * on purpose, because we want to give the available space to all other views before
968 * the title text. We'll remeasure the whole up container again later.
969 * We need to measure this container so we know the right offset for the up affordance
970 * no matter what.
971 */
972 homeLayout.measure(homeWidthSpec, exactHeightSpec);
973
974 int homeWidth = 0;
975 if ((homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive)
976 || showTitle) {
Adam Powell27cba382013-01-22 18:55:20 -0800977 homeWidth = homeLayout.getMeasuredWidth();
978 final int homeOffsetWidth = homeWidth + homeLayout.getStartOffset();
979 availableWidth = Math.max(0, availableWidth - homeOffsetWidth);
980 leftOfCenter = Math.max(0, availableWidth - homeOffsetWidth);
Adam Powell33b97432010-04-20 10:01:14 -0700981 }
Casey Burkhardt8452a7f2013-04-30 15:56:41 -0700982
Adam Powell9b4bee02011-04-27 19:24:47 -0700983 if (mMenuView != null && mMenuView.getParent() == this) {
Adam Powell6322af52012-08-08 15:59:12 -0700984 availableWidth = measureChildView(mMenuView, availableWidth, exactHeightSpec, 0);
Adam Powell1b4a1622011-05-17 12:13:13 -0700985 rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
Adam Powell33b97432010-04-20 10:01:14 -0700986 }
Adam Powell9ab97872010-10-26 21:47:29 -0700987
Adam Powellaa8e509b2011-08-25 09:29:21 -0700988 if (mIndeterminateProgressView != null &&
989 mIndeterminateProgressView.getVisibility() != GONE) {
990 availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
991 childSpecHeight, 0);
992 rightOfCenter = Math.max(0,
993 rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
994 }
Adam Powell9ab97872010-10-26 21:47:29 -0700995
Adam Powellaa8e509b2011-08-25 09:29:21 -0700996 if (mExpandedActionView == null) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700997 switch (mNavigationMode) {
998 case ActionBar.NAVIGATION_MODE_LIST:
999 if (mListNavLayout != null) {
1000 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
1001 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
1002 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
1003 mListNavLayout.measure(
1004 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
1005 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1006 final int listNavWidth = mListNavLayout.getMeasuredWidth();
1007 availableWidth = Math.max(0, availableWidth - listNavWidth);
1008 leftOfCenter = Math.max(0, leftOfCenter - listNavWidth);
1009 }
1010 break;
1011 case ActionBar.NAVIGATION_MODE_TABS:
1012 if (mTabScrollView != null) {
1013 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
1014 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
1015 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
1016 mTabScrollView.measure(
1017 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
1018 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
1019 final int tabWidth = mTabScrollView.getMeasuredWidth();
1020 availableWidth = Math.max(0, availableWidth - tabWidth);
1021 leftOfCenter = Math.max(0, leftOfCenter - tabWidth);
1022 }
1023 break;
Adam Powell33b97432010-04-20 10:01:14 -07001024 }
Adam Powell33b97432010-04-20 10:01:14 -07001025 }
1026
Adam Powell8d02dea2011-05-31 21:35:13 -07001027 View customView = null;
1028 if (mExpandedActionView != null) {
1029 customView = mExpandedActionView;
1030 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1031 mCustomNavView != null) {
1032 customView = mCustomNavView;
1033 }
1034
1035 if (customView != null) {
Adam Powell9a5cc282011-08-28 16:18:16 -07001036 final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams());
Adam Powell9ab97872010-10-26 21:47:29 -07001037 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1038 (ActionBar.LayoutParams) lp : null;
1039
1040 int horizontalMargin = 0;
1041 int verticalMargin = 0;
1042 if (ablp != null) {
1043 horizontalMargin = ablp.leftMargin + ablp.rightMargin;
1044 verticalMargin = ablp.topMargin + ablp.bottomMargin;
1045 }
1046
1047 // If the action bar is wrapping to its content height, don't allow a custom
1048 // view to MATCH_PARENT.
1049 int customNavHeightMode;
1050 if (mContentHeight <= 0) {
1051 customNavHeightMode = MeasureSpec.AT_MOST;
1052 } else {
1053 customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
1054 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
1055 }
1056 final int customNavHeight = Math.max(0,
1057 (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin);
1058
1059 final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
1060 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
1061 int customNavWidth = Math.max(0,
1062 (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth)
1063 - horizontalMargin);
1064 final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) &
1065 Gravity.HORIZONTAL_GRAVITY_MASK;
1066
1067 // Centering a custom view is treated specially; we try to center within the whole
1068 // action bar rather than in the available space.
1069 if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) {
1070 customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2;
1071 }
1072
Adam Powell8d02dea2011-05-31 21:35:13 -07001073 customView.measure(
Adam Powell9ab97872010-10-26 21:47:29 -07001074 MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
1075 MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
Adam Powellaa8e509b2011-08-25 09:29:21 -07001076 availableWidth -= horizontalMargin + customView.getMeasuredWidth();
1077 }
1078
Adam Powell27cba382013-01-22 18:55:20 -08001079 /*
1080 * Measure the whole up container now, allowing for the full home+title sections.
1081 * (This will re-measure the home view.)
1082 */
1083 availableWidth = measureChildView(mUpGoerFive, availableWidth + homeWidth,
1084 MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
1085 if (mTitleLayout != null) {
Adam Powellaa8e509b2011-08-25 09:29:21 -07001086 leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
Adam Powell9ab97872010-10-26 21:47:29 -07001087 }
1088
Adam Powelle2194442010-08-12 18:13:03 -07001089 if (mContentHeight <= 0) {
1090 int measuredHeight = 0;
Adam Powelld21aa122011-05-27 13:09:52 -07001091 for (int i = 0; i < childCount; i++) {
Adam Powelle2194442010-08-12 18:13:03 -07001092 View v = getChildAt(i);
1093 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
1094 if (paddedViewHeight > measuredHeight) {
1095 measuredHeight = paddedViewHeight;
1096 }
1097 }
1098 setMeasuredDimension(contentWidth, measuredHeight);
1099 } else {
1100 setMeasuredDimension(contentWidth, maxHeight);
1101 }
1102
1103 if (mContextView != null) {
Adam Powell425689e2011-09-08 18:09:33 -07001104 mContextView.setContentHeight(getMeasuredHeight());
Adam Powelle2194442010-08-12 18:13:03 -07001105 }
Adam Powell6af97e12010-11-11 21:11:53 -08001106
1107 if (mProgressView != null && mProgressView.getVisibility() != GONE) {
1108 mProgressView.measure(MeasureSpec.makeMeasureSpec(
1109 contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY),
1110 MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
1111 }
Adam Powell33b97432010-04-20 10:01:14 -07001112 }
1113
Adam Powell33b97432010-04-20 10:01:14 -07001114 @Override
1115 protected void onLayout(boolean changed, int l, int t, int r, int b) {
Adam Powell33b97432010-04-20 10:01:14 -07001116 final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
1117
Adam Powelld21aa122011-05-27 13:09:52 -07001118 if (contentHeight <= 0) {
1119 // Nothing to do if we can't see anything.
1120 return;
1121 }
1122
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001123 final boolean isLayoutRtl = isLayoutRtl();
Adam Powellad79b902013-06-19 11:33:28 -07001124 final int direction = isLayoutRtl ? 1 : -1;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001125 int menuStart = isLayoutRtl ? getPaddingLeft() : r - l - getPaddingRight();
1126 // In LTR mode, we start from left padding and go to the right; in RTL mode, we start
1127 // from the padding right and go to the left (in reverse way)
1128 int x = isLayoutRtl ? r - l - getPaddingRight() : getPaddingLeft();
1129 final int y = getPaddingTop();
1130
Adam Powellb1e2f252011-08-22 17:42:12 -07001131 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powellad79b902013-06-19 11:33:28 -07001132 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
1133 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
1134 int startOffset = 0;
1135 if (homeLayout.getParent() == mUpGoerFive) {
1136 if (homeLayout.getVisibility() != GONE) {
1137 startOffset = homeLayout.getStartOffset();
1138 } else if (showTitle) {
1139 startOffset = homeLayout.getUpWidth();
1140 }
1141 }
Adam Powell27cba382013-01-22 18:55:20 -08001142
1143 // Position the up container based on where the edge of the home layout should go.
1144 x += positionChild(mUpGoerFive,
1145 next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
1146 x = next(x, startOffset, isLayoutRtl);
Adam Powell9ab97872010-10-26 21:47:29 -07001147
Adam Powell8d02dea2011-05-31 21:35:13 -07001148 if (mExpandedActionView == null) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001149 switch (mNavigationMode) {
1150 case ActionBar.NAVIGATION_MODE_STANDARD:
1151 break;
1152 case ActionBar.NAVIGATION_MODE_LIST:
1153 if (mListNavLayout != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001154 if (showTitle) {
1155 x = next(x, mItemPadding, isLayoutRtl);
1156 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001157 x += positionChild(mListNavLayout, x, y, contentHeight, isLayoutRtl);
1158 x = next(x, mItemPadding, isLayoutRtl);
Adam Powell8d02dea2011-05-31 21:35:13 -07001159 }
1160 break;
1161 case ActionBar.NAVIGATION_MODE_TABS:
1162 if (mTabScrollView != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001163 if (showTitle) x = next(x, mItemPadding, isLayoutRtl);
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001164 x += positionChild(mTabScrollView, x, y, contentHeight, isLayoutRtl);
1165 x = next(x, mItemPadding, isLayoutRtl);
Adam Powell8d02dea2011-05-31 21:35:13 -07001166 }
1167 break;
Adam Powell661c9082010-07-02 10:09:44 -07001168 }
Adam Powell33b97432010-04-20 10:01:14 -07001169 }
1170
Adam Powell9b4bee02011-04-27 19:24:47 -07001171 if (mMenuView != null && mMenuView.getParent() == this) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001172 positionChild(mMenuView, menuStart, y, contentHeight, !isLayoutRtl);
1173 menuStart += direction * mMenuView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001174 }
1175
Adam Powell6af97e12010-11-11 21:11:53 -08001176 if (mIndeterminateProgressView != null &&
1177 mIndeterminateProgressView.getVisibility() != GONE) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001178 positionChild(mIndeterminateProgressView, menuStart, y, contentHeight, !isLayoutRtl);
1179 menuStart += direction * mIndeterminateProgressView.getMeasuredWidth();
Adam Powell6af97e12010-11-11 21:11:53 -08001180 }
1181
Adam Powell8d02dea2011-05-31 21:35:13 -07001182 View customView = null;
1183 if (mExpandedActionView != null) {
1184 customView = mExpandedActionView;
1185 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1186 mCustomNavView != null) {
1187 customView = mCustomNavView;
1188 }
1189 if (customView != null) {
Fabrice Di Meglio6bf6eb72012-10-10 15:30:28 -07001190 final int layoutDirection = getLayoutDirection();
Fabrice Di Megliobb4b6012012-10-26 16:27:55 -07001191 ViewGroup.LayoutParams lp = customView.getLayoutParams();
Adam Powell9ab97872010-10-26 21:47:29 -07001192 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1193 (ActionBar.LayoutParams) lp : null;
Adam Powell9ab97872010-10-26 21:47:29 -07001194 final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY;
Adam Powell8d02dea2011-05-31 21:35:13 -07001195 final int navWidth = customView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001196
1197 int topMargin = 0;
1198 int bottomMargin = 0;
1199 if (ablp != null) {
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001200 x = next(x, ablp.getMarginStart(), isLayoutRtl);
1201 menuStart += direction * ablp.getMarginEnd();
Adam Powell9ab97872010-10-26 21:47:29 -07001202 topMargin = ablp.topMargin;
1203 bottomMargin = ablp.bottomMargin;
1204 }
1205
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001206 int hgravity = gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
Adam Powell9ab97872010-10-26 21:47:29 -07001207 // See if we actually have room to truly center; if not push against left or right.
1208 if (hgravity == Gravity.CENTER_HORIZONTAL) {
1209 final int centeredLeft = ((mRight - mLeft) - navWidth) / 2;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001210 if (isLayoutRtl) {
1211 final int centeredStart = centeredLeft + navWidth;
1212 final int centeredEnd = centeredLeft;
1213 if (centeredStart > x) {
1214 hgravity = Gravity.RIGHT;
1215 } else if (centeredEnd < menuStart) {
1216 hgravity = Gravity.LEFT;
1217 }
1218 } else {
1219 final int centeredStart = centeredLeft;
1220 final int centeredEnd = centeredLeft + navWidth;
1221 if (centeredStart < x) {
1222 hgravity = Gravity.LEFT;
1223 } else if (centeredEnd > menuStart) {
1224 hgravity = Gravity.RIGHT;
1225 }
Adam Powell9ab97872010-10-26 21:47:29 -07001226 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001227 } else if (gravity == Gravity.NO_GRAVITY) {
1228 hgravity = Gravity.START;
Adam Powell9ab97872010-10-26 21:47:29 -07001229 }
1230
1231 int xpos = 0;
Fabrice Di Meglio6bf6eb72012-10-10 15:30:28 -07001232 switch (Gravity.getAbsoluteGravity(hgravity, layoutDirection)) {
Adam Powell9ab97872010-10-26 21:47:29 -07001233 case Gravity.CENTER_HORIZONTAL:
1234 xpos = ((mRight - mLeft) - navWidth) / 2;
1235 break;
1236 case Gravity.LEFT:
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001237 xpos = isLayoutRtl ? menuStart : x;
Adam Powell9ab97872010-10-26 21:47:29 -07001238 break;
1239 case Gravity.RIGHT:
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001240 xpos = isLayoutRtl ? x - navWidth : menuStart - navWidth;
Adam Powell9ab97872010-10-26 21:47:29 -07001241 break;
1242 }
1243
Adam Powell7a2424d2011-08-18 11:59:11 -07001244 int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
1245
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001246 if (gravity == Gravity.NO_GRAVITY) {
Adam Powell7a2424d2011-08-18 11:59:11 -07001247 vgravity = Gravity.CENTER_VERTICAL;
1248 }
1249
Adam Powell9ab97872010-10-26 21:47:29 -07001250 int ypos = 0;
Adam Powell7a2424d2011-08-18 11:59:11 -07001251 switch (vgravity) {
Adam Powell9ab97872010-10-26 21:47:29 -07001252 case Gravity.CENTER_VERTICAL:
Adam Powell6556c072011-06-24 17:16:57 -07001253 final int paddedTop = getPaddingTop();
1254 final int paddedBottom = mBottom - mTop - getPaddingBottom();
Adam Powell8d02dea2011-05-31 21:35:13 -07001255 ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2;
Adam Powell9ab97872010-10-26 21:47:29 -07001256 break;
1257 case Gravity.TOP:
1258 ypos = getPaddingTop() + topMargin;
1259 break;
1260 case Gravity.BOTTOM:
Adam Powell8d02dea2011-05-31 21:35:13 -07001261 ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight()
Adam Powell9ab97872010-10-26 21:47:29 -07001262 - bottomMargin;
1263 break;
1264 }
Adam Powell6556c072011-06-24 17:16:57 -07001265 final int customWidth = customView.getMeasuredWidth();
1266 customView.layout(xpos, ypos, xpos + customWidth,
1267 ypos + customView.getMeasuredHeight());
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001268 x = next(x, customWidth, isLayoutRtl);
Adam Powell33b97432010-04-20 10:01:14 -07001269 }
Adam Powell6af97e12010-11-11 21:11:53 -08001270
1271 if (mProgressView != null) {
1272 mProgressView.bringToFront();
1273 final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2;
1274 mProgressView.layout(mProgressBarPadding, -halfProgressHeight,
1275 mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight);
1276 }
Adam Powell33b97432010-04-20 10:01:14 -07001277 }
1278
Adam Powell8d02dea2011-05-31 21:35:13 -07001279 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001280 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
Adam Powellaad47fd2011-08-17 17:33:33 -07001281 return new ActionBar.LayoutParams(getContext(), attrs);
1282 }
1283
1284 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001285 public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001286 if (lp == null) {
1287 lp = generateDefaultLayoutParams();
1288 }
1289 return lp;
1290 }
1291
1292 @Override
1293 public Parcelable onSaveInstanceState() {
1294 Parcelable superState = super.onSaveInstanceState();
1295 SavedState state = new SavedState(superState);
1296
1297 if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
1298 state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
1299 }
1300
1301 state.isOverflowOpen = isOverflowMenuShowing();
1302
1303 return state;
1304 }
1305
1306 @Override
1307 public void onRestoreInstanceState(Parcelable p) {
1308 SavedState state = (SavedState) p;
1309
1310 super.onRestoreInstanceState(state.getSuperState());
1311
1312 if (state.expandedMenuItemId != 0 &&
1313 mExpandedMenuPresenter != null && mOptionsMenu != null) {
1314 final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId);
1315 if (item != null) {
1316 item.expandActionView();
1317 }
1318 }
1319
1320 if (state.isOverflowOpen) {
1321 postShowOverflowMenu();
1322 }
1323 }
1324
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001325 public void setHomeAsUpIndicator(Drawable indicator) {
1326 mHomeLayout.setUpIndicator(indicator);
1327 }
1328
1329 public void setHomeAsUpIndicator(int resId) {
1330 mHomeLayout.setUpIndicator(resId);
1331 }
1332
1333 public void setHomeActionContentDescription(CharSequence description) {
1334 mHomeDescription = description;
Adam Powell2229ca02013-11-12 16:20:46 -08001335 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001336 }
1337
1338 public void setHomeActionContentDescription(int resId) {
1339 mHomeDescriptionRes = resId;
Adam Powell2eeb4192013-04-18 13:53:27 -07001340 mHomeDescription = resId != 0 ? getResources().getText(resId) : null;
Adam Powell2229ca02013-11-12 16:20:46 -08001341 updateHomeAccessibility(mUpGoerFive.isEnabled());
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001342 }
1343
Adam Powell8d02dea2011-05-31 21:35:13 -07001344 static class SavedState extends BaseSavedState {
1345 int expandedMenuItemId;
1346 boolean isOverflowOpen;
1347
1348 SavedState(Parcelable superState) {
1349 super(superState);
1350 }
1351
1352 private SavedState(Parcel in) {
1353 super(in);
1354 expandedMenuItemId = in.readInt();
1355 isOverflowOpen = in.readInt() != 0;
1356 }
1357
1358 @Override
1359 public void writeToParcel(Parcel out, int flags) {
1360 super.writeToParcel(out, flags);
1361 out.writeInt(expandedMenuItemId);
1362 out.writeInt(isOverflowOpen ? 1 : 0);
1363 }
1364
1365 public static final Parcelable.Creator<SavedState> CREATOR =
1366 new Parcelable.Creator<SavedState>() {
1367 public SavedState createFromParcel(Parcel in) {
1368 return new SavedState(in);
1369 }
1370
1371 public SavedState[] newArray(int size) {
1372 return new SavedState[size];
1373 }
1374 };
1375 }
1376
Adam Powell2b0952b2011-03-09 00:15:38 -08001377 private static class HomeView extends FrameLayout {
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001378 private ImageView mUpView;
Adam Powell8d02dea2011-05-31 21:35:13 -07001379 private ImageView mIconView;
Adam Powellb1e2f252011-08-22 17:42:12 -07001380 private int mUpWidth;
Adam Powellad79b902013-06-19 11:33:28 -07001381 private int mStartOffset;
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001382 private int mUpIndicatorRes;
1383 private Drawable mDefaultUpIndicator;
Adam Powell2b0952b2011-03-09 00:15:38 -08001384
Adam Powellfd75eef2012-08-02 10:27:31 -07001385 private static final long DEFAULT_TRANSITION_DURATION = 150;
1386
Adam Powell2b0952b2011-03-09 00:15:38 -08001387 public HomeView(Context context) {
1388 this(context, null);
1389 }
1390
1391 public HomeView(Context context, AttributeSet attrs) {
1392 super(context, attrs);
Adam Powellfd75eef2012-08-02 10:27:31 -07001393 LayoutTransition t = getLayoutTransition();
1394 if (t != null) {
1395 // Set a lower duration than the default
1396 t.setDuration(DEFAULT_TRANSITION_DURATION);
1397 }
Adam Powell2b0952b2011-03-09 00:15:38 -08001398 }
1399
Adam Powellad79b902013-06-19 11:33:28 -07001400 public void setShowUp(boolean isUp) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001401 mUpView.setVisibility(isUp ? VISIBLE : GONE);
1402 }
1403
Adam Powellad79b902013-06-19 11:33:28 -07001404 public void setShowIcon(boolean showIcon) {
1405 mIconView.setVisibility(showIcon ? VISIBLE : GONE);
1406 }
1407
Adam Powell8d02dea2011-05-31 21:35:13 -07001408 public void setIcon(Drawable icon) {
1409 mIconView.setImageDrawable(icon);
1410 }
1411
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001412 public void setUpIndicator(Drawable d) {
1413 mUpView.setImageDrawable(d != null ? d : mDefaultUpIndicator);
1414 mUpIndicatorRes = 0;
1415 }
1416
1417 public void setUpIndicator(int resId) {
1418 mUpIndicatorRes = resId;
1419 mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
1420 }
1421
1422 @Override
1423 protected void onConfigurationChanged(Configuration newConfig) {
1424 super.onConfigurationChanged(newConfig);
1425 if (mUpIndicatorRes != 0) {
1426 // Reload for config change
1427 setUpIndicator(mUpIndicatorRes);
1428 }
1429 }
1430
Adam Powell2b0952b2011-03-09 00:15:38 -08001431 @Override
Adam Powell7bc3ca02011-08-26 18:29:58 -07001432 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
1433 onPopulateAccessibilityEvent(event);
1434 return true;
1435 }
1436
1437 @Override
1438 public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1439 super.onPopulateAccessibilityEvent(event);
1440 final CharSequence cdesc = getContentDescription();
1441 if (!TextUtils.isEmpty(cdesc)) {
1442 event.getText().add(cdesc);
1443 }
1444 }
1445
1446 @Override
1447 public boolean dispatchHoverEvent(MotionEvent event) {
1448 // Don't allow children to hover; we want this to be treated as a single component.
1449 return onHoverEvent(event);
1450 }
1451
1452 @Override
Adam Powell2b0952b2011-03-09 00:15:38 -08001453 protected void onFinishInflate() {
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001454 mUpView = (ImageView) findViewById(com.android.internal.R.id.up);
Adam Powell2b0952b2011-03-09 00:15:38 -08001455 mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
Adam Powelle0e2f4f2013-04-05 16:27:35 -07001456 mDefaultUpIndicator = mUpView.getDrawable();
Adam Powell2b0952b2011-03-09 00:15:38 -08001457 }
1458
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001459 public int getStartOffset() {
Adam Powellad79b902013-06-19 11:33:28 -07001460 return mUpView.getVisibility() == GONE ? mStartOffset : 0;
1461 }
1462
1463 public int getUpWidth() {
1464 return mUpWidth;
Adam Powell8d02dea2011-05-31 21:35:13 -07001465 }
1466
Adam Powell2b0952b2011-03-09 00:15:38 -08001467 @Override
1468 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1469 measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
1470 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
Adam Powellad79b902013-06-19 11:33:28 -07001471 final int upMargins = upLp.leftMargin + upLp.rightMargin;
1472 mUpWidth = mUpView.getMeasuredWidth();
1473 mStartOffset = mUpWidth + upMargins;
1474 int width = mUpView.getVisibility() == GONE ? 0 : mStartOffset;
Adam Powell2b0952b2011-03-09 00:15:38 -08001475 int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
Adam Powellad79b902013-06-19 11:33:28 -07001476
1477 if (mIconView.getVisibility() != GONE) {
1478 measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
1479 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1480 width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
1481 height = Math.max(height,
1482 iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
1483 } else if (upMargins < 0) {
1484 // Remove the measurement effects of negative margins used for offsets
1485 width -= upMargins;
1486 }
Adam Powell0d5d1b7e2011-06-22 17:40:40 -07001487
1488 final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
1489 final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
1490 final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
1491 final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
1492
1493 switch (widthMode) {
1494 case MeasureSpec.AT_MOST:
1495 width = Math.min(width, widthSize);
1496 break;
1497 case MeasureSpec.EXACTLY:
1498 width = widthSize;
1499 break;
1500 case MeasureSpec.UNSPECIFIED:
1501 default:
1502 break;
1503 }
1504 switch (heightMode) {
1505 case MeasureSpec.AT_MOST:
1506 height = Math.min(height, heightSize);
1507 break;
1508 case MeasureSpec.EXACTLY:
1509 height = heightSize;
1510 break;
1511 case MeasureSpec.UNSPECIFIED:
1512 default:
1513 break;
1514 }
Adam Powell2b0952b2011-03-09 00:15:38 -08001515 setMeasuredDimension(width, height);
1516 }
1517
1518 @Override
1519 protected void onLayout(boolean changed, int l, int t, int r, int b) {
1520 final int vCenter = (b - t) / 2;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001521 final boolean isLayoutRtl = isLayoutRtl();
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001522 final int width = getWidth();
Adam Powellc8b0b002011-06-23 14:39:05 -07001523 int upOffset = 0;
Adam Powell2b0952b2011-03-09 00:15:38 -08001524 if (mUpView.getVisibility() != GONE) {
1525 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
1526 final int upHeight = mUpView.getMeasuredHeight();
1527 final int upWidth = mUpView.getMeasuredWidth();
Adam Powellc8b0b002011-06-23 14:39:05 -07001528 upOffset = upLp.leftMargin + upWidth + upLp.rightMargin;
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001529 final int upTop = vCenter - upHeight / 2;
1530 final int upBottom = upTop + upHeight;
1531 final int upRight;
1532 final int upLeft;
1533 if (isLayoutRtl) {
1534 upRight = width;
1535 upLeft = upRight - upWidth;
1536 r -= upOffset;
1537 } else {
1538 upRight = upWidth;
1539 upLeft = 0;
1540 l += upOffset;
1541 }
1542 mUpView.layout(upLeft, upTop, upRight, upBottom);
Adam Powell2b0952b2011-03-09 00:15:38 -08001543 }
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001544
Adam Powell2b0952b2011-03-09 00:15:38 -08001545 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1546 final int iconHeight = mIconView.getMeasuredHeight();
1547 final int iconWidth = mIconView.getMeasuredWidth();
1548 final int hCenter = (r - l) / 2;
Adam Powellc8b0b002011-06-23 14:39:05 -07001549 final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2);
Fabrice Di Megliocf1ba022012-06-25 15:49:11 -07001550 final int iconBottom = iconTop + iconHeight;
1551 final int iconLeft;
1552 final int iconRight;
1553 int marginStart = iconLp.getMarginStart();
1554 final int delta = Math.max(marginStart, hCenter - iconWidth / 2);
1555 if (isLayoutRtl) {
1556 iconRight = width - upOffset - delta;
1557 iconLeft = iconRight - iconWidth;
1558 } else {
1559 iconLeft = upOffset + delta;
1560 iconRight = iconLeft + iconWidth;
1561 }
1562 mIconView.layout(iconLeft, iconTop, iconRight, iconBottom);
Adam Powell2b0952b2011-03-09 00:15:38 -08001563 }
1564 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001565
1566 private class ExpandedActionViewMenuPresenter implements MenuPresenter {
1567 MenuBuilder mMenu;
1568 MenuItemImpl mCurrentExpandedItem;
1569
1570 @Override
1571 public void initForMenu(Context context, MenuBuilder menu) {
1572 // Clear the expanded action view when menus change.
Adam Powell6b0e97c2011-08-03 12:06:32 -07001573 if (mMenu != null && mCurrentExpandedItem != null) {
1574 mMenu.collapseItemActionView(mCurrentExpandedItem);
Adam Powell8d02dea2011-05-31 21:35:13 -07001575 }
1576 mMenu = menu;
1577 }
1578
1579 @Override
1580 public MenuView getMenuView(ViewGroup root) {
1581 return null;
1582 }
1583
1584 @Override
1585 public void updateMenuView(boolean cleared) {
1586 // Make sure the expanded item we have is still there.
1587 if (mCurrentExpandedItem != null) {
1588 boolean found = false;
Adam Powellf35d0492011-08-17 13:56:47 -07001589
1590 if (mMenu != null) {
1591 final int count = mMenu.size();
1592 for (int i = 0; i < count; i++) {
1593 final MenuItem item = mMenu.getItem(i);
1594 if (item == mCurrentExpandedItem) {
1595 found = true;
1596 break;
1597 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001598 }
1599 }
1600
1601 if (!found) {
1602 // The item we had expanded disappeared. Collapse.
1603 collapseItemActionView(mMenu, mCurrentExpandedItem);
1604 }
1605 }
1606 }
1607
1608 @Override
1609 public void setCallback(Callback cb) {
1610 }
1611
1612 @Override
1613 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
1614 return false;
1615 }
1616
1617 @Override
1618 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1619 }
1620
1621 @Override
1622 public boolean flagActionItems() {
1623 return false;
1624 }
1625
1626 @Override
1627 public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
Chet Haased8d7c382013-09-23 11:26:36 -07001628 ActionBarTransition.beginDelayedTransition(ActionBarView.this);
Adam Powellc46d3332013-09-17 10:08:41 -07001629
Adam Powell8d02dea2011-05-31 21:35:13 -07001630 mExpandedActionView = item.getActionView();
Adam Powell28fa07e2011-07-15 20:17:25 -07001631 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
Adam Powell8d02dea2011-05-31 21:35:13 -07001632 mCurrentExpandedItem = item;
1633 if (mExpandedActionView.getParent() != ActionBarView.this) {
1634 addView(mExpandedActionView);
1635 }
Adam Powell27cba382013-01-22 18:55:20 -08001636 if (mExpandedHomeLayout.getParent() != mUpGoerFive) {
1637 mUpGoerFive.addView(mExpandedHomeLayout);
Adam Powell8d02dea2011-05-31 21:35:13 -07001638 }
1639 mHomeLayout.setVisibility(GONE);
Adam Powell15a16a82011-06-20 10:35:27 -07001640 if (mTitleLayout != null) mTitleLayout.setVisibility(GONE);
Adam Powell8d02dea2011-05-31 21:35:13 -07001641 if (mTabScrollView != null) mTabScrollView.setVisibility(GONE);
1642 if (mSpinner != null) mSpinner.setVisibility(GONE);
1643 if (mCustomNavView != null) mCustomNavView.setVisibility(GONE);
Adam Powell07cf9712013-02-05 16:13:57 -08001644 setHomeButtonEnabled(false, false);
Adam Powell8d02dea2011-05-31 21:35:13 -07001645 requestLayout();
1646 item.setActionViewExpanded(true);
Adam Powell038f1c82011-07-21 14:28:10 -07001647
1648 if (mExpandedActionView instanceof CollapsibleActionView) {
1649 ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
1650 }
Amith Yamasani10da5902011-07-26 16:14:26 -07001651
Adam Powell8d02dea2011-05-31 21:35:13 -07001652 return true;
1653 }
1654
1655 @Override
1656 public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
Chet Haased8d7c382013-09-23 11:26:36 -07001657 ActionBarTransition.beginDelayedTransition(ActionBarView.this);
Adam Powellc46d3332013-09-17 10:08:41 -07001658
Amith Yamasani10da5902011-07-26 16:14:26 -07001659 // Do this before detaching the actionview from the hierarchy, in case
1660 // it needs to dismiss the soft keyboard, etc.
1661 if (mExpandedActionView instanceof CollapsibleActionView) {
1662 ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
1663 }
1664
Adam Powell8d02dea2011-05-31 21:35:13 -07001665 removeView(mExpandedActionView);
Adam Powell27cba382013-01-22 18:55:20 -08001666 mUpGoerFive.removeView(mExpandedHomeLayout);
Adam Powellb0e217e2011-08-12 11:36:51 -07001667 mExpandedActionView = null;
Adam Powell8d02dea2011-05-31 21:35:13 -07001668 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
1669 mHomeLayout.setVisibility(VISIBLE);
1670 }
1671 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
Adam Powell15a16a82011-06-20 10:35:27 -07001672 if (mTitleLayout == null) {
1673 initTitle();
1674 } else {
1675 mTitleLayout.setVisibility(VISIBLE);
1676 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001677 }
Adam Powell6684e922013-03-26 15:38:26 -07001678 if (mTabScrollView != null) mTabScrollView.setVisibility(VISIBLE);
1679 if (mSpinner != null) mSpinner.setVisibility(VISIBLE);
1680 if (mCustomNavView != null) mCustomNavView.setVisibility(VISIBLE);
1681
Adam Powell8d02dea2011-05-31 21:35:13 -07001682 mExpandedHomeLayout.setIcon(null);
1683 mCurrentExpandedItem = null;
Adam Powell62f33032013-02-04 12:44:34 -08001684 setHomeButtonEnabled(mWasHomeEnabled); // Set by expandItemActionView above
Adam Powell8d02dea2011-05-31 21:35:13 -07001685 requestLayout();
1686 item.setActionViewExpanded(false);
Adam Powell038f1c82011-07-21 14:28:10 -07001687
Adam Powell8d02dea2011-05-31 21:35:13 -07001688 return true;
1689 }
Adam Powell11ed1d62011-07-11 21:19:59 -07001690
1691 @Override
1692 public int getId() {
1693 return 0;
1694 }
1695
1696 @Override
1697 public Parcelable onSaveInstanceState() {
1698 return null;
1699 }
1700
1701 @Override
1702 public void onRestoreInstanceState(Parcelable state) {
1703 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001704 }
Adam Powell33b97432010-04-20 10:01:14 -07001705}