blob: 2bf02f15a66a679da71d119156efb36f3e3007d8 [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 Powell9b0dc282013-07-31 13:58:43 -070019import android.animation.ValueAnimator;
Adam Powellb36e4f92014-05-01 10:23:33 -070020import android.content.res.TypedArray;
Adam Powell9b0dc282013-07-31 13:58:43 -070021import android.view.ViewParent;
Adam Powelle021e6e2014-05-23 17:27:24 -070022import android.widget.Toolbar;
Clara Bayarric57e7bc2015-02-13 12:07:52 +000023
Adam Powellb36e4f92014-05-01 10:23:33 -070024import com.android.internal.R;
Adam Powellb8139af2012-04-19 13:52:46 -070025import com.android.internal.view.ActionBarPolicy;
Clara Bayarric57e7bc2015-02-13 12:07:52 +000026import com.android.internal.view.ActionModeWrapper;
Adam Powell2c9c9fe2010-07-16 10:17:57 -070027import com.android.internal.view.menu.MenuBuilder;
Adam Powell2c9c9fe2010-07-16 10:17:57 -070028import com.android.internal.view.menu.MenuPopupHelper;
29import com.android.internal.view.menu.SubMenuBuilder;
Adam Powell01feaee2011-02-10 15:05:05 -080030import com.android.internal.widget.ActionBarContainer;
Adam Powell89e06452010-06-23 20:24:52 -070031import com.android.internal.widget.ActionBarContextView;
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070032import com.android.internal.widget.ActionBarOverlayLayout;
Adam Powelle021e6e2014-05-23 17:27:24 -070033import com.android.internal.widget.DecorToolbar;
Adam Powellf8ac6b72011-05-23 18:14:09 -070034import com.android.internal.widget.ScrollingTabContainerView;
Adam Powell89e06452010-06-23 20:24:52 -070035
Adam Powelld8b3f2e2010-12-02 13:37:03 -080036import android.animation.Animator;
Adam Powelld8b3f2e2010-12-02 13:37:03 -080037import android.animation.Animator.AnimatorListener;
Adam Powell07e1f982011-03-24 11:11:15 -070038import android.animation.AnimatorListenerAdapter;
Adam Powelld8b3f2e2010-12-02 13:37:03 -080039import android.animation.AnimatorSet;
Adam Powelle6ec7322010-12-07 15:29:26 -080040import android.animation.ObjectAnimator;
Adam Powell89e06452010-06-23 20:24:52 -070041import android.app.ActionBar;
Adam Powell661c9082010-07-02 10:09:44 -070042import android.app.Activity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070043import android.app.Dialog;
Adam Powell661c9082010-07-02 10:09:44 -070044import android.app.FragmentTransaction;
Adam Powelldec9dfd2010-08-09 15:27:54 -070045import android.content.Context;
Adam Powellf8ac6b72011-05-23 18:14:09 -070046import android.content.res.Configuration;
Adam Powell88ab6972011-07-28 11:25:01 -070047import android.content.res.Resources;
Adam Powell89e06452010-06-23 20:24:52 -070048import android.graphics.drawable.Drawable;
Adam Powell88ab6972011-07-28 11:25:01 -070049import android.util.TypedValue;
Adam Powell6e346362010-07-23 10:18:23 -070050import android.view.ActionMode;
Clara Bayarric57e7bc2015-02-13 12:07:52 +000051import android.view.ActionMode.Callback;
Adam Powell88ab6972011-07-28 11:25:01 -070052import android.view.ContextThemeWrapper;
Adam Powell32555f32010-11-17 13:49:22 -080053import android.view.LayoutInflater;
Adam Powell89e06452010-06-23 20:24:52 -070054import android.view.Menu;
Adam Powell9168f0b2010-08-02 15:46:24 -070055import android.view.MenuInflater;
Adam Powell89e06452010-06-23 20:24:52 -070056import android.view.MenuItem;
57import android.view.View;
Adam Powelle6ec7322010-12-07 15:29:26 -080058import android.view.Window;
Adam Powell86ed4362011-09-14 16:18:53 -070059import android.view.accessibility.AccessibilityEvent;
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -070060import android.view.animation.AnimationUtils;
Adam Powell89e06452010-06-23 20:24:52 -070061import android.widget.SpinnerAdapter;
Adam Powell89e06452010-06-23 20:24:52 -070062
Adam Powell29ed7572010-07-14 16:24:56 -070063import java.lang.ref.WeakReference;
Adam Powell661c9082010-07-02 10:09:44 -070064import java.util.ArrayList;
65
Adam Powell89e06452010-06-23 20:24:52 -070066/**
Adam Powelle43340c2014-03-17 19:10:43 -070067 * WindowDecorActionBar is the ActionBar implementation used
68 * by devices of all screen sizes as part of the window decor layout.
69 * If it detects a compatible decor, it will split contextual modes
70 * across both the ActionBarView at the top of the screen and
71 * a horizontal LinearLayout at the bottom which is normally hidden.
Adam Powell89e06452010-06-23 20:24:52 -070072 */
Adam Powellb36e4f92014-05-01 10:23:33 -070073public class WindowDecorActionBar extends ActionBar implements
74 ActionBarOverlayLayout.ActionBarVisibilityCallback {
Adam Powelle43340c2014-03-17 19:10:43 -070075 private static final String TAG = "WindowDecorActionBar";
Adam Powell661c9082010-07-02 10:09:44 -070076
Adam Powelldec9dfd2010-08-09 15:27:54 -070077 private Context mContext;
Adam Powell88ab6972011-07-28 11:25:01 -070078 private Context mThemedContext;
Adam Powell661c9082010-07-02 10:09:44 -070079 private Activity mActivity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070080 private Dialog mDialog;
Adam Powell661c9082010-07-02 10:09:44 -070081
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070082 private ActionBarOverlayLayout mOverlayLayout;
Adam Powell01feaee2011-02-10 15:05:05 -080083 private ActionBarContainer mContainerView;
Adam Powelle021e6e2014-05-23 17:27:24 -070084 private DecorToolbar mDecorToolbar;
Adam Powell640a66e2011-04-29 10:18:53 -070085 private ActionBarContextView mContextView;
86 private ActionBarContainer mSplitView;
Adam Powelle6ec7322010-12-07 15:29:26 -080087 private View mContentView;
Adam Powellf8ac6b72011-05-23 18:14:09 -070088 private ScrollingTabContainerView mTabScrollView;
Adam Powell661c9082010-07-02 10:09:44 -070089
90 private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
91
Adam Powell661c9082010-07-02 10:09:44 -070092 private TabImpl mSelectedTab;
Adam Powell0c24a552010-11-03 16:44:11 -070093 private int mSavedTabPosition = INVALID_POSITION;
Clara Bayarric57e7bc2015-02-13 12:07:52 +000094
Adam Powelldd8fab22012-03-22 17:47:27 -070095 private boolean mDisplayHomeAsUpSet;
96
Clara Bayarric57e7bc2015-02-13 12:07:52 +000097 ActionMode mActionMode;
Adam Powell060e3ca2011-07-19 20:39:16 -070098 ActionMode mDeferredDestroyActionMode;
99 ActionMode.Callback mDeferredModeDestroyCallback;
Clara Bayarric57e7bc2015-02-13 12:07:52 +0000100
Adam Powell8515ee82010-11-30 14:09:55 -0800101 private boolean mLastMenuVisibility;
102 private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
103 new ArrayList<OnMenuVisibilityListener>();
104
Adam Powell89e06452010-06-23 20:24:52 -0700105 private static final int CONTEXT_DISPLAY_NORMAL = 0;
106 private static final int CONTEXT_DISPLAY_SPLIT = 1;
Clara Bayarric57e7bc2015-02-13 12:07:52 +0000107
Adam Powell0c24a552010-11-03 16:44:11 -0700108 private static final int INVALID_POSITION = -1;
109
Adam Powell89e06452010-06-23 20:24:52 -0700110 private int mContextDisplayMode;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700111 private boolean mHasEmbeddedTabs;
Adam Powell0e94b512010-06-29 17:58:20 -0700112
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700113 private int mCurWindowVisibility = View.VISIBLE;
114
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800115 private boolean mContentAnimations = true;
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700116 private boolean mHiddenByApp;
117 private boolean mHiddenBySystem;
118 private boolean mShowingForMode;
119
120 private boolean mNowShowing = true;
121
Adam Powell07e1f982011-03-24 11:11:15 -0700122 private Animator mCurrentShowAnim;
Adam Powell50efbed2011-02-08 16:20:15 -0800123 private boolean mShowHideAnimationEnabled;
Adam Powellb36e4f92014-05-01 10:23:33 -0700124 boolean mHideOnContentScroll;
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800125
Adam Powell07e1f982011-03-24 11:11:15 -0700126 final AnimatorListener mHideListener = new AnimatorListenerAdapter() {
Adam Powelle6ec7322010-12-07 15:29:26 -0800127 @Override
128 public void onAnimationEnd(Animator animation) {
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800129 if (mContentAnimations && mContentView != null) {
Adam Powelle6ec7322010-12-07 15:29:26 -0800130 mContentView.setTranslationY(0);
Adam Powell9b0dc282013-07-31 13:58:43 -0700131 mContainerView.setTranslationY(0);
Adam Powelle6ec7322010-12-07 15:29:26 -0800132 }
Adam Powell993a63a2011-08-18 16:35:53 -0700133 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
134 mSplitView.setVisibility(View.GONE);
135 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700136 mContainerView.setVisibility(View.GONE);
Adam Powell01feaee2011-02-10 15:05:05 -0800137 mContainerView.setTransitioning(false);
Adam Powell07e1f982011-03-24 11:11:15 -0700138 mCurrentShowAnim = null;
Adam Powell060e3ca2011-07-19 20:39:16 -0700139 completeDeferredDestroyActionMode();
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700140 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700141 mOverlayLayout.requestApplyInsets();
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700142 }
Adam Powelle6ec7322010-12-07 15:29:26 -0800143 }
144 };
145
Adam Powell07e1f982011-03-24 11:11:15 -0700146 final AnimatorListener mShowListener = new AnimatorListenerAdapter() {
Adam Powelle6ec7322010-12-07 15:29:26 -0800147 @Override
148 public void onAnimationEnd(Animator animation) {
Adam Powell07e1f982011-03-24 11:11:15 -0700149 mCurrentShowAnim = null;
Adam Powell9b0dc282013-07-31 13:58:43 -0700150 mContainerView.requestLayout();
151 }
152 };
153
154 final ValueAnimator.AnimatorUpdateListener mUpdateListener =
155 new ValueAnimator.AnimatorUpdateListener() {
156 @Override
157 public void onAnimationUpdate(ValueAnimator animation) {
158 final ViewParent parent = mContainerView.getParent();
159 ((View) parent).invalidate();
Adam Powelle6ec7322010-12-07 15:29:26 -0800160 }
Adam Powelle6ec7322010-12-07 15:29:26 -0800161 };
162
Adam Powelle43340c2014-03-17 19:10:43 -0700163 public WindowDecorActionBar(Activity activity) {
Adam Powell661c9082010-07-02 10:09:44 -0700164 mActivity = activity;
Adam Powelle6ec7322010-12-07 15:29:26 -0800165 Window window = activity.getWindow();
166 View decor = window.getDecorView();
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800167 boolean overlayMode = mActivity.getWindow().hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
Adam Powell9b0dc282013-07-31 13:58:43 -0700168 init(decor);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800169 if (!overlayMode) {
Adam Powelle6ec7322010-12-07 15:29:26 -0800170 mContentView = decor.findViewById(android.R.id.content);
171 }
Adam Powelldec9dfd2010-08-09 15:27:54 -0700172 }
173
Adam Powelle43340c2014-03-17 19:10:43 -0700174 public WindowDecorActionBar(Dialog dialog) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700175 mDialog = dialog;
Adam Powell9b0dc282013-07-31 13:58:43 -0700176 init(dialog.getWindow().getDecorView());
Adam Powelldec9dfd2010-08-09 15:27:54 -0700177 }
178
Deepanshu Gupta14bf0ce2013-12-12 12:16:24 -0800179 /**
180 * Only for edit mode.
181 * @hide
182 */
183 public WindowDecorActionBar(View layout) {
184 assert layout.isInEditMode();
185 init(layout);
186 }
187
Adam Powell9b0dc282013-07-31 13:58:43 -0700188 private void init(View decor) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700189 mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(
Adam Powell4369e7d2014-05-17 14:16:08 -0700190 com.android.internal.R.id.decor_content_parent);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700191 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700192 mOverlayLayout.setActionBarVisibilityCallback(this);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700193 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700194 mDecorToolbar = getDecorToolbar(decor.findViewById(com.android.internal.R.id.action_bar));
Adam Powell640a66e2011-04-29 10:18:53 -0700195 mContextView = (ActionBarContextView) decor.findViewById(
Adam Powell89e06452010-06-23 20:24:52 -0700196 com.android.internal.R.id.action_context_bar);
Adam Powell01feaee2011-02-10 15:05:05 -0800197 mContainerView = (ActionBarContainer) decor.findViewById(
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800198 com.android.internal.R.id.action_bar_container);
Adam Powell640a66e2011-04-29 10:18:53 -0700199 mSplitView = (ActionBarContainer) decor.findViewById(
200 com.android.internal.R.id.split_action_bar);
Steve Block08f194b2010-08-24 18:20:48 +0100201
Adam Powelle021e6e2014-05-23 17:27:24 -0700202 if (mDecorToolbar == null || mContextView == null || mContainerView == null) {
Adam Powell89e06452010-06-23 20:24:52 -0700203 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
204 "with a compatible window decor layout");
205 }
Adam Powell0e94b512010-06-29 17:58:20 -0700206
Adam Powelle021e6e2014-05-23 17:27:24 -0700207 mContext = mDecorToolbar.getContext();
208 mContextDisplayMode = mDecorToolbar.isSplit() ?
Adam Powell9b4bee02011-04-27 19:24:47 -0700209 CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
Adam Powelldae78242011-04-25 15:23:41 -0700210
Adam Powelld40423a2012-05-02 14:06:03 -0700211 // This was initially read from the action bar style
Adam Powelle021e6e2014-05-23 17:27:24 -0700212 final int current = mDecorToolbar.getDisplayOptions();
Adam Powelld40423a2012-05-02 14:06:03 -0700213 final boolean homeAsUp = (current & DISPLAY_HOME_AS_UP) != 0;
214 if (homeAsUp) {
215 mDisplayHomeAsUpSet = true;
216 }
217
Adam Powellb8139af2012-04-19 13:52:46 -0700218 ActionBarPolicy abp = ActionBarPolicy.get(mContext);
Adam Powelld40423a2012-05-02 14:06:03 -0700219 setHomeButtonEnabled(abp.enableHomeButtonByDefault() || homeAsUp);
Adam Powellb8139af2012-04-19 13:52:46 -0700220 setHasEmbeddedTabs(abp.hasEmbeddedTabs());
Adam Powellb36e4f92014-05-01 10:23:33 -0700221
222 final TypedArray a = mContext.obtainStyledAttributes(null,
223 com.android.internal.R.styleable.ActionBar,
224 com.android.internal.R.attr.actionBarStyle, 0);
225 if (a.getBoolean(R.styleable.ActionBar_hideOnContentScroll, false)) {
226 setHideOnContentScrollEnabled(true);
227 }
Adam Powell14d1fa42014-07-10 16:23:39 -0700228 final int elevation = a.getDimensionPixelSize(R.styleable.ActionBar_elevation, 0);
229 if (elevation != 0) {
230 setElevation(elevation);
231 }
Adam Powellb36e4f92014-05-01 10:23:33 -0700232 a.recycle();
Adam Powellf8ac6b72011-05-23 18:14:09 -0700233 }
234
Adam Powelle021e6e2014-05-23 17:27:24 -0700235 private DecorToolbar getDecorToolbar(View view) {
236 if (view instanceof DecorToolbar) {
237 return (DecorToolbar) view;
238 } else if (view instanceof Toolbar) {
239 return ((Toolbar) view).getWrapper();
240 } else {
241 throw new IllegalStateException("Can't make a decor toolbar out of " +
242 view.getClass().getSimpleName());
243 }
244 }
245
Adam Powell14d1fa42014-07-10 16:23:39 -0700246 @Override
247 public void setElevation(float elevation) {
248 mContainerView.setElevation(elevation);
249 if (mSplitView != null) {
250 mSplitView.setElevation(elevation);
251 }
252 }
253
254 @Override
255 public float getElevation() {
256 return mContainerView.getElevation();
257 }
258
Adam Powellf8ac6b72011-05-23 18:14:09 -0700259 public void onConfigurationChanged(Configuration newConfig) {
Adam Powellb8139af2012-04-19 13:52:46 -0700260 setHasEmbeddedTabs(ActionBarPolicy.get(mContext).hasEmbeddedTabs());
Adam Powellf5645cb2011-08-10 22:49:02 -0700261 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700262
Adam Powellf5645cb2011-08-10 22:49:02 -0700263 private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) {
264 mHasEmbeddedTabs = hasEmbeddedTabs;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700265 // Switch tab layout configuration if needed
266 if (!mHasEmbeddedTabs) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700267 mDecorToolbar.setEmbeddedTabView(null);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700268 mContainerView.setTabContainer(mTabScrollView);
269 } else {
270 mContainerView.setTabContainer(null);
Adam Powelle021e6e2014-05-23 17:27:24 -0700271 mDecorToolbar.setEmbeddedTabView(mTabScrollView);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700272 }
Adam Powellf5645cb2011-08-10 22:49:02 -0700273 final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS;
274 if (mTabScrollView != null) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700275 if (isInTabMode) {
276 mTabScrollView.setVisibility(View.VISIBLE);
277 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700278 mOverlayLayout.requestApplyInsets();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700279 }
280 } else {
281 mTabScrollView.setVisibility(View.GONE);
282 }
Adam Powellf5645cb2011-08-10 22:49:02 -0700283 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700284 mDecorToolbar.setCollapsible(!mHasEmbeddedTabs && isInTabMode);
Adam Powellb36e4f92014-05-01 10:23:33 -0700285 mOverlayLayout.setHasNonEmbeddedTabs(!mHasEmbeddedTabs && isInTabMode);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700286 }
287
Adam Powellf8ac6b72011-05-23 18:14:09 -0700288 private void ensureTabsExist() {
289 if (mTabScrollView != null) {
290 return;
291 }
292
Adam Powellf5645cb2011-08-10 22:49:02 -0700293 ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700294
295 if (mHasEmbeddedTabs) {
296 tabScroller.setVisibility(View.VISIBLE);
Adam Powelle021e6e2014-05-23 17:27:24 -0700297 mDecorToolbar.setEmbeddedTabView(tabScroller);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700298 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700299 if (getNavigationMode() == NAVIGATION_MODE_TABS) {
300 tabScroller.setVisibility(View.VISIBLE);
301 if (mOverlayLayout != null) {
Adam Powell76d8f962014-05-14 20:13:47 -0700302 mOverlayLayout.requestApplyInsets();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700303 }
304 } else {
305 tabScroller.setVisibility(View.GONE);
306 }
Adam Powelldae78242011-04-25 15:23:41 -0700307 mContainerView.setTabContainer(tabScroller);
Adam Powelldae78242011-04-25 15:23:41 -0700308 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700309 mTabScrollView = tabScroller;
Adam Powell89e06452010-06-23 20:24:52 -0700310 }
311
Adam Powell060e3ca2011-07-19 20:39:16 -0700312 void completeDeferredDestroyActionMode() {
313 if (mDeferredModeDestroyCallback != null) {
314 mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode);
315 mDeferredDestroyActionMode = null;
316 mDeferredModeDestroyCallback = null;
317 }
318 }
319
Adam Powellb36e4f92014-05-01 10:23:33 -0700320 public void onWindowVisibilityChanged(int visibility) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700321 mCurWindowVisibility = visibility;
322 }
323
Adam Powell50efbed2011-02-08 16:20:15 -0800324 /**
325 * Enables or disables animation between show/hide states.
326 * If animation is disabled using this method, animations in progress
327 * will be finished.
328 *
329 * @param enabled true to animate, false to not animate.
330 */
331 public void setShowHideAnimationEnabled(boolean enabled) {
332 mShowHideAnimationEnabled = enabled;
Adam Powell07e1f982011-03-24 11:11:15 -0700333 if (!enabled && mCurrentShowAnim != null) {
334 mCurrentShowAnim.end();
Adam Powell50efbed2011-02-08 16:20:15 -0800335 }
336 }
337
Adam Powell8515ee82010-11-30 14:09:55 -0800338 public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
339 mMenuVisibilityListeners.add(listener);
340 }
341
342 public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
343 mMenuVisibilityListeners.remove(listener);
344 }
345
346 public void dispatchMenuVisibilityChanged(boolean isVisible) {
347 if (isVisible == mLastMenuVisibility) {
348 return;
349 }
350 mLastMenuVisibility = isVisible;
351
352 final int count = mMenuVisibilityListeners.size();
353 for (int i = 0; i < count; i++) {
354 mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible);
355 }
356 }
357
Adam Powella66c7b02010-07-28 15:28:25 -0700358 @Override
Adam Powell3f476b32011-01-03 19:25:36 -0800359 public void setCustomView(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700360 setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId,
Dan Sandler6fdeeb32014-05-29 11:02:41 -0400361 mDecorToolbar.getViewGroup(), false));
Adam Powell3f476b32011-01-03 19:25:36 -0800362 }
363
364 @Override
365 public void setDisplayUseLogoEnabled(boolean useLogo) {
366 setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO);
367 }
368
369 @Override
370 public void setDisplayShowHomeEnabled(boolean showHome) {
371 setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME);
372 }
373
374 @Override
375 public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
376 setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP);
377 }
378
379 @Override
380 public void setDisplayShowTitleEnabled(boolean showTitle) {
381 setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE);
382 }
383
384 @Override
385 public void setDisplayShowCustomEnabled(boolean showCustom) {
386 setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM);
387 }
388
389 @Override
Adam Powellc29f4e52011-07-13 20:40:52 -0700390 public void setHomeButtonEnabled(boolean enable) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700391 mDecorToolbar.setHomeButtonEnabled(enable);
Adam Powelldae78242011-04-25 15:23:41 -0700392 }
393
394 @Override
Adam Powella66c7b02010-07-28 15:28:25 -0700395 public void setTitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700396 setTitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700397 }
398
399 @Override
400 public void setSubtitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700401 setSubtitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700402 }
403
Adam Powell17809772010-07-21 13:25:11 -0700404 public void setSelectedNavigationItem(int position) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700405 switch (mDecorToolbar.getNavigationMode()) {
Adam Powell17809772010-07-21 13:25:11 -0700406 case NAVIGATION_MODE_TABS:
407 selectTab(mTabs.get(position));
408 break;
Adam Powell9ab97872010-10-26 21:47:29 -0700409 case NAVIGATION_MODE_LIST:
Adam Powelle021e6e2014-05-23 17:27:24 -0700410 mDecorToolbar.setDropdownSelectedPosition(position);
Adam Powell17809772010-07-21 13:25:11 -0700411 break;
412 default:
413 throw new IllegalStateException(
Adam Powell9ab97872010-10-26 21:47:29 -0700414 "setSelectedNavigationIndex not valid for current navigation mode");
Adam Powell17809772010-07-21 13:25:11 -0700415 }
416 }
417
Adam Powell9ab97872010-10-26 21:47:29 -0700418 public void removeAllTabs() {
419 cleanupTabs();
Adam Powell17809772010-07-21 13:25:11 -0700420 }
421
Adam Powell661c9082010-07-02 10:09:44 -0700422 private void cleanupTabs() {
423 if (mSelectedTab != null) {
424 selectTab(null);
425 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700426 mTabs.clear();
Adam Powelld21aa122011-05-27 13:09:52 -0700427 if (mTabScrollView != null) {
428 mTabScrollView.removeAllTabs();
429 }
Adam Powell0c24a552010-11-03 16:44:11 -0700430 mSavedTabPosition = INVALID_POSITION;
Adam Powell661c9082010-07-02 10:09:44 -0700431 }
432
Adam Powell0e94b512010-06-29 17:58:20 -0700433 public void setTitle(CharSequence title) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700434 mDecorToolbar.setTitle(title);
Adam Powell0e94b512010-06-29 17:58:20 -0700435 }
436
Adam Powellaf2d8592014-08-26 18:06:40 -0700437 @Override
438 public void setWindowTitle(CharSequence title) {
439 mDecorToolbar.setWindowTitle(title);
440 }
441
Adam Powell0e94b512010-06-29 17:58:20 -0700442 public void setSubtitle(CharSequence subtitle) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700443 mDecorToolbar.setSubtitle(subtitle);
Adam Powell0e94b512010-06-29 17:58:20 -0700444 }
445
Adam Powell89e06452010-06-23 20:24:52 -0700446 public void setDisplayOptions(int options) {
Adam Powelldd8fab22012-03-22 17:47:27 -0700447 if ((options & DISPLAY_HOME_AS_UP) != 0) {
448 mDisplayHomeAsUpSet = true;
449 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700450 mDecorToolbar.setDisplayOptions(options);
Adam Powell89e06452010-06-23 20:24:52 -0700451 }
Adam Powell0e94b512010-06-29 17:58:20 -0700452
Adam Powell89e06452010-06-23 20:24:52 -0700453 public void setDisplayOptions(int options, int mask) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700454 final int current = mDecorToolbar.getDisplayOptions();
Adam Powelldd8fab22012-03-22 17:47:27 -0700455 if ((mask & DISPLAY_HOME_AS_UP) != 0) {
456 mDisplayHomeAsUpSet = true;
457 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700458 mDecorToolbar.setDisplayOptions((options & mask) | (current & ~mask));
Adam Powell89e06452010-06-23 20:24:52 -0700459 }
460
461 public void setBackgroundDrawable(Drawable d) {
Adam Powellf88b9152011-09-07 14:54:32 -0700462 mContainerView.setPrimaryBackground(d);
463 }
464
465 public void setStackedBackgroundDrawable(Drawable d) {
466 mContainerView.setStackedBackground(d);
467 }
468
469 public void setSplitBackgroundDrawable(Drawable d) {
470 if (mSplitView != null) {
471 mSplitView.setSplitBackground(d);
472 }
Adam Powell89e06452010-06-23 20:24:52 -0700473 }
474
Adam Powellef704442010-11-16 14:48:22 -0800475 public View getCustomView() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700476 return mDecorToolbar.getCustomView();
Adam Powell89e06452010-06-23 20:24:52 -0700477 }
478
479 public CharSequence getTitle() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700480 return mDecorToolbar.getTitle();
Adam Powell89e06452010-06-23 20:24:52 -0700481 }
482
483 public CharSequence getSubtitle() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700484 return mDecorToolbar.getSubtitle();
Adam Powell89e06452010-06-23 20:24:52 -0700485 }
486
487 public int getNavigationMode() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700488 return mDecorToolbar.getNavigationMode();
Adam Powell89e06452010-06-23 20:24:52 -0700489 }
490
491 public int getDisplayOptions() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700492 return mDecorToolbar.getDisplayOptions();
Adam Powell89e06452010-06-23 20:24:52 -0700493 }
494
Adam Powell5d279772010-07-27 16:34:07 -0700495 public ActionMode startActionMode(ActionMode.Callback callback) {
Clara Bayarri4423d912015-03-02 19:42:48 +0000496 if (mActionMode != null) {
497 mActionMode.finish();
498 }
Adam Powell3461b322010-07-14 11:34:43 -0700499
Clara Bayarri4423d912015-03-02 19:42:48 +0000500 mOverlayLayout.setHideOnContentScrollEnabled(false);
501 mContextView.killMode();
502 ActionModeImpl mode = new ActionModeImpl(mContextView.getContext(), callback);
503 if (mode.dispatchOnCreate()) {
504 mode.invalidate();
Adam Powell640a66e2011-04-29 10:18:53 -0700505 mContextView.initForMode(mode);
506 animateToMode(true);
Adam Powell1ab418a2011-06-09 20:49:49 -0700507 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
Adam Powell89e06452010-06-23 20:24:52 -0700508 // TODO animate this
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700509 if (mSplitView.getVisibility() != View.VISIBLE) {
510 mSplitView.setVisibility(View.VISIBLE);
511 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700512 mOverlayLayout.requestApplyInsets();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700513 }
514 }
Adam Powell89e06452010-06-23 20:24:52 -0700515 }
Adam Powell86ed4362011-09-14 16:18:53 -0700516 mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Adam Powell5d279772010-07-27 16:34:07 -0700517 mActionMode = mode;
Adam Powellac695c62010-07-20 18:19:27 -0700518 return mode;
Adam Powell89e06452010-06-23 20:24:52 -0700519 }
Clara Bayarri4423d912015-03-02 19:42:48 +0000520 return null;
Adam Powell89e06452010-06-23 20:24:52 -0700521 }
522
Adam Powell661c9082010-07-02 10:09:44 -0700523 private void configureTab(Tab tab, int position) {
524 final TabImpl tabi = (TabImpl) tab;
Adam Powell2b6230e2010-09-07 17:55:25 -0700525 final ActionBar.TabListener callback = tabi.getCallback();
526
527 if (callback == null) {
528 throw new IllegalStateException("Action Bar Tab must have a Callback");
529 }
Adam Powell661c9082010-07-02 10:09:44 -0700530
531 tabi.setPosition(position);
532 mTabs.add(position, tabi);
533
Adam Powell81b89442010-11-02 17:58:56 -0700534 final int count = mTabs.size();
535 for (int i = position + 1; i < count; i++) {
536 mTabs.get(i).setPosition(i);
Adam Powell661c9082010-07-02 10:09:44 -0700537 }
Adam Powell661c9082010-07-02 10:09:44 -0700538 }
539
540 @Override
541 public void addTab(Tab tab) {
Adam Powell81b89442010-11-02 17:58:56 -0700542 addTab(tab, mTabs.isEmpty());
Adam Powell661c9082010-07-02 10:09:44 -0700543 }
544
545 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700546 public void addTab(Tab tab, int position) {
Adam Powell81b89442010-11-02 17:58:56 -0700547 addTab(tab, position, mTabs.isEmpty());
548 }
549
550 @Override
551 public void addTab(Tab tab, boolean setSelected) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700552 ensureTabsExist();
553 mTabScrollView.addTab(tab, setSelected);
Adam Powell81b89442010-11-02 17:58:56 -0700554 configureTab(tab, mTabs.size());
555 if (setSelected) {
556 selectTab(tab);
557 }
558 }
559
560 @Override
561 public void addTab(Tab tab, int position, boolean setSelected) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700562 ensureTabsExist();
563 mTabScrollView.addTab(tab, position, setSelected);
Adam Powell661c9082010-07-02 10:09:44 -0700564 configureTab(tab, position);
Adam Powell81b89442010-11-02 17:58:56 -0700565 if (setSelected) {
566 selectTab(tab);
567 }
Adam Powell661c9082010-07-02 10:09:44 -0700568 }
569
570 @Override
571 public Tab newTab() {
572 return new TabImpl();
573 }
574
575 @Override
576 public void removeTab(Tab tab) {
577 removeTabAt(tab.getPosition());
578 }
579
580 @Override
581 public void removeTabAt(int position) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700582 if (mTabScrollView == null) {
583 // No tabs around to remove
584 return;
585 }
586
Adam Powell0c24a552010-11-03 16:44:11 -0700587 int selectedTabPosition = mSelectedTab != null
588 ? mSelectedTab.getPosition() : mSavedTabPosition;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700589 mTabScrollView.removeTabAt(position);
Adam Powell0d8ec1d2011-05-03 14:49:13 -0700590 TabImpl removedTab = mTabs.remove(position);
591 if (removedTab != null) {
592 removedTab.setPosition(-1);
593 }
Adam Powell661c9082010-07-02 10:09:44 -0700594
595 final int newTabCount = mTabs.size();
596 for (int i = position; i < newTabCount; i++) {
597 mTabs.get(i).setPosition(i);
598 }
599
Adam Powell0c24a552010-11-03 16:44:11 -0700600 if (selectedTabPosition == position) {
601 selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
602 }
Adam Powell661c9082010-07-02 10:09:44 -0700603 }
604
605 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700606 public void selectTab(Tab tab) {
Adam Powell0c24a552010-11-03 16:44:11 -0700607 if (getNavigationMode() != NAVIGATION_MODE_TABS) {
608 mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
609 return;
610 }
611
Adam Powell76d14662014-05-30 10:28:14 -0700612 final FragmentTransaction trans = mDecorToolbar.getViewGroup().isInEditMode() ? null :
Deepanshu Gupta14bf0ce2013-12-12 12:16:24 -0800613 mActivity.getFragmentManager().beginTransaction().disallowAddToBackStack();
Adam Powell7f9b9052010-10-19 16:56:07 -0700614
615 if (mSelectedTab == tab) {
616 if (mSelectedTab != null) {
617 mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700618 mTabScrollView.animateToTab(tab.getPosition());
Adam Powell7f9b9052010-10-19 16:56:07 -0700619 }
620 } else {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700621 mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
Adam Powell7f9b9052010-10-19 16:56:07 -0700622 if (mSelectedTab != null) {
623 mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
624 }
625 mSelectedTab = (TabImpl) tab;
626 if (mSelectedTab != null) {
627 mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
628 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700629 }
630
Deepanshu Gupta14bf0ce2013-12-12 12:16:24 -0800631 if (trans != null && !trans.isEmpty()) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700632 trans.commit();
633 }
634 }
635
636 @Override
637 public Tab getSelectedTab() {
638 return mSelectedTab;
Adam Powell661c9082010-07-02 10:09:44 -0700639 }
640
Adam Powell6b336f82010-08-10 20:13:01 -0700641 @Override
642 public int getHeight() {
Adam Powell58c5dc12011-07-14 21:08:10 -0700643 return mContainerView.getHeight();
Adam Powell6b336f82010-08-10 20:13:01 -0700644 }
645
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800646 public void enableContentAnimations(boolean enabled) {
647 mContentAnimations = enabled;
648 }
649
Adam Powell6b336f82010-08-10 20:13:01 -0700650 @Override
651 public void show() {
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700652 if (mHiddenByApp) {
653 mHiddenByApp = false;
654 updateVisibility(false);
655 }
Adam Powell07e1f982011-03-24 11:11:15 -0700656 }
657
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700658 private void showForActionMode() {
659 if (!mShowingForMode) {
660 mShowingForMode = true;
661 if (mOverlayLayout != null) {
662 mOverlayLayout.setShowingForActionMode(true);
663 }
664 updateVisibility(false);
665 }
666 }
667
668 public void showForSystem() {
669 if (mHiddenBySystem) {
670 mHiddenBySystem = false;
671 updateVisibility(true);
672 }
673 }
674
675 @Override
676 public void hide() {
677 if (!mHiddenByApp) {
678 mHiddenByApp = true;
679 updateVisibility(false);
680 }
681 }
682
683 private void hideForActionMode() {
684 if (mShowingForMode) {
685 mShowingForMode = false;
686 if (mOverlayLayout != null) {
687 mOverlayLayout.setShowingForActionMode(false);
688 }
689 updateVisibility(false);
690 }
691 }
692
693 public void hideForSystem() {
694 if (!mHiddenBySystem) {
695 mHiddenBySystem = true;
696 updateVisibility(true);
697 }
698 }
699
Adam Powellb36e4f92014-05-01 10:23:33 -0700700 @Override
701 public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) {
702 if (hideOnContentScroll && !mOverlayLayout.isInOverlayMode()) {
703 throw new IllegalStateException("Action bar must be in overlay mode " +
704 "(Window.FEATURE_OVERLAY_ACTION_BAR) to enable hide on content scroll");
705 }
706 mHideOnContentScroll = hideOnContentScroll;
707 mOverlayLayout.setHideOnContentScrollEnabled(hideOnContentScroll);
708 }
709
710 @Override
711 public boolean isHideOnContentScrollEnabled() {
712 return mOverlayLayout.isHideOnContentScrollEnabled();
713 }
714
715 @Override
716 public int getHideOffset() {
717 return mOverlayLayout.getActionBarHideOffset();
718 }
719
720 @Override
721 public void setHideOffset(int offset) {
722 if (offset != 0 && !mOverlayLayout.isInOverlayMode()) {
723 throw new IllegalStateException("Action bar must be in overlay mode " +
724 "(Window.FEATURE_OVERLAY_ACTION_BAR) to set a non-zero hide offset");
725 }
726 mOverlayLayout.setActionBarHideOffset(offset);
727 }
728
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700729 private static boolean checkShowingFlags(boolean hiddenByApp, boolean hiddenBySystem,
730 boolean showingForMode) {
731 if (showingForMode) {
732 return true;
733 } else if (hiddenByApp || hiddenBySystem) {
734 return false;
735 } else {
736 return true;
737 }
738 }
739
740 private void updateVisibility(boolean fromSystem) {
741 // Based on the current state, should we be hidden or shown?
742 final boolean shown = checkShowingFlags(mHiddenByApp, mHiddenBySystem,
743 mShowingForMode);
744
745 if (shown) {
746 if (!mNowShowing) {
747 mNowShowing = true;
748 doShow(fromSystem);
749 }
750 } else {
751 if (mNowShowing) {
752 mNowShowing = false;
753 doHide(fromSystem);
754 }
755 }
756 }
757
758 public void doShow(boolean fromSystem) {
Adam Powell07e1f982011-03-24 11:11:15 -0700759 if (mCurrentShowAnim != null) {
760 mCurrentShowAnim.end();
Adam Powell45f1e082010-12-10 14:20:13 -0800761 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700762 mContainerView.setVisibility(View.VISIBLE);
Adam Powell50efbed2011-02-08 16:20:15 -0800763
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700764 if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700765 || fromSystem)) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700766 mContainerView.setTranslationY(0); // because we're about to ask its window loc
767 float startingY = -mContainerView.getHeight();
Chet Haasee8118e12012-05-30 14:19:02 -0700768 if (fromSystem) {
769 int topLeft[] = {0, 0};
Adam Powell9b0dc282013-07-31 13:58:43 -0700770 mContainerView.getLocationInWindow(topLeft);
Chet Haasee8118e12012-05-30 14:19:02 -0700771 startingY -= topLeft[1];
772 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700773 mContainerView.setTranslationY(startingY);
Adam Powell50efbed2011-02-08 16:20:15 -0800774 AnimatorSet anim = new AnimatorSet();
Adam Powell9b0dc282013-07-31 13:58:43 -0700775 ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, 0);
776 a.addUpdateListener(mUpdateListener);
777 AnimatorSet.Builder b = anim.play(a);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800778 if (mContentAnimations && mContentView != null) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700779 b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
Chet Haasee8118e12012-05-30 14:19:02 -0700780 startingY, 0));
Adam Powell50efbed2011-02-08 16:20:15 -0800781 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700782 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700783 mSplitView.setTranslationY(mSplitView.getHeight());
Adam Powell993a63a2011-08-18 16:35:53 -0700784 mSplitView.setVisibility(View.VISIBLE);
Adam Powell9b0dc282013-07-31 13:58:43 -0700785 b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y, 0));
Adam Powell640a66e2011-04-29 10:18:53 -0700786 }
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700787 anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
Chet Haasee8118e12012-05-30 14:19:02 -0700788 com.android.internal.R.interpolator.decelerate_cubic));
789 anim.setDuration(250);
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700790 // If this is being shown from the system, add a small delay.
791 // This is because we will also be animating in the status bar,
792 // and these two elements can't be done in lock-step. So we give
793 // a little time for the status bar to start its animation before
794 // the action bar animates. (This corresponds to the corresponding
795 // case when hiding, where the status bar has a small delay before
796 // starting.)
Adam Powell50efbed2011-02-08 16:20:15 -0800797 anim.addListener(mShowListener);
Adam Powell07e1f982011-03-24 11:11:15 -0700798 mCurrentShowAnim = anim;
Adam Powell50efbed2011-02-08 16:20:15 -0800799 anim.start();
800 } else {
Adam Powell9b0dc282013-07-31 13:58:43 -0700801 mContainerView.setAlpha(1);
802 mContainerView.setTranslationY(0);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800803 if (mContentAnimations && mContentView != null) {
Dianne Hackborn80d55062012-05-22 18:03:20 -0700804 mContentView.setTranslationY(0);
805 }
806 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
807 mSplitView.setAlpha(1);
808 mSplitView.setTranslationY(0);
809 mSplitView.setVisibility(View.VISIBLE);
810 }
Adam Powell50efbed2011-02-08 16:20:15 -0800811 mShowListener.onAnimationEnd(null);
Adam Powelle6ec7322010-12-07 15:29:26 -0800812 }
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700813 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700814 mOverlayLayout.requestApplyInsets();
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700815 }
Adam Powell6b336f82010-08-10 20:13:01 -0700816 }
817
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700818 public void doHide(boolean fromSystem) {
Adam Powell07e1f982011-03-24 11:11:15 -0700819 if (mCurrentShowAnim != null) {
820 mCurrentShowAnim.end();
Adam Powelle6ec7322010-12-07 15:29:26 -0800821 }
Adam Powell50efbed2011-02-08 16:20:15 -0800822
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700823 if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700824 || fromSystem)) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700825 mContainerView.setAlpha(1);
Adam Powell01feaee2011-02-10 15:05:05 -0800826 mContainerView.setTransitioning(true);
Adam Powell50efbed2011-02-08 16:20:15 -0800827 AnimatorSet anim = new AnimatorSet();
Adam Powell9b0dc282013-07-31 13:58:43 -0700828 float endingY = -mContainerView.getHeight();
Chet Haasee8118e12012-05-30 14:19:02 -0700829 if (fromSystem) {
830 int topLeft[] = {0, 0};
Adam Powell9b0dc282013-07-31 13:58:43 -0700831 mContainerView.getLocationInWindow(topLeft);
Chet Haasee8118e12012-05-30 14:19:02 -0700832 endingY -= topLeft[1];
833 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700834 ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, endingY);
835 a.addUpdateListener(mUpdateListener);
836 AnimatorSet.Builder b = anim.play(a);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800837 if (mContentAnimations && mContentView != null) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700838 b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
Chet Haasee8118e12012-05-30 14:19:02 -0700839 0, endingY));
Adam Powell50efbed2011-02-08 16:20:15 -0800840 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700841 if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
Adam Powell640a66e2011-04-29 10:18:53 -0700842 mSplitView.setAlpha(1);
Adam Powell9b0dc282013-07-31 13:58:43 -0700843 b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y,
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700844 mSplitView.getHeight()));
Adam Powell640a66e2011-04-29 10:18:53 -0700845 }
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700846 anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
Chet Haasee8118e12012-05-30 14:19:02 -0700847 com.android.internal.R.interpolator.accelerate_cubic));
848 anim.setDuration(250);
Adam Powell50efbed2011-02-08 16:20:15 -0800849 anim.addListener(mHideListener);
Adam Powell07e1f982011-03-24 11:11:15 -0700850 mCurrentShowAnim = anim;
Adam Powell50efbed2011-02-08 16:20:15 -0800851 anim.start();
852 } else {
853 mHideListener.onAnimationEnd(null);
Adam Powelle6ec7322010-12-07 15:29:26 -0800854 }
Adam Powell6b336f82010-08-10 20:13:01 -0700855 }
856
857 public boolean isShowing() {
Adam Powellf65bfb72014-06-19 10:55:28 -0700858 final int height = getHeight();
859 // Take into account the case where the bar has a 0 height due to not being measured yet.
860 return mNowShowing && (height == 0 || getHideOffset() < height);
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800861 }
862
Adam Powell640a66e2011-04-29 10:18:53 -0700863 void animateToMode(boolean toActionMode) {
Adam Powell060e3ca2011-07-19 20:39:16 -0700864 if (toActionMode) {
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700865 showForActionMode();
866 } else {
867 hideForActionMode();
Adam Powell07e1f982011-03-24 11:11:15 -0700868 }
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800869
Adam Powelle021e6e2014-05-23 17:27:24 -0700870 mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
Adam Powell640a66e2011-04-29 10:18:53 -0700871 mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
Yigit Boyar2bbad0c2014-09-16 18:28:03 -0700872 // mTabScrollView's visibility is not affected by action mode.
Adam Powelle021e6e2014-05-23 17:27:24 -0700873 }
874
Adam Powell88ab6972011-07-28 11:25:01 -0700875 public Context getThemedContext() {
876 if (mThemedContext == null) {
877 TypedValue outValue = new TypedValue();
878 Resources.Theme currentTheme = mContext.getTheme();
879 currentTheme.resolveAttribute(com.android.internal.R.attr.actionBarWidgetTheme,
880 outValue, true);
881 final int targetThemeRes = outValue.resourceId;
Alan Viverette3abf5c42014-10-29 11:03:35 -0700882
Adam Powell88ab6972011-07-28 11:25:01 -0700883 if (targetThemeRes != 0 && mContext.getThemeResId() != targetThemeRes) {
884 mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes);
885 } else {
886 mThemedContext = mContext;
887 }
888 }
889 return mThemedContext;
890 }
Alan Viverette3abf5c42014-10-29 11:03:35 -0700891
Adam Powell27cba382013-01-22 18:55:20 -0800892 @Override
893 public boolean isTitleTruncated() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700894 return mDecorToolbar != null && mDecorToolbar.isTitleTruncated();
Adam Powell27cba382013-01-22 18:55:20 -0800895 }
896
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700897 @Override
898 public void setHomeAsUpIndicator(Drawable indicator) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700899 mDecorToolbar.setNavigationIcon(indicator);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700900 }
901
902 @Override
903 public void setHomeAsUpIndicator(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700904 mDecorToolbar.setNavigationIcon(resId);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700905 }
906
907 @Override
908 public void setHomeActionContentDescription(CharSequence description) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700909 mDecorToolbar.setNavigationContentDescription(description);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700910 }
911
912 @Override
913 public void setHomeActionContentDescription(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700914 mDecorToolbar.setNavigationContentDescription(resId);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700915 }
916
Adam Powellb36e4f92014-05-01 10:23:33 -0700917 @Override
918 public void onContentScrollStarted() {
919 if (mCurrentShowAnim != null) {
920 mCurrentShowAnim.cancel();
921 mCurrentShowAnim = null;
922 }
923 }
924
925 @Override
926 public void onContentScrollStopped() {
927 }
928
Adam Powell5352a892014-08-20 17:33:24 -0700929 @Override
930 public boolean collapseActionView() {
931 if (mDecorToolbar != null && mDecorToolbar.hasExpandedActionView()) {
932 mDecorToolbar.collapseActionView();
933 return true;
934 }
935 return false;
936 }
937
Adam Powell89e06452010-06-23 20:24:52 -0700938 /**
Alan Viverette3abf5c42014-10-29 11:03:35 -0700939 * @hide
Adam Powell89e06452010-06-23 20:24:52 -0700940 */
Adam Powell5d279772010-07-27 16:34:07 -0700941 public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
Alan Viverette3abf5c42014-10-29 11:03:35 -0700942 private final Context mActionModeContext;
943 private final MenuBuilder mMenu;
944
Adam Powell6e346362010-07-23 10:18:23 -0700945 private ActionMode.Callback mCallback;
Adam Powell29ed7572010-07-14 16:24:56 -0700946 private WeakReference<View> mCustomView;
Alan Viverette3abf5c42014-10-29 11:03:35 -0700947
Clara Bayarric57e7bc2015-02-13 12:07:52 +0000948 public ActionModeImpl(
Clara Bayarri4423d912015-03-02 19:42:48 +0000949 Context context, ActionMode.Callback callback) {
Alan Viverette3abf5c42014-10-29 11:03:35 -0700950 mActionModeContext = context;
Adam Powell89e06452010-06-23 20:24:52 -0700951 mCallback = callback;
Clara Bayarri4423d912015-03-02 19:42:48 +0000952 mMenu = new MenuBuilder(context)
953 .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700954 mMenu.setCallback(this);
Adam Powell89e06452010-06-23 20:24:52 -0700955 }
Adam Powell9168f0b2010-08-02 15:46:24 -0700956
957 @Override
958 public MenuInflater getMenuInflater() {
Alan Viverette3abf5c42014-10-29 11:03:35 -0700959 return new MenuInflater(mActionModeContext);
Adam Powell9168f0b2010-08-02 15:46:24 -0700960 }
961
Adam Powell89e06452010-06-23 20:24:52 -0700962 @Override
963 public Menu getMenu() {
964 return mMenu;
965 }
966
967 @Override
968 public void finish() {
Adam Powell5d279772010-07-27 16:34:07 -0700969 if (mActionMode != this) {
970 // Not the active action mode - no-op
Adam Powell93b6bc32010-07-22 11:36:35 -0700971 return;
972 }
973
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700974 // If this change in state is going to cause the action bar
975 // to be hidden, defer the onDestroy callback until the animation
976 // is finished and associated relayout is about to happen. This lets
977 // apps better anticipate visibility and layout behavior.
978 if (!checkShowingFlags(mHiddenByApp, mHiddenBySystem, false)) {
979 // With the current state but the action bar hidden, our
980 // overall showing state is going to be false.
Adam Powell060e3ca2011-07-19 20:39:16 -0700981 mDeferredDestroyActionMode = this;
982 mDeferredModeDestroyCallback = mCallback;
983 } else {
984 mCallback.onDestroyActionMode(this);
985 }
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800986 mCallback = null;
Adam Powell640a66e2011-04-29 10:18:53 -0700987 animateToMode(false);
Adam Powell0e94b512010-06-29 17:58:20 -0700988
989 // Clear out the context mode views after the animation finishes
Adam Powell640a66e2011-04-29 10:18:53 -0700990 mContextView.closeMode();
Adam Powell76d14662014-05-30 10:28:14 -0700991 mDecorToolbar.getViewGroup().sendAccessibilityEvent(
Adam Powelle021e6e2014-05-23 17:27:24 -0700992 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Adam Powellb36e4f92014-05-01 10:23:33 -0700993 mOverlayLayout.setHideOnContentScrollEnabled(mHideOnContentScroll);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700994
Adam Powell5d279772010-07-27 16:34:07 -0700995 mActionMode = null;
Adam Powell89e06452010-06-23 20:24:52 -0700996 }
997
998 @Override
999 public void invalidate() {
Paul Millerf6bf1d72014-12-19 17:51:18 -08001000 if (mActionMode != this) {
1001 // Not the active action mode - no-op. It's possible we are
1002 // currently deferring onDestroy, so the app doesn't yet know we
1003 // are going away and is trying to use us. That's also a no-op.
1004 return;
1005 }
1006
Adam Powell5ee36c42011-06-02 12:59:43 -07001007 mMenu.stopDispatchingItemsChanged();
1008 try {
1009 mCallback.onPrepareActionMode(this, mMenu);
1010 } finally {
1011 mMenu.startDispatchingItemsChanged();
1012 }
1013 }
1014
Clara Bayarri4423d912015-03-02 19:42:48 +00001015 public boolean dispatchOnCreate() {
1016 mMenu.stopDispatchingItemsChanged();
1017 try {
1018 return mCallback.onCreateActionMode(this, mMenu);
1019 } finally {
1020 mMenu.startDispatchingItemsChanged();
1021 }
1022 }
1023
Adam Powell89e06452010-06-23 20:24:52 -07001024 @Override
1025 public void setCustomView(View view) {
Adam Powell640a66e2011-04-29 10:18:53 -07001026 mContextView.setCustomView(view);
Adam Powell29ed7572010-07-14 16:24:56 -07001027 mCustomView = new WeakReference<View>(view);
Adam Powell89e06452010-06-23 20:24:52 -07001028 }
1029
1030 @Override
1031 public void setSubtitle(CharSequence subtitle) {
Adam Powell640a66e2011-04-29 10:18:53 -07001032 mContextView.setSubtitle(subtitle);
Adam Powell89e06452010-06-23 20:24:52 -07001033 }
1034
1035 @Override
1036 public void setTitle(CharSequence title) {
Adam Powell640a66e2011-04-29 10:18:53 -07001037 mContextView.setTitle(title);
Adam Powell89e06452010-06-23 20:24:52 -07001038 }
Adam Powell29ed7572010-07-14 16:24:56 -07001039
1040 @Override
Adam Powellc9ae2a22010-07-28 14:44:21 -07001041 public void setTitle(int resId) {
Adam Powell48e8ac32011-01-14 12:10:24 -08001042 setTitle(mContext.getResources().getString(resId));
Adam Powellc9ae2a22010-07-28 14:44:21 -07001043 }
1044
1045 @Override
1046 public void setSubtitle(int resId) {
Adam Powell48e8ac32011-01-14 12:10:24 -08001047 setSubtitle(mContext.getResources().getString(resId));
Adam Powellc9ae2a22010-07-28 14:44:21 -07001048 }
1049
1050 @Override
Adam Powell29ed7572010-07-14 16:24:56 -07001051 public CharSequence getTitle() {
Adam Powell640a66e2011-04-29 10:18:53 -07001052 return mContextView.getTitle();
Adam Powell29ed7572010-07-14 16:24:56 -07001053 }
1054
1055 @Override
1056 public CharSequence getSubtitle() {
Adam Powell640a66e2011-04-29 10:18:53 -07001057 return mContextView.getSubtitle();
Adam Powell29ed7572010-07-14 16:24:56 -07001058 }
Alan Viverette3abf5c42014-10-29 11:03:35 -07001059
Adam Powell29ed7572010-07-14 16:24:56 -07001060 @Override
Adam Powellb98a81f2012-02-24 11:09:07 -08001061 public void setTitleOptionalHint(boolean titleOptional) {
Adam Powell785c4472012-05-02 21:25:39 -07001062 super.setTitleOptionalHint(titleOptional);
Adam Powellb98a81f2012-02-24 11:09:07 -08001063 mContextView.setTitleOptional(titleOptional);
1064 }
1065
1066 @Override
1067 public boolean isTitleOptional() {
1068 return mContextView.isTitleOptional();
1069 }
1070
1071 @Override
Adam Powell29ed7572010-07-14 16:24:56 -07001072 public View getCustomView() {
1073 return mCustomView != null ? mCustomView.get() : null;
1074 }
1075
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001076 public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -08001077 if (mCallback != null) {
1078 return mCallback.onActionItemClicked(this, item);
1079 } else {
1080 return false;
1081 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001082 }
1083
1084 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1085 }
1086
1087 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -08001088 if (mCallback == null) {
1089 return false;
1090 }
1091
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001092 if (!subMenu.hasVisibleItems()) {
1093 return true;
Adam Powell89e06452010-06-23 20:24:52 -07001094 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001095
Adam Powellf2423682011-08-11 14:29:45 -07001096 new MenuPopupHelper(getThemedContext(), subMenu).show();
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001097 return true;
1098 }
1099
1100 public void onCloseSubMenu(SubMenuBuilder menu) {
1101 }
1102
1103 public void onMenuModeChange(MenuBuilder menu) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -08001104 if (mCallback == null) {
1105 return;
1106 }
Adam Powellf6148c52010-08-11 21:10:16 -07001107 invalidate();
Adam Powell640a66e2011-04-29 10:18:53 -07001108 mContextView.showOverflowMenu();
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001109 }
Adam Powell661c9082010-07-02 10:09:44 -07001110 }
1111
1112 /**
1113 * @hide
1114 */
1115 public class TabImpl extends ActionBar.Tab {
Adam Powell2b6230e2010-09-07 17:55:25 -07001116 private ActionBar.TabListener mCallback;
1117 private Object mTag;
Adam Powell661c9082010-07-02 10:09:44 -07001118 private Drawable mIcon;
1119 private CharSequence mText;
Adam Powell94e56ef2011-09-06 21:22:22 -07001120 private CharSequence mContentDesc;
Adam Powell0d8ec1d2011-05-03 14:49:13 -07001121 private int mPosition = -1;
Adam Powell2b6230e2010-09-07 17:55:25 -07001122 private View mCustomView;
Adam Powell661c9082010-07-02 10:09:44 -07001123
1124 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -07001125 public Object getTag() {
1126 return mTag;
1127 }
1128
1129 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001130 public Tab setTag(Object tag) {
Adam Powell2b6230e2010-09-07 17:55:25 -07001131 mTag = tag;
Adam Powell9ab97872010-10-26 21:47:29 -07001132 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -07001133 }
1134
1135 public ActionBar.TabListener getCallback() {
1136 return mCallback;
1137 }
1138
1139 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001140 public Tab setTabListener(ActionBar.TabListener callback) {
Adam Powell2b6230e2010-09-07 17:55:25 -07001141 mCallback = callback;
Adam Powell9ab97872010-10-26 21:47:29 -07001142 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -07001143 }
1144
1145 @Override
1146 public View getCustomView() {
1147 return mCustomView;
1148 }
1149
1150 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001151 public Tab setCustomView(View view) {
Adam Powell2b6230e2010-09-07 17:55:25 -07001152 mCustomView = view;
Adam Powellf8ac6b72011-05-23 18:14:09 -07001153 if (mPosition >= 0) {
1154 mTabScrollView.updateTab(mPosition);
1155 }
Adam Powell9ab97872010-10-26 21:47:29 -07001156 return this;
Adam Powell661c9082010-07-02 10:09:44 -07001157 }
1158
1159 @Override
Adam Powell32555f32010-11-17 13:49:22 -08001160 public Tab setCustomView(int layoutResId) {
Adam Powellf2423682011-08-11 14:29:45 -07001161 return setCustomView(LayoutInflater.from(getThemedContext())
1162 .inflate(layoutResId, null));
Adam Powell32555f32010-11-17 13:49:22 -08001163 }
1164
1165 @Override
Adam Powell661c9082010-07-02 10:09:44 -07001166 public Drawable getIcon() {
1167 return mIcon;
1168 }
1169
1170 @Override
1171 public int getPosition() {
1172 return mPosition;
1173 }
1174
1175 public void setPosition(int position) {
1176 mPosition = position;
1177 }
1178
1179 @Override
1180 public CharSequence getText() {
1181 return mText;
1182 }
1183
1184 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001185 public Tab setIcon(Drawable icon) {
Adam Powell661c9082010-07-02 10:09:44 -07001186 mIcon = icon;
Adam Powellf8ac6b72011-05-23 18:14:09 -07001187 if (mPosition >= 0) {
1188 mTabScrollView.updateTab(mPosition);
1189 }
Adam Powell9ab97872010-10-26 21:47:29 -07001190 return this;
Adam Powell661c9082010-07-02 10:09:44 -07001191 }
1192
1193 @Override
Adam Powell32555f32010-11-17 13:49:22 -08001194 public Tab setIcon(int resId) {
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001195 return setIcon(mContext.getDrawable(resId));
Adam Powell32555f32010-11-17 13:49:22 -08001196 }
1197
1198 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001199 public Tab setText(CharSequence text) {
Adam Powell661c9082010-07-02 10:09:44 -07001200 mText = text;
Adam Powellf8ac6b72011-05-23 18:14:09 -07001201 if (mPosition >= 0) {
1202 mTabScrollView.updateTab(mPosition);
1203 }
Adam Powell9ab97872010-10-26 21:47:29 -07001204 return this;
Adam Powell661c9082010-07-02 10:09:44 -07001205 }
1206
1207 @Override
Adam Powell32555f32010-11-17 13:49:22 -08001208 public Tab setText(int resId) {
1209 return setText(mContext.getResources().getText(resId));
1210 }
1211
1212 @Override
Adam Powell661c9082010-07-02 10:09:44 -07001213 public void select() {
1214 selectTab(this);
Adam Powell89e06452010-06-23 20:24:52 -07001215 }
Adam Powell94e56ef2011-09-06 21:22:22 -07001216
1217 @Override
1218 public Tab setContentDescription(int resId) {
1219 return setContentDescription(mContext.getResources().getText(resId));
1220 }
1221
1222 @Override
1223 public Tab setContentDescription(CharSequence contentDesc) {
1224 mContentDesc = contentDesc;
1225 if (mPosition >= 0) {
1226 mTabScrollView.updateTab(mPosition);
1227 }
1228 return this;
1229 }
1230
1231 @Override
1232 public CharSequence getContentDescription() {
1233 return mContentDesc;
1234 }
Adam Powell89e06452010-06-23 20:24:52 -07001235 }
Adam Powell9ab97872010-10-26 21:47:29 -07001236
1237 @Override
1238 public void setCustomView(View view) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001239 mDecorToolbar.setCustomView(view);
Adam Powell9ab97872010-10-26 21:47:29 -07001240 }
1241
1242 @Override
1243 public void setCustomView(View view, LayoutParams layoutParams) {
1244 view.setLayoutParams(layoutParams);
Adam Powelle021e6e2014-05-23 17:27:24 -07001245 mDecorToolbar.setCustomView(view);
Adam Powell9ab97872010-10-26 21:47:29 -07001246 }
1247
1248 @Override
Adam Powell8515ee82010-11-30 14:09:55 -08001249 public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001250 mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
Adam Powell9ab97872010-10-26 21:47:29 -07001251 }
1252
1253 @Override
1254 public int getSelectedNavigationIndex() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001255 switch (mDecorToolbar.getNavigationMode()) {
Adam Powell9ab97872010-10-26 21:47:29 -07001256 case NAVIGATION_MODE_TABS:
Adam Powell04587962010-11-11 22:15:07 -08001257 return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
Adam Powell9ab97872010-10-26 21:47:29 -07001258 case NAVIGATION_MODE_LIST:
Adam Powelle021e6e2014-05-23 17:27:24 -07001259 return mDecorToolbar.getDropdownSelectedPosition();
Adam Powell9ab97872010-10-26 21:47:29 -07001260 default:
1261 return -1;
1262 }
1263 }
1264
1265 @Override
1266 public int getNavigationItemCount() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001267 switch (mDecorToolbar.getNavigationMode()) {
Adam Powell9ab97872010-10-26 21:47:29 -07001268 case NAVIGATION_MODE_TABS:
1269 return mTabs.size();
1270 case NAVIGATION_MODE_LIST:
Adam Powelle021e6e2014-05-23 17:27:24 -07001271 return mDecorToolbar.getDropdownItemCount();
Adam Powell9ab97872010-10-26 21:47:29 -07001272 default:
1273 return 0;
1274 }
1275 }
1276
1277 @Override
Adam Powell0c24a552010-11-03 16:44:11 -07001278 public int getTabCount() {
1279 return mTabs.size();
1280 }
1281
1282 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001283 public void setNavigationMode(int mode) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001284 final int oldMode = mDecorToolbar.getNavigationMode();
Adam Powell0c24a552010-11-03 16:44:11 -07001285 switch (oldMode) {
1286 case NAVIGATION_MODE_TABS:
1287 mSavedTabPosition = getSelectedNavigationIndex();
1288 selectTab(null);
Adam Powellf5645cb2011-08-10 22:49:02 -07001289 mTabScrollView.setVisibility(View.GONE);
Adam Powell0c24a552010-11-03 16:44:11 -07001290 break;
1291 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001292 if (oldMode != mode && !mHasEmbeddedTabs) {
1293 if (mOverlayLayout != null) {
1294 mOverlayLayout.requestFitSystemWindows();
1295 }
1296 }
Adam Powelle021e6e2014-05-23 17:27:24 -07001297 mDecorToolbar.setNavigationMode(mode);
Adam Powell0c24a552010-11-03 16:44:11 -07001298 switch (mode) {
1299 case NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -07001300 ensureTabsExist();
Adam Powellf5645cb2011-08-10 22:49:02 -07001301 mTabScrollView.setVisibility(View.VISIBLE);
Adam Powell0c24a552010-11-03 16:44:11 -07001302 if (mSavedTabPosition != INVALID_POSITION) {
1303 setSelectedNavigationItem(mSavedTabPosition);
1304 mSavedTabPosition = INVALID_POSITION;
1305 }
1306 break;
1307 }
Adam Powelle021e6e2014-05-23 17:27:24 -07001308 mDecorToolbar.setCollapsible(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
Adam Powellb36e4f92014-05-01 10:23:33 -07001309 mOverlayLayout.setHasNonEmbeddedTabs(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
Adam Powell9ab97872010-10-26 21:47:29 -07001310 }
1311
1312 @Override
1313 public Tab getTabAt(int index) {
1314 return mTabs.get(index);
1315 }
Adam Powell0c24a552010-11-03 16:44:11 -07001316
Adam Powell0c24a552010-11-03 16:44:11 -07001317
Adam Powell1969b872011-03-22 11:52:48 -07001318 @Override
1319 public void setIcon(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001320 mDecorToolbar.setIcon(resId);
Adam Powell1969b872011-03-22 11:52:48 -07001321 }
Adam Powell0c24a552010-11-03 16:44:11 -07001322
Adam Powell1969b872011-03-22 11:52:48 -07001323 @Override
1324 public void setIcon(Drawable icon) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001325 mDecorToolbar.setIcon(icon);
Adam Powell1969b872011-03-22 11:52:48 -07001326 }
1327
Adam Powell04fe6eb2013-05-31 14:39:48 -07001328 public boolean hasIcon() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001329 return mDecorToolbar.hasIcon();
Adam Powell04fe6eb2013-05-31 14:39:48 -07001330 }
1331
Adam Powell1969b872011-03-22 11:52:48 -07001332 @Override
1333 public void setLogo(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001334 mDecorToolbar.setLogo(resId);
Adam Powell1969b872011-03-22 11:52:48 -07001335 }
1336
1337 @Override
1338 public void setLogo(Drawable logo) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001339 mDecorToolbar.setLogo(logo);
Adam Powell0c24a552010-11-03 16:44:11 -07001340 }
Adam Powelldd8fab22012-03-22 17:47:27 -07001341
Adam Powell04fe6eb2013-05-31 14:39:48 -07001342 public boolean hasLogo() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001343 return mDecorToolbar.hasLogo();
Adam Powell04fe6eb2013-05-31 14:39:48 -07001344 }
1345
Adam Powelldd8fab22012-03-22 17:47:27 -07001346 public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
1347 if (!mDisplayHomeAsUpSet) {
1348 setDisplayHomeAsUpEnabled(enable);
1349 }
1350 }
Adam Powelle021e6e2014-05-23 17:27:24 -07001351
Adam Powell89e06452010-06-23 20:24:52 -07001352}