blob: 3115effd79dc47dc7d0100ee670d16526b73f1cf [file] [log] [blame]
Adam Powell89e06452010-06-23 20:24:52 -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
17package com.android.internal.app;
18
Adam Powell2c9c9fe2010-07-16 10:17:57 -070019import com.android.internal.view.menu.MenuBuilder;
Adam Powell2c9c9fe2010-07-16 10:17:57 -070020import com.android.internal.view.menu.MenuPopupHelper;
21import com.android.internal.view.menu.SubMenuBuilder;
Adam Powell01feaee2011-02-10 15:05:05 -080022import com.android.internal.widget.ActionBarContainer;
Adam Powell89e06452010-06-23 20:24:52 -070023import com.android.internal.widget.ActionBarContextView;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070024import com.android.internal.widget.ActionBarOverlayLayout;
Adam Powell89e06452010-06-23 20:24:52 -070025import com.android.internal.widget.ActionBarView;
Adam Powellf8ac6b72011-05-23 18:14:09 -070026import com.android.internal.widget.ScrollingTabContainerView;
Adam Powell89e06452010-06-23 20:24:52 -070027
Adam Powelld8b3f2e2010-12-02 13:37:03 -080028import android.animation.Animator;
Adam Powelld8b3f2e2010-12-02 13:37:03 -080029import android.animation.Animator.AnimatorListener;
Adam Powell07e1f982011-03-24 11:11:15 -070030import android.animation.AnimatorListenerAdapter;
Adam Powelld8b3f2e2010-12-02 13:37:03 -080031import android.animation.AnimatorSet;
Adam Powelle6ec7322010-12-07 15:29:26 -080032import android.animation.ObjectAnimator;
Adam Powell89e06452010-06-23 20:24:52 -070033import android.app.ActionBar;
Adam Powell661c9082010-07-02 10:09:44 -070034import android.app.Activity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070035import android.app.Dialog;
Adam Powell661c9082010-07-02 10:09:44 -070036import android.app.FragmentTransaction;
Adam Powelldec9dfd2010-08-09 15:27:54 -070037import android.content.Context;
Adam Powellf8ac6b72011-05-23 18:14:09 -070038import android.content.res.Configuration;
Adam Powell88ab6972011-07-28 11:25:01 -070039import android.content.res.Resources;
Adam Powell89e06452010-06-23 20:24:52 -070040import android.graphics.drawable.Drawable;
Adam Powellc29f4e52011-07-13 20:40:52 -070041import android.os.Build;
Adam Powell0e94b512010-06-29 17:58:20 -070042import android.os.Handler;
Adam Powell88ab6972011-07-28 11:25:01 -070043import android.util.TypedValue;
Adam Powell6e346362010-07-23 10:18:23 -070044import android.view.ActionMode;
Adam Powell88ab6972011-07-28 11:25:01 -070045import android.view.ContextThemeWrapper;
Adam Powell32555f32010-11-17 13:49:22 -080046import android.view.LayoutInflater;
Adam Powell89e06452010-06-23 20:24:52 -070047import android.view.Menu;
Adam Powell9168f0b2010-08-02 15:46:24 -070048import android.view.MenuInflater;
Adam Powell89e06452010-06-23 20:24:52 -070049import android.view.MenuItem;
50import android.view.View;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070051import android.view.ViewGroup;
Adam Powelle6ec7322010-12-07 15:29:26 -080052import android.view.Window;
Adam Powell86ed4362011-09-14 16:18:53 -070053import android.view.accessibility.AccessibilityEvent;
Adam Powell89e06452010-06-23 20:24:52 -070054import android.widget.SpinnerAdapter;
Adam Powell89e06452010-06-23 20:24:52 -070055
Adam Powell29ed7572010-07-14 16:24:56 -070056import java.lang.ref.WeakReference;
Adam Powell661c9082010-07-02 10:09:44 -070057import java.util.ArrayList;
58
Adam Powell89e06452010-06-23 20:24:52 -070059/**
60 * ActionBarImpl is the ActionBar implementation used
61 * by devices of all screen sizes. If it detects a compatible decor,
62 * it will split contextual modes across both the ActionBarView at
63 * the top of the screen and a horizontal LinearLayout at the bottom
64 * which is normally hidden.
65 */
66public class ActionBarImpl extends ActionBar {
Adam Powelld8145042011-03-24 14:18:27 -070067 private static final String TAG = "ActionBarImpl";
Adam Powell661c9082010-07-02 10:09:44 -070068
Adam Powelldec9dfd2010-08-09 15:27:54 -070069 private Context mContext;
Adam Powell88ab6972011-07-28 11:25:01 -070070 private Context mThemedContext;
Adam Powell661c9082010-07-02 10:09:44 -070071 private Activity mActivity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070072 private Dialog mDialog;
Adam Powell661c9082010-07-02 10:09:44 -070073
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070074 private ActionBarOverlayLayout mOverlayLayout;
Adam Powell01feaee2011-02-10 15:05:05 -080075 private ActionBarContainer mContainerView;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070076 private ViewGroup mTopVisibilityView;
Adam Powell89e06452010-06-23 20:24:52 -070077 private ActionBarView mActionView;
Adam Powell640a66e2011-04-29 10:18:53 -070078 private ActionBarContextView mContextView;
79 private ActionBarContainer mSplitView;
Adam Powelle6ec7322010-12-07 15:29:26 -080080 private View mContentView;
Adam Powellf8ac6b72011-05-23 18:14:09 -070081 private ScrollingTabContainerView mTabScrollView;
Adam Powell661c9082010-07-02 10:09:44 -070082
83 private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
84
Adam Powell661c9082010-07-02 10:09:44 -070085 private TabImpl mSelectedTab;
Adam Powell0c24a552010-11-03 16:44:11 -070086 private int mSavedTabPosition = INVALID_POSITION;
Adam Powell89e06452010-06-23 20:24:52 -070087
Adam Powell060e3ca2011-07-19 20:39:16 -070088 ActionModeImpl mActionMode;
89 ActionMode mDeferredDestroyActionMode;
90 ActionMode.Callback mDeferredModeDestroyCallback;
Adam Powell89e06452010-06-23 20:24:52 -070091
Adam Powell8515ee82010-11-30 14:09:55 -080092 private boolean mLastMenuVisibility;
93 private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
94 new ArrayList<OnMenuVisibilityListener>();
95
Adam Powell89e06452010-06-23 20:24:52 -070096 private static final int CONTEXT_DISPLAY_NORMAL = 0;
97 private static final int CONTEXT_DISPLAY_SPLIT = 1;
98
Adam Powell0c24a552010-11-03 16:44:11 -070099 private static final int INVALID_POSITION = -1;
100
Adam Powell89e06452010-06-23 20:24:52 -0700101 private int mContextDisplayMode;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700102 private boolean mHasEmbeddedTabs;
Adam Powell0e94b512010-06-29 17:58:20 -0700103
104 final Handler mHandler = new Handler();
Adam Powellf8ac6b72011-05-23 18:14:09 -0700105 Runnable mTabSelector;
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800106
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700107 private int mCurWindowVisibility = View.VISIBLE;
108
Adam Powell07e1f982011-03-24 11:11:15 -0700109 private Animator mCurrentShowAnim;
110 private Animator mCurrentModeAnim;
Adam Powell50efbed2011-02-08 16:20:15 -0800111 private boolean mShowHideAnimationEnabled;
Adam Powell07e1f982011-03-24 11:11:15 -0700112 boolean mWasHiddenBeforeMode;
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800113
Adam Powell07e1f982011-03-24 11:11:15 -0700114 final AnimatorListener mHideListener = new AnimatorListenerAdapter() {
Adam Powelle6ec7322010-12-07 15:29:26 -0800115 @Override
116 public void onAnimationEnd(Animator animation) {
117 if (mContentView != null) {
118 mContentView.setTranslationY(0);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700119 mTopVisibilityView.setTranslationY(0);
Adam Powelle6ec7322010-12-07 15:29:26 -0800120 }
Adam Powell993a63a2011-08-18 16:35:53 -0700121 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
122 mSplitView.setVisibility(View.GONE);
123 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700124 mTopVisibilityView.setVisibility(View.GONE);
Adam Powell01feaee2011-02-10 15:05:05 -0800125 mContainerView.setTransitioning(false);
Adam Powell07e1f982011-03-24 11:11:15 -0700126 mCurrentShowAnim = null;
Adam Powell060e3ca2011-07-19 20:39:16 -0700127 completeDeferredDestroyActionMode();
Adam Powelle6ec7322010-12-07 15:29:26 -0800128 }
129 };
130
Adam Powell07e1f982011-03-24 11:11:15 -0700131 final AnimatorListener mShowListener = new AnimatorListenerAdapter() {
Adam Powelle6ec7322010-12-07 15:29:26 -0800132 @Override
133 public void onAnimationEnd(Animator animation) {
Adam Powell07e1f982011-03-24 11:11:15 -0700134 mCurrentShowAnim = null;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700135 mTopVisibilityView.requestLayout();
Adam Powelle6ec7322010-12-07 15:29:26 -0800136 }
Adam Powelle6ec7322010-12-07 15:29:26 -0800137 };
138
Adam Powell661c9082010-07-02 10:09:44 -0700139 public ActionBarImpl(Activity activity) {
Adam Powell661c9082010-07-02 10:09:44 -0700140 mActivity = activity;
Adam Powelle6ec7322010-12-07 15:29:26 -0800141 Window window = activity.getWindow();
142 View decor = window.getDecorView();
143 init(decor);
144 if (!mActivity.getWindow().hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY)) {
145 mContentView = decor.findViewById(android.R.id.content);
146 }
Adam Powelldec9dfd2010-08-09 15:27:54 -0700147 }
148
149 public ActionBarImpl(Dialog dialog) {
150 mDialog = dialog;
151 init(dialog.getWindow().getDecorView());
152 }
153
154 private void init(View decor) {
155 mContext = decor.getContext();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700156 mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(
157 com.android.internal.R.id.action_bar_overlay_layout);
158 if (mOverlayLayout != null) {
159 mOverlayLayout.setActionBar(this);
160 }
Adam Powell89e06452010-06-23 20:24:52 -0700161 mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
Adam Powell640a66e2011-04-29 10:18:53 -0700162 mContextView = (ActionBarContextView) decor.findViewById(
Adam Powell89e06452010-06-23 20:24:52 -0700163 com.android.internal.R.id.action_context_bar);
Adam Powell01feaee2011-02-10 15:05:05 -0800164 mContainerView = (ActionBarContainer) decor.findViewById(
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800165 com.android.internal.R.id.action_bar_container);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700166 mTopVisibilityView = (ViewGroup)decor.findViewById(
167 com.android.internal.R.id.top_action_bar);
168 if (mTopVisibilityView == null) {
169 mTopVisibilityView = mContainerView;
170 }
Adam Powell640a66e2011-04-29 10:18:53 -0700171 mSplitView = (ActionBarContainer) decor.findViewById(
172 com.android.internal.R.id.split_action_bar);
Steve Block08f194b2010-08-24 18:20:48 +0100173
Adam Powell640a66e2011-04-29 10:18:53 -0700174 if (mActionView == null || mContextView == null || mContainerView == null) {
Adam Powell89e06452010-06-23 20:24:52 -0700175 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
176 "with a compatible window decor layout");
177 }
Adam Powell0e94b512010-06-29 17:58:20 -0700178
Adam Powell640a66e2011-04-29 10:18:53 -0700179 mActionView.setContextView(mContextView);
Adam Powell9b4bee02011-04-27 19:24:47 -0700180 mContextDisplayMode = mActionView.isSplitActionBar() ?
181 CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
Adam Powelldae78242011-04-25 15:23:41 -0700182
Adam Powellc29f4e52011-07-13 20:40:52 -0700183 // Older apps get the home button interaction enabled by default.
184 // Newer apps need to enable it explicitly.
Adam Powell28fa07e2011-07-15 20:17:25 -0700185 setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion <
186 Build.VERSION_CODES.ICE_CREAM_SANDWICH);
Adam Powellf5645cb2011-08-10 22:49:02 -0700187
188 setHasEmbeddedTabs(mContext.getResources().getBoolean(
189 com.android.internal.R.bool.action_bar_embed_tabs));
Adam Powellf8ac6b72011-05-23 18:14:09 -0700190 }
191
192 public void onConfigurationChanged(Configuration newConfig) {
Adam Powellf5645cb2011-08-10 22:49:02 -0700193 setHasEmbeddedTabs(mContext.getResources().getBoolean(
194 com.android.internal.R.bool.action_bar_embed_tabs));
195 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700196
Adam Powellf5645cb2011-08-10 22:49:02 -0700197 private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) {
198 mHasEmbeddedTabs = hasEmbeddedTabs;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700199 // Switch tab layout configuration if needed
200 if (!mHasEmbeddedTabs) {
201 mActionView.setEmbeddedTabView(null);
202 mContainerView.setTabContainer(mTabScrollView);
203 } else {
204 mContainerView.setTabContainer(null);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700205 mActionView.setEmbeddedTabView(mTabScrollView);
206 }
Adam Powellf5645cb2011-08-10 22:49:02 -0700207 final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS;
208 if (mTabScrollView != null) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700209 if (isInTabMode) {
210 mTabScrollView.setVisibility(View.VISIBLE);
211 if (mOverlayLayout != null) {
212 mOverlayLayout.requestFitSystemWindows();
213 }
214 } else {
215 mTabScrollView.setVisibility(View.GONE);
216 }
Adam Powellf5645cb2011-08-10 22:49:02 -0700217 }
218 mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700219 }
220
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700221 public boolean hasNonEmbeddedTabs() {
222 return !mHasEmbeddedTabs && getNavigationMode() == NAVIGATION_MODE_TABS;
223 }
224
Adam Powellf8ac6b72011-05-23 18:14:09 -0700225 private void ensureTabsExist() {
226 if (mTabScrollView != null) {
227 return;
228 }
229
Adam Powellf5645cb2011-08-10 22:49:02 -0700230 ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700231
232 if (mHasEmbeddedTabs) {
233 tabScroller.setVisibility(View.VISIBLE);
234 mActionView.setEmbeddedTabView(tabScroller);
235 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700236 if (getNavigationMode() == NAVIGATION_MODE_TABS) {
237 tabScroller.setVisibility(View.VISIBLE);
238 if (mOverlayLayout != null) {
239 mOverlayLayout.requestFitSystemWindows();
240 }
241 } else {
242 tabScroller.setVisibility(View.GONE);
243 }
Adam Powelldae78242011-04-25 15:23:41 -0700244 mContainerView.setTabContainer(tabScroller);
Adam Powelldae78242011-04-25 15:23:41 -0700245 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700246 mTabScrollView = tabScroller;
Adam Powell89e06452010-06-23 20:24:52 -0700247 }
248
Adam Powell060e3ca2011-07-19 20:39:16 -0700249 void completeDeferredDestroyActionMode() {
250 if (mDeferredModeDestroyCallback != null) {
251 mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode);
252 mDeferredDestroyActionMode = null;
253 mDeferredModeDestroyCallback = null;
254 }
255 }
256
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700257 public void setWindowVisibility(int visibility) {
258 mCurWindowVisibility = visibility;
259 }
260
Adam Powell50efbed2011-02-08 16:20:15 -0800261 /**
262 * Enables or disables animation between show/hide states.
263 * If animation is disabled using this method, animations in progress
264 * will be finished.
265 *
266 * @param enabled true to animate, false to not animate.
267 */
268 public void setShowHideAnimationEnabled(boolean enabled) {
269 mShowHideAnimationEnabled = enabled;
Adam Powell07e1f982011-03-24 11:11:15 -0700270 if (!enabled && mCurrentShowAnim != null) {
271 mCurrentShowAnim.end();
Adam Powell50efbed2011-02-08 16:20:15 -0800272 }
273 }
274
Adam Powell8515ee82010-11-30 14:09:55 -0800275 public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
276 mMenuVisibilityListeners.add(listener);
277 }
278
279 public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
280 mMenuVisibilityListeners.remove(listener);
281 }
282
283 public void dispatchMenuVisibilityChanged(boolean isVisible) {
284 if (isVisible == mLastMenuVisibility) {
285 return;
286 }
287 mLastMenuVisibility = isVisible;
288
289 final int count = mMenuVisibilityListeners.size();
290 for (int i = 0; i < count; i++) {
291 mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible);
292 }
293 }
294
Adam Powella66c7b02010-07-28 15:28:25 -0700295 @Override
Adam Powell3f476b32011-01-03 19:25:36 -0800296 public void setCustomView(int resId) {
Adam Powellf2423682011-08-11 14:29:45 -0700297 setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false));
Adam Powell3f476b32011-01-03 19:25:36 -0800298 }
299
300 @Override
301 public void setDisplayUseLogoEnabled(boolean useLogo) {
302 setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO);
303 }
304
305 @Override
306 public void setDisplayShowHomeEnabled(boolean showHome) {
307 setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME);
308 }
309
310 @Override
311 public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
312 setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP);
313 }
314
315 @Override
316 public void setDisplayShowTitleEnabled(boolean showTitle) {
317 setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE);
318 }
319
320 @Override
321 public void setDisplayShowCustomEnabled(boolean showCustom) {
322 setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM);
323 }
324
325 @Override
Adam Powellc29f4e52011-07-13 20:40:52 -0700326 public void setHomeButtonEnabled(boolean enable) {
327 mActionView.setHomeButtonEnabled(enable);
Adam Powelldae78242011-04-25 15:23:41 -0700328 }
329
330 @Override
Adam Powella66c7b02010-07-28 15:28:25 -0700331 public void setTitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700332 setTitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700333 }
334
335 @Override
336 public void setSubtitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700337 setSubtitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700338 }
339
Adam Powell17809772010-07-21 13:25:11 -0700340 public void setSelectedNavigationItem(int position) {
341 switch (mActionView.getNavigationMode()) {
342 case NAVIGATION_MODE_TABS:
343 selectTab(mTabs.get(position));
344 break;
Adam Powell9ab97872010-10-26 21:47:29 -0700345 case NAVIGATION_MODE_LIST:
Adam Powell17809772010-07-21 13:25:11 -0700346 mActionView.setDropdownSelectedPosition(position);
347 break;
348 default:
349 throw new IllegalStateException(
Adam Powell9ab97872010-10-26 21:47:29 -0700350 "setSelectedNavigationIndex not valid for current navigation mode");
Adam Powell17809772010-07-21 13:25:11 -0700351 }
352 }
353
Adam Powell9ab97872010-10-26 21:47:29 -0700354 public void removeAllTabs() {
355 cleanupTabs();
Adam Powell17809772010-07-21 13:25:11 -0700356 }
357
Adam Powell661c9082010-07-02 10:09:44 -0700358 private void cleanupTabs() {
359 if (mSelectedTab != null) {
360 selectTab(null);
361 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700362 mTabs.clear();
Adam Powelld21aa122011-05-27 13:09:52 -0700363 if (mTabScrollView != null) {
364 mTabScrollView.removeAllTabs();
365 }
Adam Powell0c24a552010-11-03 16:44:11 -0700366 mSavedTabPosition = INVALID_POSITION;
Adam Powell661c9082010-07-02 10:09:44 -0700367 }
368
Adam Powell0e94b512010-06-29 17:58:20 -0700369 public void setTitle(CharSequence title) {
370 mActionView.setTitle(title);
371 }
372
373 public void setSubtitle(CharSequence subtitle) {
374 mActionView.setSubtitle(subtitle);
375 }
376
Adam Powell89e06452010-06-23 20:24:52 -0700377 public void setDisplayOptions(int options) {
378 mActionView.setDisplayOptions(options);
379 }
Adam Powell0e94b512010-06-29 17:58:20 -0700380
Adam Powell89e06452010-06-23 20:24:52 -0700381 public void setDisplayOptions(int options, int mask) {
382 final int current = mActionView.getDisplayOptions();
383 mActionView.setDisplayOptions((options & mask) | (current & ~mask));
384 }
385
386 public void setBackgroundDrawable(Drawable d) {
Adam Powellf88b9152011-09-07 14:54:32 -0700387 mContainerView.setPrimaryBackground(d);
388 }
389
390 public void setStackedBackgroundDrawable(Drawable d) {
391 mContainerView.setStackedBackground(d);
392 }
393
394 public void setSplitBackgroundDrawable(Drawable d) {
395 if (mSplitView != null) {
396 mSplitView.setSplitBackground(d);
397 }
Adam Powell89e06452010-06-23 20:24:52 -0700398 }
399
Adam Powellef704442010-11-16 14:48:22 -0800400 public View getCustomView() {
Adam Powell89e06452010-06-23 20:24:52 -0700401 return mActionView.getCustomNavigationView();
402 }
403
404 public CharSequence getTitle() {
405 return mActionView.getTitle();
406 }
407
408 public CharSequence getSubtitle() {
409 return mActionView.getSubtitle();
410 }
411
412 public int getNavigationMode() {
413 return mActionView.getNavigationMode();
414 }
415
416 public int getDisplayOptions() {
417 return mActionView.getDisplayOptions();
418 }
419
Adam Powell5d279772010-07-27 16:34:07 -0700420 public ActionMode startActionMode(ActionMode.Callback callback) {
Adam Powell060e3ca2011-07-19 20:39:16 -0700421 boolean wasHidden = false;
Adam Powell5d279772010-07-27 16:34:07 -0700422 if (mActionMode != null) {
Adam Powell060e3ca2011-07-19 20:39:16 -0700423 wasHidden = mWasHiddenBeforeMode;
Adam Powell5d279772010-07-27 16:34:07 -0700424 mActionMode.finish();
Adam Powell6e346362010-07-23 10:18:23 -0700425 }
Adam Powell3461b322010-07-14 11:34:43 -0700426
Adam Powell640a66e2011-04-29 10:18:53 -0700427 mContextView.killMode();
Adam Powell5ee36c42011-06-02 12:59:43 -0700428 ActionModeImpl mode = new ActionModeImpl(callback);
429 if (mode.dispatchOnCreate()) {
Adam Powell060e3ca2011-07-19 20:39:16 -0700430 mWasHiddenBeforeMode = !isShowing() || wasHidden;
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700431 mode.invalidate();
Adam Powell640a66e2011-04-29 10:18:53 -0700432 mContextView.initForMode(mode);
433 animateToMode(true);
Adam Powell1ab418a2011-06-09 20:49:49 -0700434 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
Adam Powell89e06452010-06-23 20:24:52 -0700435 // TODO animate this
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700436 if (mSplitView.getVisibility() != View.VISIBLE) {
437 mSplitView.setVisibility(View.VISIBLE);
438 if (mOverlayLayout != null) {
439 mOverlayLayout.requestFitSystemWindows();
440 }
441 }
Adam Powell89e06452010-06-23 20:24:52 -0700442 }
Adam Powell86ed4362011-09-14 16:18:53 -0700443 mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Adam Powell5d279772010-07-27 16:34:07 -0700444 mActionMode = mode;
Adam Powellac695c62010-07-20 18:19:27 -0700445 return mode;
Adam Powell89e06452010-06-23 20:24:52 -0700446 }
Adam Powellac695c62010-07-20 18:19:27 -0700447 return null;
Adam Powell89e06452010-06-23 20:24:52 -0700448 }
449
Adam Powell661c9082010-07-02 10:09:44 -0700450 private void configureTab(Tab tab, int position) {
451 final TabImpl tabi = (TabImpl) tab;
Adam Powell2b6230e2010-09-07 17:55:25 -0700452 final ActionBar.TabListener callback = tabi.getCallback();
453
454 if (callback == null) {
455 throw new IllegalStateException("Action Bar Tab must have a Callback");
456 }
Adam Powell661c9082010-07-02 10:09:44 -0700457
458 tabi.setPosition(position);
459 mTabs.add(position, tabi);
460
Adam Powell81b89442010-11-02 17:58:56 -0700461 final int count = mTabs.size();
462 for (int i = position + 1; i < count; i++) {
463 mTabs.get(i).setPosition(i);
Adam Powell661c9082010-07-02 10:09:44 -0700464 }
Adam Powell661c9082010-07-02 10:09:44 -0700465 }
466
467 @Override
468 public void addTab(Tab tab) {
Adam Powell81b89442010-11-02 17:58:56 -0700469 addTab(tab, mTabs.isEmpty());
Adam Powell661c9082010-07-02 10:09:44 -0700470 }
471
472 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700473 public void addTab(Tab tab, int position) {
Adam Powell81b89442010-11-02 17:58:56 -0700474 addTab(tab, position, mTabs.isEmpty());
475 }
476
477 @Override
478 public void addTab(Tab tab, boolean setSelected) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700479 ensureTabsExist();
480 mTabScrollView.addTab(tab, setSelected);
Adam Powell81b89442010-11-02 17:58:56 -0700481 configureTab(tab, mTabs.size());
482 if (setSelected) {
483 selectTab(tab);
484 }
485 }
486
487 @Override
488 public void addTab(Tab tab, int position, boolean setSelected) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700489 ensureTabsExist();
490 mTabScrollView.addTab(tab, position, setSelected);
Adam Powell661c9082010-07-02 10:09:44 -0700491 configureTab(tab, position);
Adam Powell81b89442010-11-02 17:58:56 -0700492 if (setSelected) {
493 selectTab(tab);
494 }
Adam Powell661c9082010-07-02 10:09:44 -0700495 }
496
497 @Override
498 public Tab newTab() {
499 return new TabImpl();
500 }
501
502 @Override
503 public void removeTab(Tab tab) {
504 removeTabAt(tab.getPosition());
505 }
506
507 @Override
508 public void removeTabAt(int position) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700509 if (mTabScrollView == null) {
510 // No tabs around to remove
511 return;
512 }
513
Adam Powell0c24a552010-11-03 16:44:11 -0700514 int selectedTabPosition = mSelectedTab != null
515 ? mSelectedTab.getPosition() : mSavedTabPosition;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700516 mTabScrollView.removeTabAt(position);
Adam Powell0d8ec1d2011-05-03 14:49:13 -0700517 TabImpl removedTab = mTabs.remove(position);
518 if (removedTab != null) {
519 removedTab.setPosition(-1);
520 }
Adam Powell661c9082010-07-02 10:09:44 -0700521
522 final int newTabCount = mTabs.size();
523 for (int i = position; i < newTabCount; i++) {
524 mTabs.get(i).setPosition(i);
525 }
526
Adam Powell0c24a552010-11-03 16:44:11 -0700527 if (selectedTabPosition == position) {
528 selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
529 }
Adam Powell661c9082010-07-02 10:09:44 -0700530 }
531
532 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700533 public void selectTab(Tab tab) {
Adam Powell0c24a552010-11-03 16:44:11 -0700534 if (getNavigationMode() != NAVIGATION_MODE_TABS) {
535 mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
536 return;
537 }
538
Dianne Hackborn48e7b452011-01-17 12:28:35 -0800539 final FragmentTransaction trans = mActivity.getFragmentManager().beginTransaction()
Adam Powell0c24a552010-11-03 16:44:11 -0700540 .disallowAddToBackStack();
Adam Powell7f9b9052010-10-19 16:56:07 -0700541
542 if (mSelectedTab == tab) {
543 if (mSelectedTab != null) {
544 mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700545 mTabScrollView.animateToTab(tab.getPosition());
Adam Powell7f9b9052010-10-19 16:56:07 -0700546 }
547 } else {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700548 mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
Adam Powell7f9b9052010-10-19 16:56:07 -0700549 if (mSelectedTab != null) {
550 mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
551 }
552 mSelectedTab = (TabImpl) tab;
553 if (mSelectedTab != null) {
554 mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
555 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700556 }
557
558 if (!trans.isEmpty()) {
559 trans.commit();
560 }
561 }
562
563 @Override
564 public Tab getSelectedTab() {
565 return mSelectedTab;
Adam Powell661c9082010-07-02 10:09:44 -0700566 }
567
Adam Powell6b336f82010-08-10 20:13:01 -0700568 @Override
569 public int getHeight() {
Adam Powell58c5dc12011-07-14 21:08:10 -0700570 return mContainerView.getHeight();
Adam Powell6b336f82010-08-10 20:13:01 -0700571 }
572
573 @Override
574 public void show() {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700575 show(true, false);
Adam Powell07e1f982011-03-24 11:11:15 -0700576 }
577
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700578 public void show(boolean markHiddenBeforeMode, boolean alwaysAnimate) {
Adam Powell07e1f982011-03-24 11:11:15 -0700579 if (mCurrentShowAnim != null) {
580 mCurrentShowAnim.end();
Adam Powell45f1e082010-12-10 14:20:13 -0800581 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700582 if (mTopVisibilityView.getVisibility() == View.VISIBLE) {
Adam Powell07e1f982011-03-24 11:11:15 -0700583 if (markHiddenBeforeMode) mWasHiddenBeforeMode = false;
Adam Powelld76cee22011-01-31 15:05:05 -0800584 return;
585 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700586 mTopVisibilityView.setVisibility(View.VISIBLE);
Adam Powell50efbed2011-02-08 16:20:15 -0800587
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700588 if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
589 || alwaysAnimate)) {
590 mTopVisibilityView.setAlpha(0);
Adam Powell50efbed2011-02-08 16:20:15 -0800591 AnimatorSet anim = new AnimatorSet();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700592 AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView, "alpha", 1));
Adam Powell50efbed2011-02-08 16:20:15 -0800593 if (mContentView != null) {
594 b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700595 -mTopVisibilityView.getHeight(), 0));
596 mTopVisibilityView.setTranslationY(-mTopVisibilityView.getHeight());
597 b.with(ObjectAnimator.ofFloat(mTopVisibilityView, "translationY", 0));
Adam Powell50efbed2011-02-08 16:20:15 -0800598 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700599 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
Adam Powell640a66e2011-04-29 10:18:53 -0700600 mSplitView.setAlpha(0);
Adam Powell993a63a2011-08-18 16:35:53 -0700601 mSplitView.setVisibility(View.VISIBLE);
Adam Powell640a66e2011-04-29 10:18:53 -0700602 b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1));
603 }
Adam Powell50efbed2011-02-08 16:20:15 -0800604 anim.addListener(mShowListener);
Adam Powell07e1f982011-03-24 11:11:15 -0700605 mCurrentShowAnim = anim;
Adam Powell50efbed2011-02-08 16:20:15 -0800606 anim.start();
607 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700608 mTopVisibilityView.setAlpha(1);
Adam Powelld8145042011-03-24 14:18:27 -0700609 mContainerView.setTranslationY(0);
Adam Powell50efbed2011-02-08 16:20:15 -0800610 mShowListener.onAnimationEnd(null);
Adam Powelle6ec7322010-12-07 15:29:26 -0800611 }
Adam Powell6b336f82010-08-10 20:13:01 -0700612 }
613
614 @Override
615 public void hide() {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700616 hide(false);
617 }
618
619 public void hide(boolean alwaysAnimate) {
Adam Powell07e1f982011-03-24 11:11:15 -0700620 if (mCurrentShowAnim != null) {
621 mCurrentShowAnim.end();
Adam Powelle6ec7322010-12-07 15:29:26 -0800622 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700623 if (mTopVisibilityView.getVisibility() == View.GONE) {
Adam Powelle6ec7322010-12-07 15:29:26 -0800624 return;
625 }
Adam Powell50efbed2011-02-08 16:20:15 -0800626
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700627 if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
628 || alwaysAnimate)) {
629 mTopVisibilityView.setAlpha(1);
Adam Powell01feaee2011-02-10 15:05:05 -0800630 mContainerView.setTransitioning(true);
Adam Powell50efbed2011-02-08 16:20:15 -0800631 AnimatorSet anim = new AnimatorSet();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700632 AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView, "alpha", 0));
Adam Powell50efbed2011-02-08 16:20:15 -0800633 if (mContentView != null) {
634 b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700635 0, -mTopVisibilityView.getHeight()));
636 b.with(ObjectAnimator.ofFloat(mTopVisibilityView, "translationY",
637 -mTopVisibilityView.getHeight()));
Adam Powell50efbed2011-02-08 16:20:15 -0800638 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700639 if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
Adam Powell640a66e2011-04-29 10:18:53 -0700640 mSplitView.setAlpha(1);
641 b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0));
642 }
Adam Powell50efbed2011-02-08 16:20:15 -0800643 anim.addListener(mHideListener);
Adam Powell07e1f982011-03-24 11:11:15 -0700644 mCurrentShowAnim = anim;
Adam Powell50efbed2011-02-08 16:20:15 -0800645 anim.start();
646 } else {
647 mHideListener.onAnimationEnd(null);
Adam Powelle6ec7322010-12-07 15:29:26 -0800648 }
Adam Powell6b336f82010-08-10 20:13:01 -0700649 }
650
651 public boolean isShowing() {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700652 return mTopVisibilityView.getVisibility() == View.VISIBLE;
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800653 }
654
Adam Powell640a66e2011-04-29 10:18:53 -0700655 void animateToMode(boolean toActionMode) {
Adam Powell060e3ca2011-07-19 20:39:16 -0700656 if (toActionMode) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700657 show(false, false);
Adam Powell060e3ca2011-07-19 20:39:16 -0700658 }
Adam Powell07e1f982011-03-24 11:11:15 -0700659 if (mCurrentModeAnim != null) {
660 mCurrentModeAnim.end();
661 }
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800662
Adam Powell640a66e2011-04-29 10:18:53 -0700663 mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
664 mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700665 if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) {
666 mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
667 }
Adam Powell6b336f82010-08-10 20:13:01 -0700668 }
669
Adam Powell88ab6972011-07-28 11:25:01 -0700670 public Context getThemedContext() {
671 if (mThemedContext == null) {
672 TypedValue outValue = new TypedValue();
673 Resources.Theme currentTheme = mContext.getTheme();
674 currentTheme.resolveAttribute(com.android.internal.R.attr.actionBarWidgetTheme,
675 outValue, true);
676 final int targetThemeRes = outValue.resourceId;
677
678 if (targetThemeRes != 0 && mContext.getThemeResId() != targetThemeRes) {
679 mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes);
680 } else {
681 mThemedContext = mContext;
682 }
683 }
684 return mThemedContext;
685 }
686
Adam Powell89e06452010-06-23 20:24:52 -0700687 /**
688 * @hide
689 */
Adam Powell5d279772010-07-27 16:34:07 -0700690 public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
Adam Powell6e346362010-07-23 10:18:23 -0700691 private ActionMode.Callback mCallback;
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700692 private MenuBuilder mMenu;
Adam Powell29ed7572010-07-14 16:24:56 -0700693 private WeakReference<View> mCustomView;
Adam Powell89e06452010-06-23 20:24:52 -0700694
Adam Powell5d279772010-07-27 16:34:07 -0700695 public ActionModeImpl(ActionMode.Callback callback) {
Adam Powell89e06452010-06-23 20:24:52 -0700696 mCallback = callback;
Adam Powellf2423682011-08-11 14:29:45 -0700697 mMenu = new MenuBuilder(getThemedContext())
Adam Powell4d9861e2010-08-17 11:14:40 -0700698 .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700699 mMenu.setCallback(this);
Adam Powell89e06452010-06-23 20:24:52 -0700700 }
Adam Powell9168f0b2010-08-02 15:46:24 -0700701
702 @Override
703 public MenuInflater getMenuInflater() {
Adam Powellf2423682011-08-11 14:29:45 -0700704 return new MenuInflater(getThemedContext());
Adam Powell9168f0b2010-08-02 15:46:24 -0700705 }
706
Adam Powell89e06452010-06-23 20:24:52 -0700707 @Override
708 public Menu getMenu() {
709 return mMenu;
710 }
711
712 @Override
713 public void finish() {
Adam Powell5d279772010-07-27 16:34:07 -0700714 if (mActionMode != this) {
715 // Not the active action mode - no-op
Adam Powell93b6bc32010-07-22 11:36:35 -0700716 return;
717 }
718
Adam Powell060e3ca2011-07-19 20:39:16 -0700719 // If we were hidden before the mode was shown, defer the onDestroy
720 // callback until the animation is finished and associated relayout
721 // is about to happen. This lets apps better anticipate visibility
722 // and layout behavior.
723 if (mWasHiddenBeforeMode) {
724 mDeferredDestroyActionMode = this;
725 mDeferredModeDestroyCallback = mCallback;
726 } else {
727 mCallback.onDestroyActionMode(this);
728 }
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800729 mCallback = null;
Adam Powell640a66e2011-04-29 10:18:53 -0700730 animateToMode(false);
Adam Powell0e94b512010-06-29 17:58:20 -0700731
732 // Clear out the context mode views after the animation finishes
Adam Powell640a66e2011-04-29 10:18:53 -0700733 mContextView.closeMode();
Adam Powell86ed4362011-09-14 16:18:53 -0700734 mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700735
Adam Powell5d279772010-07-27 16:34:07 -0700736 mActionMode = null;
Adam Powell07e1f982011-03-24 11:11:15 -0700737
738 if (mWasHiddenBeforeMode) {
739 hide();
740 }
Adam Powell89e06452010-06-23 20:24:52 -0700741 }
742
743 @Override
744 public void invalidate() {
Adam Powell5ee36c42011-06-02 12:59:43 -0700745 mMenu.stopDispatchingItemsChanged();
746 try {
747 mCallback.onPrepareActionMode(this, mMenu);
748 } finally {
749 mMenu.startDispatchingItemsChanged();
750 }
751 }
752
753 public boolean dispatchOnCreate() {
754 mMenu.stopDispatchingItemsChanged();
755 try {
756 return mCallback.onCreateActionMode(this, mMenu);
757 } finally {
758 mMenu.startDispatchingItemsChanged();
Adam Powell89e06452010-06-23 20:24:52 -0700759 }
760 }
761
762 @Override
763 public void setCustomView(View view) {
Adam Powell640a66e2011-04-29 10:18:53 -0700764 mContextView.setCustomView(view);
Adam Powell29ed7572010-07-14 16:24:56 -0700765 mCustomView = new WeakReference<View>(view);
Adam Powell89e06452010-06-23 20:24:52 -0700766 }
767
768 @Override
769 public void setSubtitle(CharSequence subtitle) {
Adam Powell640a66e2011-04-29 10:18:53 -0700770 mContextView.setSubtitle(subtitle);
Adam Powell89e06452010-06-23 20:24:52 -0700771 }
772
773 @Override
774 public void setTitle(CharSequence title) {
Adam Powell640a66e2011-04-29 10:18:53 -0700775 mContextView.setTitle(title);
Adam Powell89e06452010-06-23 20:24:52 -0700776 }
Adam Powell29ed7572010-07-14 16:24:56 -0700777
778 @Override
Adam Powellc9ae2a22010-07-28 14:44:21 -0700779 public void setTitle(int resId) {
Adam Powell48e8ac32011-01-14 12:10:24 -0800780 setTitle(mContext.getResources().getString(resId));
Adam Powellc9ae2a22010-07-28 14:44:21 -0700781 }
782
783 @Override
784 public void setSubtitle(int resId) {
Adam Powell48e8ac32011-01-14 12:10:24 -0800785 setSubtitle(mContext.getResources().getString(resId));
Adam Powellc9ae2a22010-07-28 14:44:21 -0700786 }
787
788 @Override
Adam Powell29ed7572010-07-14 16:24:56 -0700789 public CharSequence getTitle() {
Adam Powell640a66e2011-04-29 10:18:53 -0700790 return mContextView.getTitle();
Adam Powell29ed7572010-07-14 16:24:56 -0700791 }
792
793 @Override
794 public CharSequence getSubtitle() {
Adam Powell640a66e2011-04-29 10:18:53 -0700795 return mContextView.getSubtitle();
Adam Powell29ed7572010-07-14 16:24:56 -0700796 }
Adam Powell89e06452010-06-23 20:24:52 -0700797
Adam Powell29ed7572010-07-14 16:24:56 -0700798 @Override
Adam Powellb98a81f2012-02-24 11:09:07 -0800799 public void setTitleOptionalHint(boolean titleOptional) {
800 mContextView.setTitleOptional(titleOptional);
801 }
802
803 @Override
804 public boolean isTitleOptional() {
805 return mContextView.isTitleOptional();
806 }
807
808 @Override
Adam Powell29ed7572010-07-14 16:24:56 -0700809 public View getCustomView() {
810 return mCustomView != null ? mCustomView.get() : null;
811 }
812
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700813 public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800814 if (mCallback != null) {
815 return mCallback.onActionItemClicked(this, item);
816 } else {
817 return false;
818 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700819 }
820
821 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
822 }
823
824 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800825 if (mCallback == null) {
826 return false;
827 }
828
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700829 if (!subMenu.hasVisibleItems()) {
830 return true;
Adam Powell89e06452010-06-23 20:24:52 -0700831 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700832
Adam Powellf2423682011-08-11 14:29:45 -0700833 new MenuPopupHelper(getThemedContext(), subMenu).show();
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700834 return true;
835 }
836
837 public void onCloseSubMenu(SubMenuBuilder menu) {
838 }
839
840 public void onMenuModeChange(MenuBuilder menu) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800841 if (mCallback == null) {
842 return;
843 }
Adam Powellf6148c52010-08-11 21:10:16 -0700844 invalidate();
Adam Powell640a66e2011-04-29 10:18:53 -0700845 mContextView.showOverflowMenu();
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700846 }
Adam Powell661c9082010-07-02 10:09:44 -0700847 }
848
849 /**
850 * @hide
851 */
852 public class TabImpl extends ActionBar.Tab {
Adam Powell2b6230e2010-09-07 17:55:25 -0700853 private ActionBar.TabListener mCallback;
854 private Object mTag;
Adam Powell661c9082010-07-02 10:09:44 -0700855 private Drawable mIcon;
856 private CharSequence mText;
Adam Powell94e56ef2011-09-06 21:22:22 -0700857 private CharSequence mContentDesc;
Adam Powell0d8ec1d2011-05-03 14:49:13 -0700858 private int mPosition = -1;
Adam Powell2b6230e2010-09-07 17:55:25 -0700859 private View mCustomView;
Adam Powell661c9082010-07-02 10:09:44 -0700860
861 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700862 public Object getTag() {
863 return mTag;
864 }
865
866 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700867 public Tab setTag(Object tag) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700868 mTag = tag;
Adam Powell9ab97872010-10-26 21:47:29 -0700869 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -0700870 }
871
872 public ActionBar.TabListener getCallback() {
873 return mCallback;
874 }
875
876 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700877 public Tab setTabListener(ActionBar.TabListener callback) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700878 mCallback = callback;
Adam Powell9ab97872010-10-26 21:47:29 -0700879 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -0700880 }
881
882 @Override
883 public View getCustomView() {
884 return mCustomView;
885 }
886
887 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700888 public Tab setCustomView(View view) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700889 mCustomView = view;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700890 if (mPosition >= 0) {
891 mTabScrollView.updateTab(mPosition);
892 }
Adam Powell9ab97872010-10-26 21:47:29 -0700893 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700894 }
895
896 @Override
Adam Powell32555f32010-11-17 13:49:22 -0800897 public Tab setCustomView(int layoutResId) {
Adam Powellf2423682011-08-11 14:29:45 -0700898 return setCustomView(LayoutInflater.from(getThemedContext())
899 .inflate(layoutResId, null));
Adam Powell32555f32010-11-17 13:49:22 -0800900 }
901
902 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700903 public Drawable getIcon() {
904 return mIcon;
905 }
906
907 @Override
908 public int getPosition() {
909 return mPosition;
910 }
911
912 public void setPosition(int position) {
913 mPosition = position;
914 }
915
916 @Override
917 public CharSequence getText() {
918 return mText;
919 }
920
921 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700922 public Tab setIcon(Drawable icon) {
Adam Powell661c9082010-07-02 10:09:44 -0700923 mIcon = icon;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700924 if (mPosition >= 0) {
925 mTabScrollView.updateTab(mPosition);
926 }
Adam Powell9ab97872010-10-26 21:47:29 -0700927 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700928 }
929
930 @Override
Adam Powell32555f32010-11-17 13:49:22 -0800931 public Tab setIcon(int resId) {
932 return setIcon(mContext.getResources().getDrawable(resId));
933 }
934
935 @Override
Adam Powell9ab97872010-10-26 21:47:29 -0700936 public Tab setText(CharSequence text) {
Adam Powell661c9082010-07-02 10:09:44 -0700937 mText = text;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700938 if (mPosition >= 0) {
939 mTabScrollView.updateTab(mPosition);
940 }
Adam Powell9ab97872010-10-26 21:47:29 -0700941 return this;
Adam Powell661c9082010-07-02 10:09:44 -0700942 }
943
944 @Override
Adam Powell32555f32010-11-17 13:49:22 -0800945 public Tab setText(int resId) {
946 return setText(mContext.getResources().getText(resId));
947 }
948
949 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700950 public void select() {
951 selectTab(this);
Adam Powell89e06452010-06-23 20:24:52 -0700952 }
Adam Powell94e56ef2011-09-06 21:22:22 -0700953
954 @Override
955 public Tab setContentDescription(int resId) {
956 return setContentDescription(mContext.getResources().getText(resId));
957 }
958
959 @Override
960 public Tab setContentDescription(CharSequence contentDesc) {
961 mContentDesc = contentDesc;
962 if (mPosition >= 0) {
963 mTabScrollView.updateTab(mPosition);
964 }
965 return this;
966 }
967
968 @Override
969 public CharSequence getContentDescription() {
970 return mContentDesc;
971 }
Adam Powell89e06452010-06-23 20:24:52 -0700972 }
Adam Powell9ab97872010-10-26 21:47:29 -0700973
974 @Override
975 public void setCustomView(View view) {
976 mActionView.setCustomNavigationView(view);
977 }
978
979 @Override
980 public void setCustomView(View view, LayoutParams layoutParams) {
981 view.setLayoutParams(layoutParams);
982 mActionView.setCustomNavigationView(view);
983 }
984
985 @Override
Adam Powell8515ee82010-11-30 14:09:55 -0800986 public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
Adam Powell9ab97872010-10-26 21:47:29 -0700987 mActionView.setDropdownAdapter(adapter);
988 mActionView.setCallback(callback);
989 }
990
991 @Override
992 public int getSelectedNavigationIndex() {
993 switch (mActionView.getNavigationMode()) {
994 case NAVIGATION_MODE_TABS:
Adam Powell04587962010-11-11 22:15:07 -0800995 return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
Adam Powell9ab97872010-10-26 21:47:29 -0700996 case NAVIGATION_MODE_LIST:
997 return mActionView.getDropdownSelectedPosition();
998 default:
999 return -1;
1000 }
1001 }
1002
1003 @Override
1004 public int getNavigationItemCount() {
1005 switch (mActionView.getNavigationMode()) {
1006 case NAVIGATION_MODE_TABS:
1007 return mTabs.size();
1008 case NAVIGATION_MODE_LIST:
1009 SpinnerAdapter adapter = mActionView.getDropdownAdapter();
1010 return adapter != null ? adapter.getCount() : 0;
1011 default:
1012 return 0;
1013 }
1014 }
1015
1016 @Override
Adam Powell0c24a552010-11-03 16:44:11 -07001017 public int getTabCount() {
1018 return mTabs.size();
1019 }
1020
1021 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001022 public void setNavigationMode(int mode) {
Adam Powell0c24a552010-11-03 16:44:11 -07001023 final int oldMode = mActionView.getNavigationMode();
1024 switch (oldMode) {
1025 case NAVIGATION_MODE_TABS:
1026 mSavedTabPosition = getSelectedNavigationIndex();
1027 selectTab(null);
Adam Powellf5645cb2011-08-10 22:49:02 -07001028 mTabScrollView.setVisibility(View.GONE);
Adam Powell0c24a552010-11-03 16:44:11 -07001029 break;
1030 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001031 if (oldMode != mode && !mHasEmbeddedTabs) {
1032 if (mOverlayLayout != null) {
1033 mOverlayLayout.requestFitSystemWindows();
1034 }
1035 }
Adam Powell9ab97872010-10-26 21:47:29 -07001036 mActionView.setNavigationMode(mode);
Adam Powell0c24a552010-11-03 16:44:11 -07001037 switch (mode) {
1038 case NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -07001039 ensureTabsExist();
Adam Powellf5645cb2011-08-10 22:49:02 -07001040 mTabScrollView.setVisibility(View.VISIBLE);
Adam Powell0c24a552010-11-03 16:44:11 -07001041 if (mSavedTabPosition != INVALID_POSITION) {
1042 setSelectedNavigationItem(mSavedTabPosition);
1043 mSavedTabPosition = INVALID_POSITION;
1044 }
1045 break;
1046 }
Adam Powelld21aa122011-05-27 13:09:52 -07001047 mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
Adam Powell9ab97872010-10-26 21:47:29 -07001048 }
1049
1050 @Override
1051 public Tab getTabAt(int index) {
1052 return mTabs.get(index);
1053 }
Adam Powell0c24a552010-11-03 16:44:11 -07001054
Adam Powell0c24a552010-11-03 16:44:11 -07001055
Adam Powell1969b872011-03-22 11:52:48 -07001056 @Override
1057 public void setIcon(int resId) {
Adam Powell45c515b2011-04-21 18:50:20 -07001058 mActionView.setIcon(resId);
Adam Powell1969b872011-03-22 11:52:48 -07001059 }
Adam Powell0c24a552010-11-03 16:44:11 -07001060
Adam Powell1969b872011-03-22 11:52:48 -07001061 @Override
1062 public void setIcon(Drawable icon) {
1063 mActionView.setIcon(icon);
1064 }
1065
1066 @Override
1067 public void setLogo(int resId) {
Adam Powell45c515b2011-04-21 18:50:20 -07001068 mActionView.setLogo(resId);
Adam Powell1969b872011-03-22 11:52:48 -07001069 }
1070
1071 @Override
1072 public void setLogo(Drawable logo) {
1073 mActionView.setLogo(logo);
Adam Powell0c24a552010-11-03 16:44:11 -07001074 }
Adam Powell89e06452010-06-23 20:24:52 -07001075}