blob: 6d2e8232156b4ff8a03242352751da15a1fc7067 [file] [log] [blame]
Adam Powell33b97432010-04-20 10:01:14 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Adam Powell89e06452010-06-23 20:24:52 -070017package com.android.internal.widget;
Adam Powell33b97432010-04-20 10:01:14 -070018
Adam Powell96675b12010-06-10 18:58:59 -070019import com.android.internal.R;
Adam Powell96675b12010-06-10 18:58:59 -070020import com.android.internal.view.menu.ActionMenuItem;
Adam Powell696cba52011-03-29 10:38:16 -070021import com.android.internal.view.menu.ActionMenuPresenter;
Adam Powell7ade1be2010-06-17 12:51:21 -070022import com.android.internal.view.menu.ActionMenuView;
Adam Powell96675b12010-06-10 18:58:59 -070023import com.android.internal.view.menu.MenuBuilder;
Adam Powell8d02dea2011-05-31 21:35:13 -070024import com.android.internal.view.menu.MenuItemImpl;
Adam Powell696cba52011-03-29 10:38:16 -070025import com.android.internal.view.menu.MenuPresenter;
Adam Powell8d02dea2011-05-31 21:35:13 -070026import com.android.internal.view.menu.MenuView;
27import com.android.internal.view.menu.SubMenuBuilder;
Adam Powell33b97432010-04-20 10:01:14 -070028
29import android.app.ActionBar;
Adam Powell8515ee82010-11-30 14:09:55 -080030import android.app.ActionBar.OnNavigationListener;
Adam Powell9146ac72010-08-16 18:53:38 -070031import android.app.Activity;
Adam Powell33b97432010-04-20 10:01:14 -070032import android.content.Context;
33import android.content.pm.ApplicationInfo;
34import android.content.pm.PackageManager;
Adam Powell9ab97872010-10-26 21:47:29 -070035import android.content.pm.PackageManager.NameNotFoundException;
Adam Powell45c0b192011-07-28 15:11:57 -070036import android.content.res.Configuration;
Adam Powell33b97432010-04-20 10:01:14 -070037import android.content.res.TypedArray;
Adam Powell33b97432010-04-20 10:01:14 -070038import android.graphics.drawable.Drawable;
Adam Powell8d02dea2011-05-31 21:35:13 -070039import android.os.Parcel;
40import android.os.Parcelable;
Adam Powell2a7ea672011-01-23 20:25:15 -080041import android.text.TextUtils;
Adam Powell33b97432010-04-20 10:01:14 -070042import android.util.AttributeSet;
Adam Powell9ab97872010-10-26 21:47:29 -070043import android.util.Log;
Adam Powell038f1c82011-07-21 14:28:10 -070044import android.view.CollapsibleActionView;
Adam Powell661c9082010-07-02 10:09:44 -070045import android.view.Gravity;
Adam Powell89e06452010-06-23 20:24:52 -070046import android.view.LayoutInflater;
47import android.view.Menu;
Adam Powell8d02dea2011-05-31 21:35:13 -070048import android.view.MenuItem;
Adam Powell7bc3ca02011-08-26 18:29:58 -070049import android.view.MotionEvent;
Adam Powell89e06452010-06-23 20:24:52 -070050import android.view.View;
51import android.view.ViewGroup;
Adam Powell9ab97872010-10-26 21:47:29 -070052import android.view.ViewParent;
Adam Powell8d12e202010-11-15 16:44:17 -080053import android.view.Window;
Adam Powell7bc3ca02011-08-26 18:29:58 -070054import android.view.accessibility.AccessibilityEvent;
Adam Powella4082912010-06-04 18:34:02 -070055import android.widget.AdapterView;
Adam Powell2b0952b2011-03-09 00:15:38 -080056import android.widget.FrameLayout;
Adam Powell33b97432010-04-20 10:01:14 -070057import android.widget.ImageView;
Adam Powell0e94b512010-06-29 17:58:20 -070058import android.widget.LinearLayout;
Adam Powell6af97e12010-11-11 21:11:53 -080059import android.widget.ProgressBar;
Adam Powella4082912010-06-04 18:34:02 -070060import android.widget.Spinner;
61import android.widget.SpinnerAdapter;
Adam Powell33b97432010-04-20 10:01:14 -070062import android.widget.TextView;
63
Adam Powell33b97432010-04-20 10:01:14 -070064/**
65 * @hide
66 */
Adam Powell640a66e2011-04-29 10:18:53 -070067public class ActionBarView extends AbsActionBarView {
Adam Powell33b97432010-04-20 10:01:14 -070068 private static final String TAG = "ActionBarView";
Adam Powellbe4d68e2010-10-08 18:16:34 -070069
Adam Powell33b97432010-04-20 10:01:14 -070070 /**
71 * Display options applied by default
72 */
73 public static final int DISPLAY_DEFAULT = 0;
74
75 /**
76 * Display options that require re-layout as opposed to a simple invalidate
77 */
Adam Powella1700782010-05-13 13:27:35 -070078 private static final int DISPLAY_RELAYOUT_MASK =
Adam Powell9ab97872010-10-26 21:47:29 -070079 ActionBar.DISPLAY_SHOW_HOME |
80 ActionBar.DISPLAY_USE_LOGO |
81 ActionBar.DISPLAY_HOME_AS_UP |
82 ActionBar.DISPLAY_SHOW_CUSTOM |
83 ActionBar.DISPLAY_SHOW_TITLE;
84
85 private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL;
Adam Powell33b97432010-04-20 10:01:14 -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 Powell33b97432010-04-20 10:01:14 -070093
Adam Powell8d02dea2011-05-31 21:35:13 -070094 private HomeView mHomeLayout;
95 private HomeView mExpandedHomeLayout;
Adam Powell0e94b512010-06-29 17:58:20 -070096 private LinearLayout mTitleLayout;
Adam Powell33b97432010-04-20 10:01:14 -070097 private TextView mTitleView;
98 private TextView mSubtitleView;
Adam Powell54c7d7e2011-06-17 20:30:13 -070099 private View mTitleUpView;
100
Adam Powella4082912010-06-04 18:34:02 -0700101 private Spinner mSpinner;
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800102 private LinearLayout mListNavLayout;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700103 private ScrollingTabContainerView mTabScrollView;
Adam Powella4082912010-06-04 18:34:02 -0700104 private View mCustomNavView;
Adam Powell6af97e12010-11-11 21:11:53 -0800105 private ProgressBar mProgressView;
106 private ProgressBar mIndeterminateProgressView;
107
108 private int mProgressBarPadding;
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800109 private int mItemPadding;
Adam Powell33b97432010-04-20 10:01:14 -0700110
Adam Powelle2194442010-08-12 18:13:03 -0700111 private int mTitleStyleRes;
112 private int mSubtitleStyleRes;
Adam Powell6af97e12010-11-11 21:11:53 -0800113 private int mProgressStyle;
114 private int mIndeterminateProgressStyle;
Adam Powelle2194442010-08-12 18:13:03 -0700115
Adam Powelle92ea342010-07-14 14:45:50 -0700116 private boolean mUserTitle;
Adam Powelldae78242011-04-25 15:23:41 -0700117 private boolean mIncludeTabs;
Adam Powelld21aa122011-05-27 13:09:52 -0700118 private boolean mIsCollapsable;
Adam Powellf6ce6a92011-06-29 10:25:01 -0700119 private boolean mIsCollapsed;
Adam Powell33b97432010-04-20 10:01:14 -0700120
Adam Powell96675b12010-06-10 18:58:59 -0700121 private MenuBuilder mOptionsMenu;
Adam Powell96675b12010-06-10 18:58:59 -0700122
Adam Powelle2194442010-08-12 18:13:03 -0700123 private ActionBarContextView mContextView;
124
Adam Powell33b97432010-04-20 10:01:14 -0700125 private ActionMenuItem mLogoNavItem;
Adam Powell9ab97872010-10-26 21:47:29 -0700126
127 private SpinnerAdapter mSpinnerAdapter;
Adam Powell8515ee82010-11-30 14:09:55 -0800128 private OnNavigationListener mCallback;
Adam Powell33b97432010-04-20 10:01:14 -0700129
Adam Powellf8ac6b72011-05-23 18:14:09 -0700130 private Runnable mTabSelector;
131
Adam Powell8d02dea2011-05-31 21:35:13 -0700132 private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
133 View mExpandedActionView;
134
Adam Powell915ce0d2011-09-28 15:52:57 -0700135 Window.Callback mWindowCallback;
136
Adam Powella4082912010-06-04 18:34:02 -0700137 private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
138 new AdapterView.OnItemSelectedListener() {
139 public void onItemSelected(AdapterView parent, View view, int position, long id) {
140 if (mCallback != null) {
141 mCallback.onNavigationItemSelected(position, id);
142 }
143 }
144 public void onNothingSelected(AdapterView parent) {
145 // Do nothing
146 }
147 };
148
Adam Powell8d02dea2011-05-31 21:35:13 -0700149 private final OnClickListener mExpandedActionViewUpListener = new OnClickListener() {
150 @Override
151 public void onClick(View v) {
152 final MenuItemImpl item = mExpandedMenuPresenter.mCurrentExpandedItem;
153 if (item != null) {
154 item.collapseActionView();
155 }
156 }
157 };
Adam Powell2b6230e2010-09-07 17:55:25 -0700158
Adam Powell54c7d7e2011-06-17 20:30:13 -0700159 private final OnClickListener mUpClickListener = new OnClickListener() {
160 public void onClick(View v) {
Adam Powell915ce0d2011-09-28 15:52:57 -0700161 mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, mLogoNavItem);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700162 }
163 };
164
Adam Powell33b97432010-04-20 10:01:14 -0700165 public ActionBarView(Context context, AttributeSet attrs) {
166 super(context, attrs);
167
Adam Powell654e4e42011-01-03 16:33:50 -0800168 // Background is always provided by the container.
169 setBackgroundResource(0);
170
Adam Powell45c0b192011-07-28 15:11:57 -0700171 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
172 com.android.internal.R.attr.actionBarStyle, 0);
Adam Powell33b97432010-04-20 10:01:14 -0700173
Adam Powell9ab97872010-10-26 21:47:29 -0700174 ApplicationInfo appInfo = context.getApplicationInfo();
Adam Powell33b97432010-04-20 10:01:14 -0700175 PackageManager pm = context.getPackageManager();
Adam Powell661c9082010-07-02 10:09:44 -0700176 mNavigationMode = a.getInt(R.styleable.ActionBar_navigationMode,
177 ActionBar.NAVIGATION_MODE_STANDARD);
Adam Powell33b97432010-04-20 10:01:14 -0700178 mTitle = a.getText(R.styleable.ActionBar_title);
179 mSubtitle = a.getText(R.styleable.ActionBar_subtitle);
Adam Powell33b97432010-04-20 10:01:14 -0700180
181 mLogo = a.getDrawable(R.styleable.ActionBar_logo);
182 if (mLogo == null) {
Adam Powell9ab97872010-10-26 21:47:29 -0700183 if (context instanceof Activity) {
184 try {
185 mLogo = pm.getActivityLogo(((Activity) context).getComponentName());
186 } catch (NameNotFoundException e) {
187 Log.e(TAG, "Activity component name not found!", e);
188 }
189 }
190 if (mLogo == null) {
191 mLogo = appInfo.loadLogo(pm);
192 }
Adam Powell33b97432010-04-20 10:01:14 -0700193 }
Adam Powell9ab97872010-10-26 21:47:29 -0700194
Adam Powell33b97432010-04-20 10:01:14 -0700195 mIcon = a.getDrawable(R.styleable.ActionBar_icon);
196 if (mIcon == null) {
Adam Powell9ab97872010-10-26 21:47:29 -0700197 if (context instanceof Activity) {
198 try {
199 mIcon = pm.getActivityIcon(((Activity) context).getComponentName());
200 } catch (NameNotFoundException e) {
201 Log.e(TAG, "Activity component name not found!", e);
202 }
203 }
204 if (mIcon == null) {
205 mIcon = appInfo.loadIcon(pm);
206 }
Adam Powell33b97432010-04-20 10:01:14 -0700207 }
Adam Powell9ab97872010-10-26 21:47:29 -0700208
Ed Heyl1c603002010-11-18 12:18:23 -0800209 final LayoutInflater inflater = LayoutInflater.from(context);
Adam Powell9ab97872010-10-26 21:47:29 -0700210
Ed Heyl1c603002010-11-18 12:18:23 -0800211 final int homeResId = a.getResourceId(
Adam Powellb33be1c2010-11-18 12:11:40 -0800212 com.android.internal.R.styleable.ActionBar_homeLayout,
213 com.android.internal.R.layout.action_bar_home);
Adam Powell9ab97872010-10-26 21:47:29 -0700214
Adam Powell8d02dea2011-05-31 21:35:13 -0700215 mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false);
Ed Heyl1c603002010-11-18 12:18:23 -0800216
Adam Powell8d02dea2011-05-31 21:35:13 -0700217 mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false);
218 mExpandedHomeLayout.setUp(true);
219 mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
Adam Powell7bc3ca02011-08-26 18:29:58 -0700220 mExpandedHomeLayout.setContentDescription(getResources().getText(
221 R.string.action_bar_up_description));
Adam Powell33b97432010-04-20 10:01:14 -0700222
Adam Powelle2194442010-08-12 18:13:03 -0700223 mTitleStyleRes = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
224 mSubtitleStyleRes = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
Adam Powell6af97e12010-11-11 21:11:53 -0800225 mProgressStyle = a.getResourceId(R.styleable.ActionBar_progressBarStyle, 0);
226 mIndeterminateProgressStyle = a.getResourceId(
227 R.styleable.ActionBar_indeterminateProgressStyle, 0);
228
229 mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_progressBarPadding, 0);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800230 mItemPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_itemPadding, 0);
Adam Powelle2194442010-08-12 18:13:03 -0700231
Adam Powell9ab97872010-10-26 21:47:29 -0700232 setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT));
233
Adam Powell33b97432010-04-20 10:01:14 -0700234 final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
235 if (customNavId != 0) {
Ed Heyl1c603002010-11-18 12:18:23 -0800236 mCustomNavView = (View) inflater.inflate(customNavId, this, false);
Adam Powell9ab97872010-10-26 21:47:29 -0700237 mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
238 setDisplayOptions(mDisplayOptions | ActionBar.DISPLAY_SHOW_CUSTOM);
Adam Powell33b97432010-04-20 10:01:14 -0700239 }
240
Adam Powelle2194442010-08-12 18:13:03 -0700241 mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
Adam Powellbe4d68e2010-10-08 18:16:34 -0700242
Adam Powell33b97432010-04-20 10:01:14 -0700243 a.recycle();
Adam Powell33b97432010-04-20 10:01:14 -0700244
Ben Komaload199ec2010-11-01 12:24:16 -0700245 mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700246 mHomeLayout.setOnClickListener(mUpClickListener);
Ben Komaload199ec2010-11-01 12:24:16 -0700247 mHomeLayout.setClickable(true);
248 mHomeLayout.setFocusable(true);
Adam Powell33b97432010-04-20 10:01:14 -0700249 }
Adam Powella7db0372010-06-30 17:08:47 -0700250
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700251 @Override
Adam Powell45c0b192011-07-28 15:11:57 -0700252 protected void onConfigurationChanged(Configuration newConfig) {
253 super.onConfigurationChanged(newConfig);
254
Adam Powell07a047f2011-08-31 10:33:20 -0700255 mTitleView = null;
256 mSubtitleView = null;
257 mTitleUpView = null;
258 if (mTitleLayout != null && mTitleLayout.getParent() == this) {
259 removeView(mTitleLayout);
260 }
261 mTitleLayout = null;
262 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
263 initTitle();
264 }
Adam Powell425689e2011-09-08 18:09:33 -0700265
266 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);
288 }
289
290 @Override
Patrick Dubroye0a799a2011-05-04 16:19:22 -0700291 public boolean shouldDelayChildPressedState() {
292 return false;
293 }
294
Adam Powell6af97e12010-11-11 21:11:53 -0800295 public void initProgress() {
296 mProgressView = new ProgressBar(mContext, null, 0, mProgressStyle);
297 mProgressView.setId(R.id.progress_horizontal);
298 mProgressView.setMax(10000);
299 addView(mProgressView);
300 }
301
302 public void initIndeterminateProgress() {
303 mIndeterminateProgressView = new ProgressBar(mContext, null, 0,
304 mIndeterminateProgressStyle);
305 mIndeterminateProgressView.setId(R.id.progress_circular);
306 addView(mIndeterminateProgressView);
307 }
308
Adam Powella05aba92011-09-23 14:22:49 -0700309 @Override
Adam Powell9b4bee02011-04-27 19:24:47 -0700310 public void setSplitActionBar(boolean splitActionBar) {
311 if (mSplitActionBar != splitActionBar) {
312 if (mMenuView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700313 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
314 if (oldParent != null) {
315 oldParent.removeView(mMenuView);
316 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700317 if (splitActionBar) {
Adam Powell9b4bee02011-04-27 19:24:47 -0700318 if (mSplitView != null) {
319 mSplitView.addView(mMenuView);
320 }
321 } else {
322 addView(mMenuView);
323 }
324 }
Adam Powella05aba92011-09-23 14:22:49 -0700325 if (mSplitView != null) {
326 mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE);
327 }
328 super.setSplitActionBar(splitActionBar);
Adam Powell9b4bee02011-04-27 19:24:47 -0700329 }
330 }
331
332 public boolean isSplitActionBar() {
333 return mSplitActionBar;
334 }
335
Adam Powelldae78242011-04-25 15:23:41 -0700336 public boolean hasEmbeddedTabs() {
337 return mIncludeTabs;
338 }
339
Adam Powellf8ac6b72011-05-23 18:14:09 -0700340 public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
Adam Powelle0adac02011-06-14 13:46:30 -0700341 if (mTabScrollView != null) {
342 removeView(mTabScrollView);
343 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700344 mTabScrollView = tabs;
345 mIncludeTabs = tabs != null;
Adam Powellc3076422011-06-01 18:19:04 -0700346 if (mIncludeTabs && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
Adam Powell39a8dc42011-05-27 18:44:00 -0700347 addView(mTabScrollView);
Adam Powellf5645cb2011-08-10 22:49:02 -0700348 ViewGroup.LayoutParams lp = mTabScrollView.getLayoutParams();
349 lp.width = LayoutParams.WRAP_CONTENT;
350 lp.height = LayoutParams.MATCH_PARENT;
351 tabs.setAllowCollapse(true);
Adam Powell39a8dc42011-05-27 18:44:00 -0700352 }
Adam Powelldae78242011-04-25 15:23:41 -0700353 }
354
Adam Powell8515ee82010-11-30 14:09:55 -0800355 public void setCallback(OnNavigationListener callback) {
Adam Powell96675b12010-06-10 18:58:59 -0700356 mCallback = callback;
Adam Powell33b97432010-04-20 10:01:14 -0700357 }
Adam Powella7db0372010-06-30 17:08:47 -0700358
Adam Powell696cba52011-03-29 10:38:16 -0700359 public void setMenu(Menu menu, MenuPresenter.Callback cb) {
Adam Powellf2d7a5d2011-02-07 18:05:24 -0800360 if (menu == mOptionsMenu) return;
361
Adam Powell696cba52011-03-29 10:38:16 -0700362 if (mOptionsMenu != null) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700363 mOptionsMenu.removeMenuPresenter(mActionMenuPresenter);
364 mOptionsMenu.removeMenuPresenter(mExpandedMenuPresenter);
Adam Powell696cba52011-03-29 10:38:16 -0700365 }
366
Adam Powell96675b12010-06-10 18:58:59 -0700367 MenuBuilder builder = (MenuBuilder) menu;
368 mOptionsMenu = builder;
369 if (mMenuView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700370 final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
371 if (oldParent != null) {
372 oldParent.removeView(mMenuView);
373 }
Adam Powell33b97432010-04-20 10:01:14 -0700374 }
Adam Powell8d02dea2011-05-31 21:35:13 -0700375 if (mActionMenuPresenter == null) {
376 mActionMenuPresenter = new ActionMenuPresenter();
377 mActionMenuPresenter.setCallback(cb);
Adam Powell11ed1d62011-07-11 21:19:59 -0700378 mActionMenuPresenter.setId(com.android.internal.R.id.action_menu_presenter);
Adam Powell8d02dea2011-05-31 21:35:13 -0700379 mExpandedMenuPresenter = new ExpandedActionViewMenuPresenter();
Adam Powell696cba52011-03-29 10:38:16 -0700380 }
Adam Powell35265562011-05-27 15:29:41 -0700381
Adam Powell1ab418a2011-06-09 20:49:49 -0700382 ActionMenuView menuView;
Adam Powell96675b12010-06-10 18:58:59 -0700383 final LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
384 LayoutParams.MATCH_PARENT);
Adam Powell9b4bee02011-04-27 19:24:47 -0700385 if (!mSplitActionBar) {
Adam Powellb187cd92011-07-20 14:17:56 -0700386 mActionMenuPresenter.setExpandedActionViewsExclusive(
387 getResources().getBoolean(
388 com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
Adam Powellf35d0492011-08-17 13:56:47 -0700389 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700390 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell894bf542011-07-22 13:39:08 -0700391 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
392 if (oldParent != null && oldParent != this) {
393 oldParent.removeView(menuView);
394 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700395 addView(menuView, layoutParams);
Adam Powell9b4bee02011-04-27 19:24:47 -0700396 } else {
Adam Powellb187cd92011-07-20 14:17:56 -0700397 mActionMenuPresenter.setExpandedActionViewsExclusive(false);
Adam Powell9b4bee02011-04-27 19:24:47 -0700398 // Allow full screen width in split mode.
Adam Powell8d02dea2011-05-31 21:35:13 -0700399 mActionMenuPresenter.setWidthLimit(
Adam Powell640a66e2011-04-29 10:18:53 -0700400 getContext().getResources().getDisplayMetrics().widthPixels, true);
Adam Powell9b4bee02011-04-27 19:24:47 -0700401 // No limit to the item count; use whatever will fit.
Adam Powell8d02dea2011-05-31 21:35:13 -0700402 mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
Adam Powell640a66e2011-04-29 10:18:53 -0700403 // Span the whole width
404 layoutParams.width = LayoutParams.MATCH_PARENT;
Adam Powellf35d0492011-08-17 13:56:47 -0700405 configPresenters(builder);
Adam Powell1ab418a2011-06-09 20:49:49 -0700406 menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
Adam Powell9b4bee02011-04-27 19:24:47 -0700407 if (mSplitView != null) {
Adam Powell894bf542011-07-22 13:39:08 -0700408 final ViewGroup oldParent = (ViewGroup) menuView.getParent();
409 if (oldParent != null && oldParent != mSplitView) {
410 oldParent.removeView(menuView);
411 }
Adam Powell9a5cc282011-08-28 16:18:16 -0700412 menuView.setVisibility(getAnimatedVisibility());
Adam Powell1ab418a2011-06-09 20:49:49 -0700413 mSplitView.addView(menuView, layoutParams);
414 } else {
415 // We'll add this later if we missed it this time.
416 menuView.setLayoutParams(layoutParams);
417 }
Adam Powell9b4bee02011-04-27 19:24:47 -0700418 }
Adam Powell96675b12010-06-10 18:58:59 -0700419 mMenuView = menuView;
Adam Powell33b97432010-04-20 10:01:14 -0700420 }
Adam Powella7db0372010-06-30 17:08:47 -0700421
Adam Powellf35d0492011-08-17 13:56:47 -0700422 private void configPresenters(MenuBuilder builder) {
423 if (builder != null) {
424 builder.addMenuPresenter(mActionMenuPresenter);
425 builder.addMenuPresenter(mExpandedMenuPresenter);
426 } else {
427 mActionMenuPresenter.initForMenu(mContext, null);
428 mExpandedMenuPresenter.initForMenu(mContext, null);
429 mActionMenuPresenter.updateMenuView(true);
430 mExpandedMenuPresenter.updateMenuView(true);
431 }
432 }
433
Adam Powellb80d3322011-07-15 21:33:11 -0700434 public boolean hasExpandedActionView() {
435 return mExpandedMenuPresenter != null &&
436 mExpandedMenuPresenter.mCurrentExpandedItem != null;
437 }
438
439 public void collapseActionView() {
440 final MenuItemImpl item = mExpandedMenuPresenter == null ? null :
441 mExpandedMenuPresenter.mCurrentExpandedItem;
442 if (item != null) {
443 item.collapseActionView();
444 }
445 }
446
Adam Powell33b97432010-04-20 10:01:14 -0700447 public void setCustomNavigationView(View view) {
Adam Powell9ab97872010-10-26 21:47:29 -0700448 final boolean showCustom = (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0;
449 if (mCustomNavView != null && showCustom) {
450 removeView(mCustomNavView);
451 }
Adam Powella4082912010-06-04 18:34:02 -0700452 mCustomNavView = view;
Adam Powell9ab97872010-10-26 21:47:29 -0700453 if (mCustomNavView != null && showCustom) {
454 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700455 }
Adam Powell33b97432010-04-20 10:01:14 -0700456 }
Adam Powella7db0372010-06-30 17:08:47 -0700457
Adam Powell33b97432010-04-20 10:01:14 -0700458 public CharSequence getTitle() {
459 return mTitle;
460 }
Adam Powella7db0372010-06-30 17:08:47 -0700461
Adam Powelle92ea342010-07-14 14:45:50 -0700462 /**
463 * Set the action bar title. This will always replace or override window titles.
464 * @param title Title to set
465 *
466 * @see #setWindowTitle(CharSequence)
467 */
Adam Powell33b97432010-04-20 10:01:14 -0700468 public void setTitle(CharSequence title) {
Adam Powelle92ea342010-07-14 14:45:50 -0700469 mUserTitle = true;
470 setTitleImpl(title);
471 }
472
473 /**
474 * Set the window title. A window title will always be replaced or overridden by a user title.
475 * @param title Title to set
476 *
477 * @see #setTitle(CharSequence)
478 */
479 public void setWindowTitle(CharSequence title) {
480 if (!mUserTitle) {
481 setTitleImpl(title);
482 }
483 }
484
485 private void setTitleImpl(CharSequence title) {
Adam Powell33b97432010-04-20 10:01:14 -0700486 mTitle = title;
487 if (mTitleView != null) {
488 mTitleView.setText(title);
Adam Powellb0e217e2011-08-12 11:36:51 -0700489 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700490 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700491 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
492 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700493 }
494 if (mLogoNavItem != null) {
495 mLogoNavItem.setTitle(title);
496 }
497 }
Adam Powella7db0372010-06-30 17:08:47 -0700498
Adam Powell33b97432010-04-20 10:01:14 -0700499 public CharSequence getSubtitle() {
500 return mSubtitle;
501 }
Adam Powella7db0372010-06-30 17:08:47 -0700502
Adam Powell33b97432010-04-20 10:01:14 -0700503 public void setSubtitle(CharSequence subtitle) {
504 mSubtitle = subtitle;
505 if (mSubtitleView != null) {
506 mSubtitleView.setText(subtitle);
Adam Powell04587962010-11-11 22:15:07 -0800507 mSubtitleView.setVisibility(subtitle != null ? VISIBLE : GONE);
Adam Powellb0e217e2011-08-12 11:36:51 -0700508 final boolean visible = mExpandedActionView == null &&
Adam Powell71f34172011-08-11 20:07:11 -0700509 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0 &&
Adam Powellb0e217e2011-08-12 11:36:51 -0700510 (!TextUtils.isEmpty(mTitle) || !TextUtils.isEmpty(mSubtitle));
511 mTitleLayout.setVisibility(visible ? VISIBLE : GONE);
Adam Powell33b97432010-04-20 10:01:14 -0700512 }
513 }
Adam Powella7db0372010-06-30 17:08:47 -0700514
Adam Powellc29f4e52011-07-13 20:40:52 -0700515 public void setHomeButtonEnabled(boolean enable) {
516 mHomeLayout.setEnabled(enable);
517 // Make sure the home button has an accurate content description for accessibility.
518 if (!enable) {
519 mHomeLayout.setContentDescription(null);
520 } else if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
521 mHomeLayout.setContentDescription(mContext.getResources().getText(
522 R.string.action_bar_up_description));
523 } else {
524 mHomeLayout.setContentDescription(mContext.getResources().getText(
525 R.string.action_bar_home_description));
526 }
527 }
528
Adam Powell33b97432010-04-20 10:01:14 -0700529 public void setDisplayOptions(int options) {
Adam Powell82f24e82011-08-18 20:15:20 -0700530 final int flagsChanged = mDisplayOptions == -1 ? -1 : options ^ mDisplayOptions;
Adam Powell33b97432010-04-20 10:01:14 -0700531 mDisplayOptions = options;
Adam Powelldae78242011-04-25 15:23:41 -0700532
Adam Powell33b97432010-04-20 10:01:14 -0700533 if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
Adam Powell54c7d7e2011-06-17 20:30:13 -0700534 final boolean showHome = (options & ActionBar.DISPLAY_SHOW_HOME) != 0;
535 final int vis = showHome ? VISIBLE : GONE;
Adam Powell9ab97872010-10-26 21:47:29 -0700536 mHomeLayout.setVisibility(vis);
537
538 if ((flagsChanged & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
Adam Powellc29f4e52011-07-13 20:40:52 -0700539 final boolean setUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0;
540 mHomeLayout.setUp(setUp);
541
542 // Showing home as up implicitly enables interaction with it.
543 // In honeycomb it was always enabled, so make this transition
544 // a bit easier for developers in the common case.
545 // (It would be silly to show it as up without responding to it.)
546 if (setUp) {
547 setHomeButtonEnabled(true);
548 }
Adam Powella1700782010-05-13 13:27:35 -0700549 }
Adam Powell9ab97872010-10-26 21:47:29 -0700550
Ed Heyl1c603002010-11-18 12:18:23 -0800551 if ((flagsChanged & ActionBar.DISPLAY_USE_LOGO) != 0) {
552 final boolean logoVis = mLogo != null && (options & ActionBar.DISPLAY_USE_LOGO) != 0;
Adam Powell8d02dea2011-05-31 21:35:13 -0700553 mHomeLayout.setIcon(logoVis ? mLogo : mIcon);
Adam Powell9ab97872010-10-26 21:47:29 -0700554 }
555
556 if ((flagsChanged & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
557 if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
558 initTitle();
559 } else {
560 removeView(mTitleLayout);
561 }
562 }
563
Adam Powell15a16a82011-06-20 10:35:27 -0700564 if (mTitleLayout != null && (flagsChanged &
Adam Powell54c7d7e2011-06-17 20:30:13 -0700565 (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) {
Adam Powellb1e2f252011-08-22 17:42:12 -0700566 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
567 mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
568 mTitleLayout.setEnabled(!showHome && homeAsUp);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700569 }
570
Adam Powell9ab97872010-10-26 21:47:29 -0700571 if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
572 if ((options & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
573 addView(mCustomNavView);
574 } else {
575 removeView(mCustomNavView);
576 }
Adam Powella1700782010-05-13 13:27:35 -0700577 }
578
Adam Powell33b97432010-04-20 10:01:14 -0700579 requestLayout();
580 } else {
581 invalidate();
582 }
Adam Powellf3cd1d92011-04-26 17:31:52 -0700583
584 // Make sure the home button has an accurate content description for accessibility.
Adam Powellc29f4e52011-07-13 20:40:52 -0700585 if (!mHomeLayout.isEnabled()) {
Adam Powellf3cd1d92011-04-26 17:31:52 -0700586 mHomeLayout.setContentDescription(null);
587 } else if ((options & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
588 mHomeLayout.setContentDescription(mContext.getResources().getText(
589 R.string.action_bar_up_description));
590 } else {
591 mHomeLayout.setContentDescription(mContext.getResources().getText(
592 R.string.action_bar_home_description));
593 }
Adam Powell33b97432010-04-20 10:01:14 -0700594 }
595
Adam Powell1969b872011-03-22 11:52:48 -0700596 public void setIcon(Drawable icon) {
597 mIcon = icon;
598 if (icon != null &&
599 ((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700600 mHomeLayout.setIcon(icon);
Adam Powell1969b872011-03-22 11:52:48 -0700601 }
602 }
603
Adam Powell45c515b2011-04-21 18:50:20 -0700604 public void setIcon(int resId) {
Adam Powellf2b09612011-08-12 14:18:04 -0700605 setIcon(mContext.getResources().getDrawable(resId));
Adam Powell45c515b2011-04-21 18:50:20 -0700606 }
607
Adam Powell1969b872011-03-22 11:52:48 -0700608 public void setLogo(Drawable logo) {
609 mLogo = logo;
610 if (logo != null && (mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) != 0) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700611 mHomeLayout.setIcon(logo);
Adam Powell1969b872011-03-22 11:52:48 -0700612 }
613 }
614
Adam Powell45c515b2011-04-21 18:50:20 -0700615 public void setLogo(int resId) {
Adam Powell29764ea2011-08-04 13:12:01 -0700616 setLogo(mContext.getResources().getDrawable(resId));
Adam Powell45c515b2011-04-21 18:50:20 -0700617 }
618
Adam Powell33b97432010-04-20 10:01:14 -0700619 public void setNavigationMode(int mode) {
Adam Powella1700782010-05-13 13:27:35 -0700620 final int oldMode = mNavigationMode;
621 if (mode != oldMode) {
622 switch (oldMode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700623 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powellc3076422011-06-01 18:19:04 -0700624 if (mListNavLayout != null) {
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800625 removeView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700626 }
627 break;
Adam Powell661c9082010-07-02 10:09:44 -0700628 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700629 if (mTabScrollView != null && mIncludeTabs) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700630 removeView(mTabScrollView);
Adam Powell661c9082010-07-02 10:09:44 -0700631 }
Adam Powella1700782010-05-13 13:27:35 -0700632 }
633
634 switch (mode) {
Adam Powell9ab97872010-10-26 21:47:29 -0700635 case ActionBar.NAVIGATION_MODE_LIST:
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800636 if (mSpinner == null) {
637 mSpinner = new Spinner(mContext, null,
638 com.android.internal.R.attr.actionDropDownStyle);
639 mListNavLayout = new LinearLayout(mContext, null,
640 com.android.internal.R.attr.actionBarTabBarStyle);
641 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
Adam Powelle7d46842011-01-13 21:36:09 -0800642 LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800643 params.gravity = Gravity.CENTER;
644 mListNavLayout.addView(mSpinner, params);
645 }
646 if (mSpinner.getAdapter() != mSpinnerAdapter) {
647 mSpinner.setAdapter(mSpinnerAdapter);
648 }
Adam Powella4082912010-06-04 18:34:02 -0700649 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
Adam Powell3f7f7ac2010-12-05 16:44:38 -0800650 addView(mListNavLayout);
Adam Powella4082912010-06-04 18:34:02 -0700651 break;
Adam Powell661c9082010-07-02 10:09:44 -0700652 case ActionBar.NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -0700653 if (mTabScrollView != null && mIncludeTabs) {
Adam Powelldae78242011-04-25 15:23:41 -0700654 addView(mTabScrollView);
655 }
Adam Powell661c9082010-07-02 10:09:44 -0700656 break;
Adam Powella1700782010-05-13 13:27:35 -0700657 }
Adam Powell33b97432010-04-20 10:01:14 -0700658 mNavigationMode = mode;
659 requestLayout();
660 }
661 }
Adam Powelldae78242011-04-25 15:23:41 -0700662
Adam Powella4082912010-06-04 18:34:02 -0700663 public void setDropdownAdapter(SpinnerAdapter adapter) {
Adam Powell9ab97872010-10-26 21:47:29 -0700664 mSpinnerAdapter = adapter;
665 if (mSpinner != null) {
666 mSpinner.setAdapter(adapter);
667 }
668 }
669
670 public SpinnerAdapter getDropdownAdapter() {
671 return mSpinnerAdapter;
Adam Powella4082912010-06-04 18:34:02 -0700672 }
Adam Powell17809772010-07-21 13:25:11 -0700673
674 public void setDropdownSelectedPosition(int position) {
675 mSpinner.setSelection(position);
676 }
677
678 public int getDropdownSelectedPosition() {
679 return mSpinner.getSelectedItemPosition();
680 }
681
Adam Powell33b97432010-04-20 10:01:14 -0700682 public View getCustomNavigationView() {
Adam Powella4082912010-06-04 18:34:02 -0700683 return mCustomNavView;
Adam Powell33b97432010-04-20 10:01:14 -0700684 }
685
686 public int getNavigationMode() {
687 return mNavigationMode;
688 }
689
690 public int getDisplayOptions() {
691 return mDisplayOptions;
692 }
Adam Powella7db0372010-06-30 17:08:47 -0700693
694 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -0700695 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
Adam Powella7db0372010-06-30 17:08:47 -0700696 // Used by custom nav views if they don't supply layout params. Everything else
697 // added to an ActionBarView should have them already.
Adam Powell9ab97872010-10-26 21:47:29 -0700698 return new ActionBar.LayoutParams(DEFAULT_CUSTOM_GRAVITY);
Adam Powella7db0372010-06-30 17:08:47 -0700699 }
700
Adam Powell33b97432010-04-20 10:01:14 -0700701 @Override
702 protected void onFinishInflate() {
703 super.onFinishInflate();
704
Adam Powell9ab97872010-10-26 21:47:29 -0700705 addView(mHomeLayout);
706
Adam Powell9ab97872010-10-26 21:47:29 -0700707 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
708 final ViewParent parent = mCustomNavView.getParent();
709 if (parent != this) {
710 if (parent instanceof ViewGroup) {
711 ((ViewGroup) parent).removeView(mCustomNavView);
712 }
Adam Powella4082912010-06-04 18:34:02 -0700713 addView(mCustomNavView);
Adam Powell33b97432010-04-20 10:01:14 -0700714 }
Adam Powell33b97432010-04-20 10:01:14 -0700715 }
716 }
Adam Powellc8b0b002011-06-23 14:39:05 -0700717
Adam Powella1700782010-05-13 13:27:35 -0700718 private void initTitle() {
Adam Powell15a16a82011-06-20 10:35:27 -0700719 if (mTitleLayout == null) {
720 LayoutInflater inflater = LayoutInflater.from(getContext());
Adam Powell9e58df52011-08-15 17:06:49 -0700721 mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item,
722 this, false);
Adam Powell15a16a82011-06-20 10:35:27 -0700723 mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
724 mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
725 mTitleUpView = (View) mTitleLayout.findViewById(R.id.up);
Adam Powell54c7d7e2011-06-17 20:30:13 -0700726
Adam Powell15a16a82011-06-20 10:35:27 -0700727 mTitleLayout.setOnClickListener(mUpClickListener);
Adam Powelle2194442010-08-12 18:13:03 -0700728
Adam Powell15a16a82011-06-20 10:35:27 -0700729 if (mTitleStyleRes != 0) {
730 mTitleView.setTextAppearance(mContext, mTitleStyleRes);
731 }
732 if (mTitle != null) {
733 mTitleView.setText(mTitle);
734 }
Adam Powelle2194442010-08-12 18:13:03 -0700735
Adam Powell15a16a82011-06-20 10:35:27 -0700736 if (mSubtitleStyleRes != 0) {
737 mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
738 }
739 if (mSubtitle != null) {
740 mSubtitleView.setText(mSubtitle);
741 mSubtitleView.setVisibility(VISIBLE);
742 }
743
744 final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
Adam Powellb1e2f252011-08-22 17:42:12 -0700745 final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0;
746 mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
747 mTitleLayout.setEnabled(homeAsUp && !showHome);
Adam Powell0e94b512010-06-29 17:58:20 -0700748 }
Adam Powelle2194442010-08-12 18:13:03 -0700749
Adam Powell9e58df52011-08-15 17:06:49 -0700750 addView(mTitleLayout);
Adam Powell82f24e82011-08-18 20:15:20 -0700751 if (mExpandedActionView != null ||
752 (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
753 // Don't show while in expanded mode or with empty text
Adam Powell71f34172011-08-11 20:07:11 -0700754 mTitleLayout.setVisibility(GONE);
755 }
Adam Powella1700782010-05-13 13:27:35 -0700756 }
Adam Powell33b97432010-04-20 10:01:14 -0700757
Adam Powelle2194442010-08-12 18:13:03 -0700758 public void setContextView(ActionBarContextView view) {
759 mContextView = view;
760 }
761
Adam Powelld21aa122011-05-27 13:09:52 -0700762 public void setCollapsable(boolean collapsable) {
763 mIsCollapsable = collapsable;
764 }
765
Adam Powellf6ce6a92011-06-29 10:25:01 -0700766 public boolean isCollapsed() {
767 return mIsCollapsed;
768 }
769
Adam Powell33b97432010-04-20 10:01:14 -0700770 @Override
771 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Adam Powelld21aa122011-05-27 13:09:52 -0700772 final int childCount = getChildCount();
773 if (mIsCollapsable) {
774 int visibleChildren = 0;
775 for (int i = 0; i < childCount; i++) {
776 final View child = getChildAt(i);
777 if (child.getVisibility() != GONE &&
778 !(child == mMenuView && mMenuView.getChildCount() == 0)) {
779 visibleChildren++;
780 }
781 }
782
783 if (visibleChildren == 0) {
784 // No size for an empty action bar when collapsable.
785 setMeasuredDimension(0, 0);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700786 mIsCollapsed = true;
Adam Powelld21aa122011-05-27 13:09:52 -0700787 return;
788 }
789 }
Adam Powellf6ce6a92011-06-29 10:25:01 -0700790 mIsCollapsed = false;
Adam Powelld21aa122011-05-27 13:09:52 -0700791
Adam Powell33b97432010-04-20 10:01:14 -0700792 int widthMode = MeasureSpec.getMode(widthMeasureSpec);
793 if (widthMode != MeasureSpec.EXACTLY) {
794 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
795 "with android:layout_width=\"match_parent\" (or fill_parent)");
796 }
797
798 int heightMode = MeasureSpec.getMode(heightMeasureSpec);
799 if (heightMode != MeasureSpec.AT_MOST) {
800 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
801 "with android:layout_height=\"wrap_content\"");
802 }
803
804 int contentWidth = MeasureSpec.getSize(widthMeasureSpec);
Adam Powelle2194442010-08-12 18:13:03 -0700805
806 int maxHeight = mContentHeight > 0 ?
807 mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
Adam Powell33b97432010-04-20 10:01:14 -0700808
Adam Powelle2194442010-08-12 18:13:03 -0700809 final int verticalPadding = getPaddingTop() + getPaddingBottom();
Adam Powell9ab97872010-10-26 21:47:29 -0700810 final int paddingLeft = getPaddingLeft();
811 final int paddingRight = getPaddingRight();
Adam Powelle2194442010-08-12 18:13:03 -0700812 final int height = maxHeight - verticalPadding;
Adam Powella1700782010-05-13 13:27:35 -0700813 final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
Adam Powell33b97432010-04-20 10:01:14 -0700814
Adam Powell9ab97872010-10-26 21:47:29 -0700815 int availableWidth = contentWidth - paddingLeft - paddingRight;
816 int leftOfCenter = availableWidth / 2;
817 int rightOfCenter = leftOfCenter;
818
Adam Powellb1e2f252011-08-22 17:42:12 -0700819 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powell8d02dea2011-05-31 21:35:13 -0700820
821 if (homeLayout.getVisibility() != GONE) {
Adam Powell9a5cc282011-08-28 16:18:16 -0700822 final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams();
Adam Powell0d5d1b7e2011-06-22 17:40:40 -0700823 int homeWidthSpec;
824 if (lp.width < 0) {
825 homeWidthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
826 } else {
827 homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
828 }
829 homeLayout.measure(homeWidthSpec,
Ed Heyl1c603002010-11-18 12:18:23 -0800830 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
Adam Powellb1e2f252011-08-22 17:42:12 -0700831 final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getLeftOffset();
Adam Powell1b4a1622011-05-17 12:13:13 -0700832 availableWidth = Math.max(0, availableWidth - homeWidth);
833 leftOfCenter = Math.max(0, availableWidth - homeWidth);
Adam Powell33b97432010-04-20 10:01:14 -0700834 }
Adam Powell96675b12010-06-10 18:58:59 -0700835
Adam Powell9b4bee02011-04-27 19:24:47 -0700836 if (mMenuView != null && mMenuView.getParent() == this) {
Adam Powell96675b12010-06-10 18:58:59 -0700837 availableWidth = measureChildView(mMenuView, availableWidth,
Adam Powell7ade1be2010-06-17 12:51:21 -0700838 childSpecHeight, 0);
Adam Powell1b4a1622011-05-17 12:13:13 -0700839 rightOfCenter = Math.max(0, rightOfCenter - mMenuView.getMeasuredWidth());
Adam Powell33b97432010-04-20 10:01:14 -0700840 }
Adam Powell9ab97872010-10-26 21:47:29 -0700841
Adam Powellaa8e509b2011-08-25 09:29:21 -0700842 if (mIndeterminateProgressView != null &&
843 mIndeterminateProgressView.getVisibility() != GONE) {
844 availableWidth = measureChildView(mIndeterminateProgressView, availableWidth,
845 childSpecHeight, 0);
846 rightOfCenter = Math.max(0,
847 rightOfCenter - mIndeterminateProgressView.getMeasuredWidth());
848 }
Adam Powell9ab97872010-10-26 21:47:29 -0700849
Adam Powellaa8e509b2011-08-25 09:29:21 -0700850 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
851 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
852
853 if (mExpandedActionView == null) {
Adam Powell8d02dea2011-05-31 21:35:13 -0700854 switch (mNavigationMode) {
855 case ActionBar.NAVIGATION_MODE_LIST:
856 if (mListNavLayout != null) {
857 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
858 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
859 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
860 mListNavLayout.measure(
861 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
862 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
863 final int listNavWidth = mListNavLayout.getMeasuredWidth();
864 availableWidth = Math.max(0, availableWidth - listNavWidth);
865 leftOfCenter = Math.max(0, leftOfCenter - listNavWidth);
866 }
867 break;
868 case ActionBar.NAVIGATION_MODE_TABS:
869 if (mTabScrollView != null) {
870 final int itemPaddingSize = showTitle ? mItemPadding * 2 : mItemPadding;
871 availableWidth = Math.max(0, availableWidth - itemPaddingSize);
872 leftOfCenter = Math.max(0, leftOfCenter - itemPaddingSize);
873 mTabScrollView.measure(
874 MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
875 MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
876 final int tabWidth = mTabScrollView.getMeasuredWidth();
877 availableWidth = Math.max(0, availableWidth - tabWidth);
878 leftOfCenter = Math.max(0, leftOfCenter - tabWidth);
879 }
880 break;
Adam Powell33b97432010-04-20 10:01:14 -0700881 }
Adam Powell33b97432010-04-20 10:01:14 -0700882 }
883
Adam Powell8d02dea2011-05-31 21:35:13 -0700884 View customView = null;
885 if (mExpandedActionView != null) {
886 customView = mExpandedActionView;
887 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
888 mCustomNavView != null) {
889 customView = mCustomNavView;
890 }
891
892 if (customView != null) {
Adam Powell9a5cc282011-08-28 16:18:16 -0700893 final ViewGroup.LayoutParams lp = generateLayoutParams(customView.getLayoutParams());
Adam Powell9ab97872010-10-26 21:47:29 -0700894 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
895 (ActionBar.LayoutParams) lp : null;
896
897 int horizontalMargin = 0;
898 int verticalMargin = 0;
899 if (ablp != null) {
900 horizontalMargin = ablp.leftMargin + ablp.rightMargin;
901 verticalMargin = ablp.topMargin + ablp.bottomMargin;
902 }
903
904 // If the action bar is wrapping to its content height, don't allow a custom
905 // view to MATCH_PARENT.
906 int customNavHeightMode;
907 if (mContentHeight <= 0) {
908 customNavHeightMode = MeasureSpec.AT_MOST;
909 } else {
910 customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
911 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
912 }
913 final int customNavHeight = Math.max(0,
914 (lp.height >= 0 ? Math.min(lp.height, height) : height) - verticalMargin);
915
916 final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
917 MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
918 int customNavWidth = Math.max(0,
919 (lp.width >= 0 ? Math.min(lp.width, availableWidth) : availableWidth)
920 - horizontalMargin);
921 final int hgrav = (ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY) &
922 Gravity.HORIZONTAL_GRAVITY_MASK;
923
924 // Centering a custom view is treated specially; we try to center within the whole
925 // action bar rather than in the available space.
926 if (hgrav == Gravity.CENTER_HORIZONTAL && lp.width == LayoutParams.MATCH_PARENT) {
927 customNavWidth = Math.min(leftOfCenter, rightOfCenter) * 2;
928 }
929
Adam Powell8d02dea2011-05-31 21:35:13 -0700930 customView.measure(
Adam Powell9ab97872010-10-26 21:47:29 -0700931 MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
932 MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
Adam Powellaa8e509b2011-08-25 09:29:21 -0700933 availableWidth -= horizontalMargin + customView.getMeasuredWidth();
934 }
935
936 if (mExpandedActionView == null && showTitle) {
937 availableWidth = measureChildView(mTitleLayout, availableWidth,
938 MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
939 leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
Adam Powell9ab97872010-10-26 21:47:29 -0700940 }
941
Adam Powelle2194442010-08-12 18:13:03 -0700942 if (mContentHeight <= 0) {
943 int measuredHeight = 0;
Adam Powelld21aa122011-05-27 13:09:52 -0700944 for (int i = 0; i < childCount; i++) {
Adam Powelle2194442010-08-12 18:13:03 -0700945 View v = getChildAt(i);
946 int paddedViewHeight = v.getMeasuredHeight() + verticalPadding;
947 if (paddedViewHeight > measuredHeight) {
948 measuredHeight = paddedViewHeight;
949 }
950 }
951 setMeasuredDimension(contentWidth, measuredHeight);
952 } else {
953 setMeasuredDimension(contentWidth, maxHeight);
954 }
955
956 if (mContextView != null) {
Adam Powell425689e2011-09-08 18:09:33 -0700957 mContextView.setContentHeight(getMeasuredHeight());
Adam Powelle2194442010-08-12 18:13:03 -0700958 }
Adam Powell6af97e12010-11-11 21:11:53 -0800959
960 if (mProgressView != null && mProgressView.getVisibility() != GONE) {
961 mProgressView.measure(MeasureSpec.makeMeasureSpec(
962 contentWidth - mProgressBarPadding * 2, MeasureSpec.EXACTLY),
963 MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
964 }
Adam Powell33b97432010-04-20 10:01:14 -0700965 }
966
Adam Powell33b97432010-04-20 10:01:14 -0700967 @Override
968 protected void onLayout(boolean changed, int l, int t, int r, int b) {
969 int x = getPaddingLeft();
970 final int y = getPaddingTop();
971 final int contentHeight = b - t - getPaddingTop() - getPaddingBottom();
972
Adam Powelld21aa122011-05-27 13:09:52 -0700973 if (contentHeight <= 0) {
974 // Nothing to do if we can't see anything.
975 return;
976 }
977
Adam Powellb1e2f252011-08-22 17:42:12 -0700978 HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
Adam Powell8d02dea2011-05-31 21:35:13 -0700979 if (homeLayout.getVisibility() != GONE) {
Adam Powellb1e2f252011-08-22 17:42:12 -0700980 final int leftOffset = homeLayout.getLeftOffset();
981 x += positionChild(homeLayout, x + leftOffset, y, contentHeight) + leftOffset;
Adam Powell9ab97872010-10-26 21:47:29 -0700982 }
983
Adam Powell8d02dea2011-05-31 21:35:13 -0700984 if (mExpandedActionView == null) {
985 final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
Adam Powell15a16a82011-06-20 10:35:27 -0700986 (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
Adam Powell8d02dea2011-05-31 21:35:13 -0700987 if (showTitle) {
988 x += positionChild(mTitleLayout, x, y, contentHeight);
Adam Powella4082912010-06-04 18:34:02 -0700989 }
Adam Powell8d02dea2011-05-31 21:35:13 -0700990
991 switch (mNavigationMode) {
992 case ActionBar.NAVIGATION_MODE_STANDARD:
993 break;
994 case ActionBar.NAVIGATION_MODE_LIST:
995 if (mListNavLayout != null) {
996 if (showTitle) x += mItemPadding;
997 x += positionChild(mListNavLayout, x, y, contentHeight) + mItemPadding;
998 }
999 break;
1000 case ActionBar.NAVIGATION_MODE_TABS:
1001 if (mTabScrollView != null) {
1002 if (showTitle) x += mItemPadding;
1003 x += positionChild(mTabScrollView, x, y, contentHeight) + mItemPadding;
1004 }
1005 break;
Adam Powell661c9082010-07-02 10:09:44 -07001006 }
Adam Powell33b97432010-04-20 10:01:14 -07001007 }
1008
Adam Powell9ab97872010-10-26 21:47:29 -07001009 int menuLeft = r - l - getPaddingRight();
Adam Powell9b4bee02011-04-27 19:24:47 -07001010 if (mMenuView != null && mMenuView.getParent() == this) {
Adam Powell9ab97872010-10-26 21:47:29 -07001011 positionChildInverse(mMenuView, menuLeft, y, contentHeight);
1012 menuLeft -= mMenuView.getMeasuredWidth();
1013 }
1014
Adam Powell6af97e12010-11-11 21:11:53 -08001015 if (mIndeterminateProgressView != null &&
1016 mIndeterminateProgressView.getVisibility() != GONE) {
1017 positionChildInverse(mIndeterminateProgressView, menuLeft, y, contentHeight);
1018 menuLeft -= mIndeterminateProgressView.getMeasuredWidth();
1019 }
1020
Adam Powell8d02dea2011-05-31 21:35:13 -07001021 View customView = null;
1022 if (mExpandedActionView != null) {
1023 customView = mExpandedActionView;
1024 } else if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 &&
1025 mCustomNavView != null) {
1026 customView = mCustomNavView;
1027 }
1028 if (customView != null) {
Adam Powell9a5cc282011-08-28 16:18:16 -07001029 ViewGroup.LayoutParams lp = customView.getLayoutParams();
Adam Powell9ab97872010-10-26 21:47:29 -07001030 final ActionBar.LayoutParams ablp = lp instanceof ActionBar.LayoutParams ?
1031 (ActionBar.LayoutParams) lp : null;
1032
1033 final int gravity = ablp != null ? ablp.gravity : DEFAULT_CUSTOM_GRAVITY;
Adam Powell8d02dea2011-05-31 21:35:13 -07001034 final int navWidth = customView.getMeasuredWidth();
Adam Powell9ab97872010-10-26 21:47:29 -07001035
1036 int topMargin = 0;
1037 int bottomMargin = 0;
1038 if (ablp != null) {
1039 x += ablp.leftMargin;
1040 menuLeft -= ablp.rightMargin;
1041 topMargin = ablp.topMargin;
1042 bottomMargin = ablp.bottomMargin;
1043 }
1044
1045 int hgravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
1046 // See if we actually have room to truly center; if not push against left or right.
1047 if (hgravity == Gravity.CENTER_HORIZONTAL) {
1048 final int centeredLeft = ((mRight - mLeft) - navWidth) / 2;
1049 if (centeredLeft < x) {
1050 hgravity = Gravity.LEFT;
1051 } else if (centeredLeft + navWidth > menuLeft) {
1052 hgravity = Gravity.RIGHT;
1053 }
Adam Powell7a2424d2011-08-18 11:59:11 -07001054 } else if (gravity == -1) {
1055 hgravity = Gravity.LEFT;
Adam Powell9ab97872010-10-26 21:47:29 -07001056 }
1057
1058 int xpos = 0;
1059 switch (hgravity) {
1060 case Gravity.CENTER_HORIZONTAL:
1061 xpos = ((mRight - mLeft) - navWidth) / 2;
1062 break;
1063 case Gravity.LEFT:
1064 xpos = x;
1065 break;
1066 case Gravity.RIGHT:
1067 xpos = menuLeft - navWidth;
1068 break;
1069 }
1070
Adam Powell7a2424d2011-08-18 11:59:11 -07001071 int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
1072
1073 if (gravity == -1) {
1074 vgravity = Gravity.CENTER_VERTICAL;
1075 }
1076
Adam Powell9ab97872010-10-26 21:47:29 -07001077 int ypos = 0;
Adam Powell7a2424d2011-08-18 11:59:11 -07001078 switch (vgravity) {
Adam Powell9ab97872010-10-26 21:47:29 -07001079 case Gravity.CENTER_VERTICAL:
Adam Powell6556c072011-06-24 17:16:57 -07001080 final int paddedTop = getPaddingTop();
1081 final int paddedBottom = mBottom - mTop - getPaddingBottom();
Adam Powell8d02dea2011-05-31 21:35:13 -07001082 ypos = ((paddedBottom - paddedTop) - customView.getMeasuredHeight()) / 2;
Adam Powell9ab97872010-10-26 21:47:29 -07001083 break;
1084 case Gravity.TOP:
1085 ypos = getPaddingTop() + topMargin;
1086 break;
1087 case Gravity.BOTTOM:
Adam Powell8d02dea2011-05-31 21:35:13 -07001088 ypos = getHeight() - getPaddingBottom() - customView.getMeasuredHeight()
Adam Powell9ab97872010-10-26 21:47:29 -07001089 - bottomMargin;
1090 break;
1091 }
Adam Powell6556c072011-06-24 17:16:57 -07001092 final int customWidth = customView.getMeasuredWidth();
1093 customView.layout(xpos, ypos, xpos + customWidth,
1094 ypos + customView.getMeasuredHeight());
1095 x += customWidth;
Adam Powell33b97432010-04-20 10:01:14 -07001096 }
Adam Powell6af97e12010-11-11 21:11:53 -08001097
1098 if (mProgressView != null) {
1099 mProgressView.bringToFront();
1100 final int halfProgressHeight = mProgressView.getMeasuredHeight() / 2;
1101 mProgressView.layout(mProgressBarPadding, -halfProgressHeight,
1102 mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight);
1103 }
Adam Powell33b97432010-04-20 10:01:14 -07001104 }
1105
Adam Powell8d02dea2011-05-31 21:35:13 -07001106 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001107 public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
Adam Powellaad47fd2011-08-17 17:33:33 -07001108 return new ActionBar.LayoutParams(getContext(), attrs);
1109 }
1110
1111 @Override
Adam Powell9a5cc282011-08-28 16:18:16 -07001112 public ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
Adam Powell8d02dea2011-05-31 21:35:13 -07001113 if (lp == null) {
1114 lp = generateDefaultLayoutParams();
1115 }
1116 return lp;
1117 }
1118
1119 @Override
1120 public Parcelable onSaveInstanceState() {
1121 Parcelable superState = super.onSaveInstanceState();
1122 SavedState state = new SavedState(superState);
1123
1124 if (mExpandedMenuPresenter != null && mExpandedMenuPresenter.mCurrentExpandedItem != null) {
1125 state.expandedMenuItemId = mExpandedMenuPresenter.mCurrentExpandedItem.getItemId();
1126 }
1127
1128 state.isOverflowOpen = isOverflowMenuShowing();
1129
1130 return state;
1131 }
1132
1133 @Override
1134 public void onRestoreInstanceState(Parcelable p) {
1135 SavedState state = (SavedState) p;
1136
1137 super.onRestoreInstanceState(state.getSuperState());
1138
1139 if (state.expandedMenuItemId != 0 &&
1140 mExpandedMenuPresenter != null && mOptionsMenu != null) {
1141 final MenuItem item = mOptionsMenu.findItem(state.expandedMenuItemId);
1142 if (item != null) {
1143 item.expandActionView();
1144 }
1145 }
1146
1147 if (state.isOverflowOpen) {
1148 postShowOverflowMenu();
1149 }
1150 }
1151
1152 static class SavedState extends BaseSavedState {
1153 int expandedMenuItemId;
1154 boolean isOverflowOpen;
1155
1156 SavedState(Parcelable superState) {
1157 super(superState);
1158 }
1159
1160 private SavedState(Parcel in) {
1161 super(in);
1162 expandedMenuItemId = in.readInt();
1163 isOverflowOpen = in.readInt() != 0;
1164 }
1165
1166 @Override
1167 public void writeToParcel(Parcel out, int flags) {
1168 super.writeToParcel(out, flags);
1169 out.writeInt(expandedMenuItemId);
1170 out.writeInt(isOverflowOpen ? 1 : 0);
1171 }
1172
1173 public static final Parcelable.Creator<SavedState> CREATOR =
1174 new Parcelable.Creator<SavedState>() {
1175 public SavedState createFromParcel(Parcel in) {
1176 return new SavedState(in);
1177 }
1178
1179 public SavedState[] newArray(int size) {
1180 return new SavedState[size];
1181 }
1182 };
1183 }
1184
Adam Powell2b0952b2011-03-09 00:15:38 -08001185 private static class HomeView extends FrameLayout {
1186 private View mUpView;
Adam Powell8d02dea2011-05-31 21:35:13 -07001187 private ImageView mIconView;
Adam Powellb1e2f252011-08-22 17:42:12 -07001188 private int mUpWidth;
Adam Powell2b0952b2011-03-09 00:15:38 -08001189
1190 public HomeView(Context context) {
1191 this(context, null);
1192 }
1193
1194 public HomeView(Context context, AttributeSet attrs) {
1195 super(context, attrs);
1196 }
1197
Adam Powell8d02dea2011-05-31 21:35:13 -07001198 public void setUp(boolean isUp) {
1199 mUpView.setVisibility(isUp ? VISIBLE : GONE);
1200 }
1201
1202 public void setIcon(Drawable icon) {
1203 mIconView.setImageDrawable(icon);
1204 }
1205
Adam Powell2b0952b2011-03-09 00:15:38 -08001206 @Override
Adam Powell7bc3ca02011-08-26 18:29:58 -07001207 public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
1208 onPopulateAccessibilityEvent(event);
1209 return true;
1210 }
1211
1212 @Override
1213 public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1214 super.onPopulateAccessibilityEvent(event);
1215 final CharSequence cdesc = getContentDescription();
1216 if (!TextUtils.isEmpty(cdesc)) {
1217 event.getText().add(cdesc);
1218 }
1219 }
1220
1221 @Override
1222 public boolean dispatchHoverEvent(MotionEvent event) {
1223 // Don't allow children to hover; we want this to be treated as a single component.
1224 return onHoverEvent(event);
1225 }
1226
1227 @Override
Adam Powell2b0952b2011-03-09 00:15:38 -08001228 protected void onFinishInflate() {
1229 mUpView = findViewById(com.android.internal.R.id.up);
1230 mIconView = (ImageView) findViewById(com.android.internal.R.id.home);
1231 }
1232
Adam Powellb1e2f252011-08-22 17:42:12 -07001233 public int getLeftOffset() {
1234 return mUpView.getVisibility() == GONE ? mUpWidth : 0;
Adam Powell8d02dea2011-05-31 21:35:13 -07001235 }
1236
Adam Powell2b0952b2011-03-09 00:15:38 -08001237 @Override
1238 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1239 measureChildWithMargins(mUpView, widthMeasureSpec, 0, heightMeasureSpec, 0);
1240 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
Adam Powellb1e2f252011-08-22 17:42:12 -07001241 mUpWidth = upLp.leftMargin + mUpView.getMeasuredWidth() + upLp.rightMargin;
1242 int width = mUpView.getVisibility() == GONE ? 0 : mUpWidth;
Adam Powell2b0952b2011-03-09 00:15:38 -08001243 int height = upLp.topMargin + mUpView.getMeasuredHeight() + upLp.bottomMargin;
1244 measureChildWithMargins(mIconView, widthMeasureSpec, width, heightMeasureSpec, 0);
1245 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1246 width += iconLp.leftMargin + mIconView.getMeasuredWidth() + iconLp.rightMargin;
1247 height = Math.max(height,
1248 iconLp.topMargin + mIconView.getMeasuredHeight() + iconLp.bottomMargin);
Adam Powell0d5d1b7e2011-06-22 17:40:40 -07001249
1250 final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
1251 final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
1252 final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
1253 final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
1254
1255 switch (widthMode) {
1256 case MeasureSpec.AT_MOST:
1257 width = Math.min(width, widthSize);
1258 break;
1259 case MeasureSpec.EXACTLY:
1260 width = widthSize;
1261 break;
1262 case MeasureSpec.UNSPECIFIED:
1263 default:
1264 break;
1265 }
1266 switch (heightMode) {
1267 case MeasureSpec.AT_MOST:
1268 height = Math.min(height, heightSize);
1269 break;
1270 case MeasureSpec.EXACTLY:
1271 height = heightSize;
1272 break;
1273 case MeasureSpec.UNSPECIFIED:
1274 default:
1275 break;
1276 }
Adam Powell2b0952b2011-03-09 00:15:38 -08001277 setMeasuredDimension(width, height);
1278 }
1279
1280 @Override
1281 protected void onLayout(boolean changed, int l, int t, int r, int b) {
1282 final int vCenter = (b - t) / 2;
1283 int width = r - l;
Adam Powellc8b0b002011-06-23 14:39:05 -07001284 int upOffset = 0;
Adam Powell2b0952b2011-03-09 00:15:38 -08001285 if (mUpView.getVisibility() != GONE) {
1286 final LayoutParams upLp = (LayoutParams) mUpView.getLayoutParams();
1287 final int upHeight = mUpView.getMeasuredHeight();
1288 final int upWidth = mUpView.getMeasuredWidth();
Adam Powellc8b0b002011-06-23 14:39:05 -07001289 final int upTop = vCenter - upHeight / 2;
1290 mUpView.layout(0, upTop, upWidth, upTop + upHeight);
1291 upOffset = upLp.leftMargin + upWidth + upLp.rightMargin;
Adam Powell2b0952b2011-03-09 00:15:38 -08001292 width -= upOffset;
1293 l += upOffset;
1294 }
1295 final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
1296 final int iconHeight = mIconView.getMeasuredHeight();
1297 final int iconWidth = mIconView.getMeasuredWidth();
1298 final int hCenter = (r - l) / 2;
Adam Powellc8b0b002011-06-23 14:39:05 -07001299 final int iconLeft = upOffset + Math.max(iconLp.leftMargin, hCenter - iconWidth / 2);
1300 final int iconTop = Math.max(iconLp.topMargin, vCenter - iconHeight / 2);
Adam Powell2b0952b2011-03-09 00:15:38 -08001301 mIconView.layout(iconLeft, iconTop, iconLeft + iconWidth, iconTop + iconHeight);
1302 }
1303 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001304
1305 private class ExpandedActionViewMenuPresenter implements MenuPresenter {
1306 MenuBuilder mMenu;
1307 MenuItemImpl mCurrentExpandedItem;
1308
1309 @Override
1310 public void initForMenu(Context context, MenuBuilder menu) {
1311 // Clear the expanded action view when menus change.
Adam Powell6b0e97c2011-08-03 12:06:32 -07001312 if (mMenu != null && mCurrentExpandedItem != null) {
1313 mMenu.collapseItemActionView(mCurrentExpandedItem);
Adam Powell8d02dea2011-05-31 21:35:13 -07001314 }
1315 mMenu = menu;
1316 }
1317
1318 @Override
1319 public MenuView getMenuView(ViewGroup root) {
1320 return null;
1321 }
1322
1323 @Override
1324 public void updateMenuView(boolean cleared) {
1325 // Make sure the expanded item we have is still there.
1326 if (mCurrentExpandedItem != null) {
1327 boolean found = false;
Adam Powellf35d0492011-08-17 13:56:47 -07001328
1329 if (mMenu != null) {
1330 final int count = mMenu.size();
1331 for (int i = 0; i < count; i++) {
1332 final MenuItem item = mMenu.getItem(i);
1333 if (item == mCurrentExpandedItem) {
1334 found = true;
1335 break;
1336 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001337 }
1338 }
1339
1340 if (!found) {
1341 // The item we had expanded disappeared. Collapse.
1342 collapseItemActionView(mMenu, mCurrentExpandedItem);
1343 }
1344 }
1345 }
1346
1347 @Override
1348 public void setCallback(Callback cb) {
1349 }
1350
1351 @Override
1352 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
1353 return false;
1354 }
1355
1356 @Override
1357 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1358 }
1359
1360 @Override
1361 public boolean flagActionItems() {
1362 return false;
1363 }
1364
1365 @Override
1366 public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
1367 mExpandedActionView = item.getActionView();
Adam Powell28fa07e2011-07-15 20:17:25 -07001368 mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
Adam Powell8d02dea2011-05-31 21:35:13 -07001369 mCurrentExpandedItem = item;
1370 if (mExpandedActionView.getParent() != ActionBarView.this) {
1371 addView(mExpandedActionView);
1372 }
1373 if (mExpandedHomeLayout.getParent() != ActionBarView.this) {
1374 addView(mExpandedHomeLayout);
1375 }
1376 mHomeLayout.setVisibility(GONE);
Adam Powell15a16a82011-06-20 10:35:27 -07001377 if (mTitleLayout != null) mTitleLayout.setVisibility(GONE);
Adam Powell8d02dea2011-05-31 21:35:13 -07001378 if (mTabScrollView != null) mTabScrollView.setVisibility(GONE);
1379 if (mSpinner != null) mSpinner.setVisibility(GONE);
1380 if (mCustomNavView != null) mCustomNavView.setVisibility(GONE);
1381 requestLayout();
1382 item.setActionViewExpanded(true);
Adam Powell038f1c82011-07-21 14:28:10 -07001383
1384 if (mExpandedActionView instanceof CollapsibleActionView) {
1385 ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
1386 }
Amith Yamasani10da5902011-07-26 16:14:26 -07001387
Adam Powell8d02dea2011-05-31 21:35:13 -07001388 return true;
1389 }
1390
1391 @Override
1392 public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
Amith Yamasani10da5902011-07-26 16:14:26 -07001393 // Do this before detaching the actionview from the hierarchy, in case
1394 // it needs to dismiss the soft keyboard, etc.
1395 if (mExpandedActionView instanceof CollapsibleActionView) {
1396 ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
1397 }
1398
Adam Powell8d02dea2011-05-31 21:35:13 -07001399 removeView(mExpandedActionView);
1400 removeView(mExpandedHomeLayout);
Adam Powellb0e217e2011-08-12 11:36:51 -07001401 mExpandedActionView = null;
Adam Powell8d02dea2011-05-31 21:35:13 -07001402 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
1403 mHomeLayout.setVisibility(VISIBLE);
1404 }
1405 if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
Adam Powell15a16a82011-06-20 10:35:27 -07001406 if (mTitleLayout == null) {
1407 initTitle();
1408 } else {
1409 mTitleLayout.setVisibility(VISIBLE);
1410 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001411 }
1412 if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
1413 mTabScrollView.setVisibility(VISIBLE);
1414 }
1415 if (mSpinner != null && mNavigationMode == ActionBar.NAVIGATION_MODE_LIST) {
1416 mSpinner.setVisibility(VISIBLE);
1417 }
1418 if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
1419 mCustomNavView.setVisibility(VISIBLE);
1420 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001421 mExpandedHomeLayout.setIcon(null);
1422 mCurrentExpandedItem = null;
1423 requestLayout();
1424 item.setActionViewExpanded(false);
Adam Powell038f1c82011-07-21 14:28:10 -07001425
Adam Powell8d02dea2011-05-31 21:35:13 -07001426 return true;
1427 }
Adam Powell11ed1d62011-07-11 21:19:59 -07001428
1429 @Override
1430 public int getId() {
1431 return 0;
1432 }
1433
1434 @Override
1435 public Parcelable onSaveInstanceState() {
1436 return null;
1437 }
1438
1439 @Override
1440 public void onRestoreInstanceState(Parcelable state) {
1441 }
Adam Powell8d02dea2011-05-31 21:35:13 -07001442 }
Adam Powell33b97432010-04-20 10:01:14 -07001443}