blob: 5c7a4e63fd7d652456c25c529bdc86f219cbfd39 [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 Powelle021e6e2014-05-23 17:27:24 -070021import android.view.ViewGroup;
Adam Powell9b0dc282013-07-31 13:58:43 -070022import android.view.ViewParent;
Adam Powelle021e6e2014-05-23 17:27:24 -070023import android.widget.AdapterView;
24import android.widget.Toolbar;
Adam Powellb36e4f92014-05-01 10:23:33 -070025import com.android.internal.R;
Adam Powellb8139af2012-04-19 13:52:46 -070026import com.android.internal.view.ActionBarPolicy;
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 Powell89e06452010-06-23 20:24:52 -070033import com.android.internal.widget.ActionBarView;
Adam Powelle021e6e2014-05-23 17:27:24 -070034import com.android.internal.widget.DecorToolbar;
Adam Powellf8ac6b72011-05-23 18:14:09 -070035import com.android.internal.widget.ScrollingTabContainerView;
Adam Powell89e06452010-06-23 20:24:52 -070036
Adam Powelld8b3f2e2010-12-02 13:37:03 -080037import android.animation.Animator;
Adam Powelld8b3f2e2010-12-02 13:37:03 -080038import android.animation.Animator.AnimatorListener;
Adam Powell07e1f982011-03-24 11:11:15 -070039import android.animation.AnimatorListenerAdapter;
Adam Powelld8b3f2e2010-12-02 13:37:03 -080040import android.animation.AnimatorSet;
Adam Powelle6ec7322010-12-07 15:29:26 -080041import android.animation.ObjectAnimator;
Adam Powell89e06452010-06-23 20:24:52 -070042import android.app.ActionBar;
Adam Powell661c9082010-07-02 10:09:44 -070043import android.app.Activity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070044import android.app.Dialog;
Adam Powell661c9082010-07-02 10:09:44 -070045import android.app.FragmentTransaction;
Adam Powelldec9dfd2010-08-09 15:27:54 -070046import android.content.Context;
Adam Powellf8ac6b72011-05-23 18:14:09 -070047import android.content.res.Configuration;
Adam Powell88ab6972011-07-28 11:25:01 -070048import android.content.res.Resources;
Adam Powell89e06452010-06-23 20:24:52 -070049import android.graphics.drawable.Drawable;
Adam Powell88ab6972011-07-28 11:25:01 -070050import android.util.TypedValue;
Adam Powell6e346362010-07-23 10:18:23 -070051import android.view.ActionMode;
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 Powelle021e6e2014-05-23 17:27:24 -070062import com.android.internal.widget.ToolbarWidgetWrapper;
Adam Powell89e06452010-06-23 20:24:52 -070063
Adam Powell29ed7572010-07-14 16:24:56 -070064import java.lang.ref.WeakReference;
Adam Powell661c9082010-07-02 10:09:44 -070065import java.util.ArrayList;
66
Adam Powell89e06452010-06-23 20:24:52 -070067/**
Adam Powelle43340c2014-03-17 19:10:43 -070068 * WindowDecorActionBar is the ActionBar implementation used
69 * by devices of all screen sizes as part of the window decor layout.
70 * If it detects a compatible decor, it will split contextual modes
71 * across both the ActionBarView at the top of the screen and
72 * a horizontal LinearLayout at the bottom which is normally hidden.
Adam Powell89e06452010-06-23 20:24:52 -070073 */
Adam Powellb36e4f92014-05-01 10:23:33 -070074public class WindowDecorActionBar extends ActionBar implements
75 ActionBarOverlayLayout.ActionBarVisibilityCallback {
Adam Powelle43340c2014-03-17 19:10:43 -070076 private static final String TAG = "WindowDecorActionBar";
Adam Powell661c9082010-07-02 10:09:44 -070077
Adam Powelldec9dfd2010-08-09 15:27:54 -070078 private Context mContext;
Adam Powell88ab6972011-07-28 11:25:01 -070079 private Context mThemedContext;
Adam Powell661c9082010-07-02 10:09:44 -070080 private Activity mActivity;
Adam Powelldec9dfd2010-08-09 15:27:54 -070081 private Dialog mDialog;
Adam Powell661c9082010-07-02 10:09:44 -070082
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -070083 private ActionBarOverlayLayout mOverlayLayout;
Adam Powell01feaee2011-02-10 15:05:05 -080084 private ActionBarContainer mContainerView;
Adam Powelle021e6e2014-05-23 17:27:24 -070085 private DecorToolbar mDecorToolbar;
Adam Powell640a66e2011-04-29 10:18:53 -070086 private ActionBarContextView mContextView;
87 private ActionBarContainer mSplitView;
Adam Powelle6ec7322010-12-07 15:29:26 -080088 private View mContentView;
Adam Powellf8ac6b72011-05-23 18:14:09 -070089 private ScrollingTabContainerView mTabScrollView;
Adam Powell661c9082010-07-02 10:09:44 -070090
91 private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
92
Adam Powell661c9082010-07-02 10:09:44 -070093 private TabImpl mSelectedTab;
Adam Powell0c24a552010-11-03 16:44:11 -070094 private int mSavedTabPosition = INVALID_POSITION;
Adam Powell89e06452010-06-23 20:24:52 -070095
Adam Powelldd8fab22012-03-22 17:47:27 -070096 private boolean mDisplayHomeAsUpSet;
97
Adam Powell060e3ca2011-07-19 20:39:16 -070098 ActionModeImpl mActionMode;
99 ActionMode mDeferredDestroyActionMode;
100 ActionMode.Callback mDeferredModeDestroyCallback;
Adam Powell89e06452010-06-23 20:24:52 -0700101
Adam Powell8515ee82010-11-30 14:09:55 -0800102 private boolean mLastMenuVisibility;
103 private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
104 new ArrayList<OnMenuVisibilityListener>();
105
Adam Powell89e06452010-06-23 20:24:52 -0700106 private static final int CONTEXT_DISPLAY_NORMAL = 0;
107 private static final int CONTEXT_DISPLAY_SPLIT = 1;
108
Adam Powell0c24a552010-11-03 16:44:11 -0700109 private static final int INVALID_POSITION = -1;
110
Adam Powell89e06452010-06-23 20:24:52 -0700111 private int mContextDisplayMode;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700112 private boolean mHasEmbeddedTabs;
Adam Powell0e94b512010-06-29 17:58:20 -0700113
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700114 private int mCurWindowVisibility = View.VISIBLE;
115
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800116 private boolean mContentAnimations = true;
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700117 private boolean mHiddenByApp;
118 private boolean mHiddenBySystem;
119 private boolean mShowingForMode;
120
121 private boolean mNowShowing = true;
122
Adam Powell07e1f982011-03-24 11:11:15 -0700123 private Animator mCurrentShowAnim;
Adam Powell50efbed2011-02-08 16:20:15 -0800124 private boolean mShowHideAnimationEnabled;
Adam Powellb36e4f92014-05-01 10:23:33 -0700125 boolean mHideOnContentScroll;
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800126
Adam Powell07e1f982011-03-24 11:11:15 -0700127 final AnimatorListener mHideListener = new AnimatorListenerAdapter() {
Adam Powelle6ec7322010-12-07 15:29:26 -0800128 @Override
129 public void onAnimationEnd(Animator animation) {
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800130 if (mContentAnimations && mContentView != null) {
Adam Powelle6ec7322010-12-07 15:29:26 -0800131 mContentView.setTranslationY(0);
Adam Powell9b0dc282013-07-31 13:58:43 -0700132 mContainerView.setTranslationY(0);
Adam Powelle6ec7322010-12-07 15:29:26 -0800133 }
Adam Powell993a63a2011-08-18 16:35:53 -0700134 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
135 mSplitView.setVisibility(View.GONE);
136 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700137 mContainerView.setVisibility(View.GONE);
Adam Powell01feaee2011-02-10 15:05:05 -0800138 mContainerView.setTransitioning(false);
Adam Powell07e1f982011-03-24 11:11:15 -0700139 mCurrentShowAnim = null;
Adam Powell060e3ca2011-07-19 20:39:16 -0700140 completeDeferredDestroyActionMode();
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700141 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700142 mOverlayLayout.requestApplyInsets();
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700143 }
Adam Powelle6ec7322010-12-07 15:29:26 -0800144 }
145 };
146
Adam Powell07e1f982011-03-24 11:11:15 -0700147 final AnimatorListener mShowListener = new AnimatorListenerAdapter() {
Adam Powelle6ec7322010-12-07 15:29:26 -0800148 @Override
149 public void onAnimationEnd(Animator animation) {
Adam Powell07e1f982011-03-24 11:11:15 -0700150 mCurrentShowAnim = null;
Adam Powell9b0dc282013-07-31 13:58:43 -0700151 mContainerView.requestLayout();
152 }
153 };
154
155 final ValueAnimator.AnimatorUpdateListener mUpdateListener =
156 new ValueAnimator.AnimatorUpdateListener() {
157 @Override
158 public void onAnimationUpdate(ValueAnimator animation) {
159 final ViewParent parent = mContainerView.getParent();
160 ((View) parent).invalidate();
Adam Powelle6ec7322010-12-07 15:29:26 -0800161 }
Adam Powelle6ec7322010-12-07 15:29:26 -0800162 };
163
Adam Powelle43340c2014-03-17 19:10:43 -0700164 public WindowDecorActionBar(Activity activity) {
Adam Powell661c9082010-07-02 10:09:44 -0700165 mActivity = activity;
Adam Powelle6ec7322010-12-07 15:29:26 -0800166 Window window = activity.getWindow();
167 View decor = window.getDecorView();
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800168 boolean overlayMode = mActivity.getWindow().hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
Adam Powell9b0dc282013-07-31 13:58:43 -0700169 init(decor);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800170 if (!overlayMode) {
Adam Powelle6ec7322010-12-07 15:29:26 -0800171 mContentView = decor.findViewById(android.R.id.content);
172 }
Adam Powelldec9dfd2010-08-09 15:27:54 -0700173 }
174
Adam Powelle43340c2014-03-17 19:10:43 -0700175 public WindowDecorActionBar(Dialog dialog) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700176 mDialog = dialog;
Adam Powell9b0dc282013-07-31 13:58:43 -0700177 init(dialog.getWindow().getDecorView());
Adam Powelldec9dfd2010-08-09 15:27:54 -0700178 }
179
Deepanshu Gupta14bf0ce2013-12-12 12:16:24 -0800180 /**
181 * Only for edit mode.
182 * @hide
183 */
184 public WindowDecorActionBar(View layout) {
185 assert layout.isInEditMode();
186 init(layout);
187 }
188
Adam Powell9b0dc282013-07-31 13:58:43 -0700189 private void init(View decor) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700190 mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(
Adam Powell4369e7d2014-05-17 14:16:08 -0700191 com.android.internal.R.id.decor_content_parent);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700192 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700193 mOverlayLayout.setActionBarVisibilityCallback(this);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700194 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700195 mDecorToolbar = getDecorToolbar(decor.findViewById(com.android.internal.R.id.action_bar));
Adam Powell640a66e2011-04-29 10:18:53 -0700196 mContextView = (ActionBarContextView) decor.findViewById(
Adam Powell89e06452010-06-23 20:24:52 -0700197 com.android.internal.R.id.action_context_bar);
Adam Powell01feaee2011-02-10 15:05:05 -0800198 mContainerView = (ActionBarContainer) decor.findViewById(
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800199 com.android.internal.R.id.action_bar_container);
Adam Powell640a66e2011-04-29 10:18:53 -0700200 mSplitView = (ActionBarContainer) decor.findViewById(
201 com.android.internal.R.id.split_action_bar);
Steve Block08f194b2010-08-24 18:20:48 +0100202
Adam Powelle021e6e2014-05-23 17:27:24 -0700203 if (mDecorToolbar == null || mContextView == null || mContainerView == null) {
Adam Powell89e06452010-06-23 20:24:52 -0700204 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
205 "with a compatible window decor layout");
206 }
Adam Powell0e94b512010-06-29 17:58:20 -0700207
Adam Powelle021e6e2014-05-23 17:27:24 -0700208 mContext = mDecorToolbar.getContext();
209 mContextDisplayMode = mDecorToolbar.isSplit() ?
Adam Powell9b4bee02011-04-27 19:24:47 -0700210 CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
Adam Powelldae78242011-04-25 15:23:41 -0700211
Adam Powelld40423a2012-05-02 14:06:03 -0700212 // This was initially read from the action bar style
Adam Powelle021e6e2014-05-23 17:27:24 -0700213 final int current = mDecorToolbar.getDisplayOptions();
Adam Powelld40423a2012-05-02 14:06:03 -0700214 final boolean homeAsUp = (current & DISPLAY_HOME_AS_UP) != 0;
215 if (homeAsUp) {
216 mDisplayHomeAsUpSet = true;
217 }
218
Adam Powellb8139af2012-04-19 13:52:46 -0700219 ActionBarPolicy abp = ActionBarPolicy.get(mContext);
Adam Powelld40423a2012-05-02 14:06:03 -0700220 setHomeButtonEnabled(abp.enableHomeButtonByDefault() || homeAsUp);
Adam Powellb8139af2012-04-19 13:52:46 -0700221 setHasEmbeddedTabs(abp.hasEmbeddedTabs());
Adam Powellb36e4f92014-05-01 10:23:33 -0700222
223 final TypedArray a = mContext.obtainStyledAttributes(null,
224 com.android.internal.R.styleable.ActionBar,
225 com.android.internal.R.attr.actionBarStyle, 0);
226 if (a.getBoolean(R.styleable.ActionBar_hideOnContentScroll, false)) {
227 setHideOnContentScrollEnabled(true);
228 }
229 a.recycle();
Adam Powellf8ac6b72011-05-23 18:14:09 -0700230 }
231
Adam Powelle021e6e2014-05-23 17:27:24 -0700232 private DecorToolbar getDecorToolbar(View view) {
233 if (view instanceof DecorToolbar) {
234 return (DecorToolbar) view;
235 } else if (view instanceof Toolbar) {
236 return ((Toolbar) view).getWrapper();
237 } else {
238 throw new IllegalStateException("Can't make a decor toolbar out of " +
239 view.getClass().getSimpleName());
240 }
241 }
242
Adam Powellf8ac6b72011-05-23 18:14:09 -0700243 public void onConfigurationChanged(Configuration newConfig) {
Adam Powellb8139af2012-04-19 13:52:46 -0700244 setHasEmbeddedTabs(ActionBarPolicy.get(mContext).hasEmbeddedTabs());
Adam Powellf5645cb2011-08-10 22:49:02 -0700245 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700246
Adam Powellf5645cb2011-08-10 22:49:02 -0700247 private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) {
248 mHasEmbeddedTabs = hasEmbeddedTabs;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700249 // Switch tab layout configuration if needed
250 if (!mHasEmbeddedTabs) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700251 mDecorToolbar.setEmbeddedTabView(null);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700252 mContainerView.setTabContainer(mTabScrollView);
253 } else {
254 mContainerView.setTabContainer(null);
Adam Powelle021e6e2014-05-23 17:27:24 -0700255 mDecorToolbar.setEmbeddedTabView(mTabScrollView);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700256 }
Adam Powellf5645cb2011-08-10 22:49:02 -0700257 final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS;
258 if (mTabScrollView != null) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700259 if (isInTabMode) {
260 mTabScrollView.setVisibility(View.VISIBLE);
261 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700262 mOverlayLayout.requestApplyInsets();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700263 }
264 } else {
265 mTabScrollView.setVisibility(View.GONE);
266 }
Adam Powellf5645cb2011-08-10 22:49:02 -0700267 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700268 mDecorToolbar.setCollapsible(!mHasEmbeddedTabs && isInTabMode);
Adam Powellb36e4f92014-05-01 10:23:33 -0700269 mOverlayLayout.setHasNonEmbeddedTabs(!mHasEmbeddedTabs && isInTabMode);
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700270 }
271
Adam Powellf8ac6b72011-05-23 18:14:09 -0700272 private void ensureTabsExist() {
273 if (mTabScrollView != null) {
274 return;
275 }
276
Adam Powellf5645cb2011-08-10 22:49:02 -0700277 ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700278
279 if (mHasEmbeddedTabs) {
280 tabScroller.setVisibility(View.VISIBLE);
Adam Powelle021e6e2014-05-23 17:27:24 -0700281 mDecorToolbar.setEmbeddedTabView(tabScroller);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700282 } else {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700283 if (getNavigationMode() == NAVIGATION_MODE_TABS) {
284 tabScroller.setVisibility(View.VISIBLE);
285 if (mOverlayLayout != null) {
Adam Powell76d8f962014-05-14 20:13:47 -0700286 mOverlayLayout.requestApplyInsets();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700287 }
288 } else {
289 tabScroller.setVisibility(View.GONE);
290 }
Adam Powelldae78242011-04-25 15:23:41 -0700291 mContainerView.setTabContainer(tabScroller);
Adam Powelldae78242011-04-25 15:23:41 -0700292 }
Adam Powellf8ac6b72011-05-23 18:14:09 -0700293 mTabScrollView = tabScroller;
Adam Powell89e06452010-06-23 20:24:52 -0700294 }
295
Adam Powell060e3ca2011-07-19 20:39:16 -0700296 void completeDeferredDestroyActionMode() {
297 if (mDeferredModeDestroyCallback != null) {
298 mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode);
299 mDeferredDestroyActionMode = null;
300 mDeferredModeDestroyCallback = null;
301 }
302 }
303
Adam Powellb36e4f92014-05-01 10:23:33 -0700304 public void onWindowVisibilityChanged(int visibility) {
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700305 mCurWindowVisibility = visibility;
306 }
307
Adam Powell50efbed2011-02-08 16:20:15 -0800308 /**
309 * Enables or disables animation between show/hide states.
310 * If animation is disabled using this method, animations in progress
311 * will be finished.
312 *
313 * @param enabled true to animate, false to not animate.
314 */
315 public void setShowHideAnimationEnabled(boolean enabled) {
316 mShowHideAnimationEnabled = enabled;
Adam Powell07e1f982011-03-24 11:11:15 -0700317 if (!enabled && mCurrentShowAnim != null) {
318 mCurrentShowAnim.end();
Adam Powell50efbed2011-02-08 16:20:15 -0800319 }
320 }
321
Adam Powell8515ee82010-11-30 14:09:55 -0800322 public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
323 mMenuVisibilityListeners.add(listener);
324 }
325
326 public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
327 mMenuVisibilityListeners.remove(listener);
328 }
329
330 public void dispatchMenuVisibilityChanged(boolean isVisible) {
331 if (isVisible == mLastMenuVisibility) {
332 return;
333 }
334 mLastMenuVisibility = isVisible;
335
336 final int count = mMenuVisibilityListeners.size();
337 for (int i = 0; i < count; i++) {
338 mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible);
339 }
340 }
341
Adam Powella66c7b02010-07-28 15:28:25 -0700342 @Override
Adam Powell3f476b32011-01-03 19:25:36 -0800343 public void setCustomView(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700344 setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId,
Dan Sandler6fdeeb32014-05-29 11:02:41 -0400345 mDecorToolbar.getViewGroup(), false));
Adam Powell3f476b32011-01-03 19:25:36 -0800346 }
347
348 @Override
349 public void setDisplayUseLogoEnabled(boolean useLogo) {
350 setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO);
351 }
352
353 @Override
354 public void setDisplayShowHomeEnabled(boolean showHome) {
355 setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME);
356 }
357
358 @Override
359 public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
360 setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP);
361 }
362
363 @Override
364 public void setDisplayShowTitleEnabled(boolean showTitle) {
365 setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE);
366 }
367
368 @Override
369 public void setDisplayShowCustomEnabled(boolean showCustom) {
370 setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM);
371 }
372
373 @Override
Adam Powellc29f4e52011-07-13 20:40:52 -0700374 public void setHomeButtonEnabled(boolean enable) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700375 mDecorToolbar.setHomeButtonEnabled(enable);
Adam Powelldae78242011-04-25 15:23:41 -0700376 }
377
378 @Override
Adam Powella66c7b02010-07-28 15:28:25 -0700379 public void setTitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700380 setTitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700381 }
382
383 @Override
384 public void setSubtitle(int resId) {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700385 setSubtitle(mContext.getString(resId));
Adam Powella66c7b02010-07-28 15:28:25 -0700386 }
387
Adam Powell17809772010-07-21 13:25:11 -0700388 public void setSelectedNavigationItem(int position) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700389 switch (mDecorToolbar.getNavigationMode()) {
Adam Powell17809772010-07-21 13:25:11 -0700390 case NAVIGATION_MODE_TABS:
391 selectTab(mTabs.get(position));
392 break;
Adam Powell9ab97872010-10-26 21:47:29 -0700393 case NAVIGATION_MODE_LIST:
Adam Powelle021e6e2014-05-23 17:27:24 -0700394 mDecorToolbar.setDropdownSelectedPosition(position);
Adam Powell17809772010-07-21 13:25:11 -0700395 break;
396 default:
397 throw new IllegalStateException(
Adam Powell9ab97872010-10-26 21:47:29 -0700398 "setSelectedNavigationIndex not valid for current navigation mode");
Adam Powell17809772010-07-21 13:25:11 -0700399 }
400 }
401
Adam Powell9ab97872010-10-26 21:47:29 -0700402 public void removeAllTabs() {
403 cleanupTabs();
Adam Powell17809772010-07-21 13:25:11 -0700404 }
405
Adam Powell661c9082010-07-02 10:09:44 -0700406 private void cleanupTabs() {
407 if (mSelectedTab != null) {
408 selectTab(null);
409 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700410 mTabs.clear();
Adam Powelld21aa122011-05-27 13:09:52 -0700411 if (mTabScrollView != null) {
412 mTabScrollView.removeAllTabs();
413 }
Adam Powell0c24a552010-11-03 16:44:11 -0700414 mSavedTabPosition = INVALID_POSITION;
Adam Powell661c9082010-07-02 10:09:44 -0700415 }
416
Adam Powell0e94b512010-06-29 17:58:20 -0700417 public void setTitle(CharSequence title) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700418 mDecorToolbar.setTitle(title);
Adam Powell0e94b512010-06-29 17:58:20 -0700419 }
420
421 public void setSubtitle(CharSequence subtitle) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700422 mDecorToolbar.setSubtitle(subtitle);
Adam Powell0e94b512010-06-29 17:58:20 -0700423 }
424
Adam Powell89e06452010-06-23 20:24:52 -0700425 public void setDisplayOptions(int options) {
Adam Powelldd8fab22012-03-22 17:47:27 -0700426 if ((options & DISPLAY_HOME_AS_UP) != 0) {
427 mDisplayHomeAsUpSet = true;
428 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700429 mDecorToolbar.setDisplayOptions(options);
Adam Powell89e06452010-06-23 20:24:52 -0700430 }
Adam Powell0e94b512010-06-29 17:58:20 -0700431
Adam Powell89e06452010-06-23 20:24:52 -0700432 public void setDisplayOptions(int options, int mask) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700433 final int current = mDecorToolbar.getDisplayOptions();
Adam Powelldd8fab22012-03-22 17:47:27 -0700434 if ((mask & DISPLAY_HOME_AS_UP) != 0) {
435 mDisplayHomeAsUpSet = true;
436 }
Adam Powelle021e6e2014-05-23 17:27:24 -0700437 mDecorToolbar.setDisplayOptions((options & mask) | (current & ~mask));
Adam Powell89e06452010-06-23 20:24:52 -0700438 }
439
440 public void setBackgroundDrawable(Drawable d) {
Adam Powellf88b9152011-09-07 14:54:32 -0700441 mContainerView.setPrimaryBackground(d);
442 }
443
444 public void setStackedBackgroundDrawable(Drawable d) {
445 mContainerView.setStackedBackground(d);
446 }
447
448 public void setSplitBackgroundDrawable(Drawable d) {
449 if (mSplitView != null) {
450 mSplitView.setSplitBackground(d);
451 }
Adam Powell89e06452010-06-23 20:24:52 -0700452 }
453
Adam Powellef704442010-11-16 14:48:22 -0800454 public View getCustomView() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700455 return mDecorToolbar.getCustomView();
Adam Powell89e06452010-06-23 20:24:52 -0700456 }
457
458 public CharSequence getTitle() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700459 return mDecorToolbar.getTitle();
Adam Powell89e06452010-06-23 20:24:52 -0700460 }
461
462 public CharSequence getSubtitle() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700463 return mDecorToolbar.getSubtitle();
Adam Powell89e06452010-06-23 20:24:52 -0700464 }
465
466 public int getNavigationMode() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700467 return mDecorToolbar.getNavigationMode();
Adam Powell89e06452010-06-23 20:24:52 -0700468 }
469
470 public int getDisplayOptions() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700471 return mDecorToolbar.getDisplayOptions();
Adam Powell89e06452010-06-23 20:24:52 -0700472 }
473
Adam Powell5d279772010-07-27 16:34:07 -0700474 public ActionMode startActionMode(ActionMode.Callback callback) {
475 if (mActionMode != null) {
476 mActionMode.finish();
Adam Powell6e346362010-07-23 10:18:23 -0700477 }
Adam Powell3461b322010-07-14 11:34:43 -0700478
Adam Powellb36e4f92014-05-01 10:23:33 -0700479 mOverlayLayout.setHideOnContentScrollEnabled(false);
Adam Powell640a66e2011-04-29 10:18:53 -0700480 mContextView.killMode();
Adam Powell5ee36c42011-06-02 12:59:43 -0700481 ActionModeImpl mode = new ActionModeImpl(callback);
482 if (mode.dispatchOnCreate()) {
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700483 mode.invalidate();
Adam Powell640a66e2011-04-29 10:18:53 -0700484 mContextView.initForMode(mode);
485 animateToMode(true);
Adam Powell1ab418a2011-06-09 20:49:49 -0700486 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
Adam Powell89e06452010-06-23 20:24:52 -0700487 // TODO animate this
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700488 if (mSplitView.getVisibility() != View.VISIBLE) {
489 mSplitView.setVisibility(View.VISIBLE);
490 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700491 mOverlayLayout.requestApplyInsets();
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700492 }
493 }
Adam Powell89e06452010-06-23 20:24:52 -0700494 }
Adam Powell86ed4362011-09-14 16:18:53 -0700495 mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Adam Powell5d279772010-07-27 16:34:07 -0700496 mActionMode = mode;
Adam Powellac695c62010-07-20 18:19:27 -0700497 return mode;
Adam Powell89e06452010-06-23 20:24:52 -0700498 }
Adam Powellac695c62010-07-20 18:19:27 -0700499 return null;
Adam Powell89e06452010-06-23 20:24:52 -0700500 }
501
Adam Powell661c9082010-07-02 10:09:44 -0700502 private void configureTab(Tab tab, int position) {
503 final TabImpl tabi = (TabImpl) tab;
Adam Powell2b6230e2010-09-07 17:55:25 -0700504 final ActionBar.TabListener callback = tabi.getCallback();
505
506 if (callback == null) {
507 throw new IllegalStateException("Action Bar Tab must have a Callback");
508 }
Adam Powell661c9082010-07-02 10:09:44 -0700509
510 tabi.setPosition(position);
511 mTabs.add(position, tabi);
512
Adam Powell81b89442010-11-02 17:58:56 -0700513 final int count = mTabs.size();
514 for (int i = position + 1; i < count; i++) {
515 mTabs.get(i).setPosition(i);
Adam Powell661c9082010-07-02 10:09:44 -0700516 }
Adam Powell661c9082010-07-02 10:09:44 -0700517 }
518
519 @Override
520 public void addTab(Tab tab) {
Adam Powell81b89442010-11-02 17:58:56 -0700521 addTab(tab, mTabs.isEmpty());
Adam Powell661c9082010-07-02 10:09:44 -0700522 }
523
524 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -0700525 public void addTab(Tab tab, int position) {
Adam Powell81b89442010-11-02 17:58:56 -0700526 addTab(tab, position, mTabs.isEmpty());
527 }
528
529 @Override
530 public void addTab(Tab tab, boolean setSelected) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700531 ensureTabsExist();
532 mTabScrollView.addTab(tab, setSelected);
Adam Powell81b89442010-11-02 17:58:56 -0700533 configureTab(tab, mTabs.size());
534 if (setSelected) {
535 selectTab(tab);
536 }
537 }
538
539 @Override
540 public void addTab(Tab tab, int position, boolean setSelected) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700541 ensureTabsExist();
542 mTabScrollView.addTab(tab, position, setSelected);
Adam Powell661c9082010-07-02 10:09:44 -0700543 configureTab(tab, position);
Adam Powell81b89442010-11-02 17:58:56 -0700544 if (setSelected) {
545 selectTab(tab);
546 }
Adam Powell661c9082010-07-02 10:09:44 -0700547 }
548
549 @Override
550 public Tab newTab() {
551 return new TabImpl();
552 }
553
554 @Override
555 public void removeTab(Tab tab) {
556 removeTabAt(tab.getPosition());
557 }
558
559 @Override
560 public void removeTabAt(int position) {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700561 if (mTabScrollView == null) {
562 // No tabs around to remove
563 return;
564 }
565
Adam Powell0c24a552010-11-03 16:44:11 -0700566 int selectedTabPosition = mSelectedTab != null
567 ? mSelectedTab.getPosition() : mSavedTabPosition;
Adam Powellf8ac6b72011-05-23 18:14:09 -0700568 mTabScrollView.removeTabAt(position);
Adam Powell0d8ec1d2011-05-03 14:49:13 -0700569 TabImpl removedTab = mTabs.remove(position);
570 if (removedTab != null) {
571 removedTab.setPosition(-1);
572 }
Adam Powell661c9082010-07-02 10:09:44 -0700573
574 final int newTabCount = mTabs.size();
575 for (int i = position; i < newTabCount; i++) {
576 mTabs.get(i).setPosition(i);
577 }
578
Adam Powell0c24a552010-11-03 16:44:11 -0700579 if (selectedTabPosition == position) {
580 selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
581 }
Adam Powell661c9082010-07-02 10:09:44 -0700582 }
583
584 @Override
Adam Powell661c9082010-07-02 10:09:44 -0700585 public void selectTab(Tab tab) {
Adam Powell0c24a552010-11-03 16:44:11 -0700586 if (getNavigationMode() != NAVIGATION_MODE_TABS) {
587 mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
588 return;
589 }
590
Adam Powelle021e6e2014-05-23 17:27:24 -0700591 final FragmentTransaction trans = ((View) mDecorToolbar).isInEditMode() ? null :
Deepanshu Gupta14bf0ce2013-12-12 12:16:24 -0800592 mActivity.getFragmentManager().beginTransaction().disallowAddToBackStack();
Adam Powell7f9b9052010-10-19 16:56:07 -0700593
594 if (mSelectedTab == tab) {
595 if (mSelectedTab != null) {
596 mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
Adam Powellf8ac6b72011-05-23 18:14:09 -0700597 mTabScrollView.animateToTab(tab.getPosition());
Adam Powell7f9b9052010-10-19 16:56:07 -0700598 }
599 } else {
Adam Powellf8ac6b72011-05-23 18:14:09 -0700600 mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
Adam Powell7f9b9052010-10-19 16:56:07 -0700601 if (mSelectedTab != null) {
602 mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
603 }
604 mSelectedTab = (TabImpl) tab;
605 if (mSelectedTab != null) {
606 mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
607 }
Adam Powell2b6230e2010-09-07 17:55:25 -0700608 }
609
Deepanshu Gupta14bf0ce2013-12-12 12:16:24 -0800610 if (trans != null && !trans.isEmpty()) {
Adam Powell2b6230e2010-09-07 17:55:25 -0700611 trans.commit();
612 }
613 }
614
615 @Override
616 public Tab getSelectedTab() {
617 return mSelectedTab;
Adam Powell661c9082010-07-02 10:09:44 -0700618 }
619
Adam Powell6b336f82010-08-10 20:13:01 -0700620 @Override
621 public int getHeight() {
Adam Powell58c5dc12011-07-14 21:08:10 -0700622 return mContainerView.getHeight();
Adam Powell6b336f82010-08-10 20:13:01 -0700623 }
624
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800625 public void enableContentAnimations(boolean enabled) {
626 mContentAnimations = enabled;
627 }
628
Adam Powell6b336f82010-08-10 20:13:01 -0700629 @Override
630 public void show() {
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700631 if (mHiddenByApp) {
632 mHiddenByApp = false;
633 updateVisibility(false);
634 }
Adam Powell07e1f982011-03-24 11:11:15 -0700635 }
636
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700637 private void showForActionMode() {
638 if (!mShowingForMode) {
639 mShowingForMode = true;
640 if (mOverlayLayout != null) {
641 mOverlayLayout.setShowingForActionMode(true);
642 }
643 updateVisibility(false);
644 }
645 }
646
647 public void showForSystem() {
648 if (mHiddenBySystem) {
649 mHiddenBySystem = false;
650 updateVisibility(true);
651 }
652 }
653
654 @Override
655 public void hide() {
656 if (!mHiddenByApp) {
657 mHiddenByApp = true;
658 updateVisibility(false);
659 }
660 }
661
662 private void hideForActionMode() {
663 if (mShowingForMode) {
664 mShowingForMode = false;
665 if (mOverlayLayout != null) {
666 mOverlayLayout.setShowingForActionMode(false);
667 }
668 updateVisibility(false);
669 }
670 }
671
672 public void hideForSystem() {
673 if (!mHiddenBySystem) {
674 mHiddenBySystem = true;
675 updateVisibility(true);
676 }
677 }
678
Adam Powellb36e4f92014-05-01 10:23:33 -0700679 @Override
680 public void setHideOnContentScrollEnabled(boolean hideOnContentScroll) {
681 if (hideOnContentScroll && !mOverlayLayout.isInOverlayMode()) {
682 throw new IllegalStateException("Action bar must be in overlay mode " +
683 "(Window.FEATURE_OVERLAY_ACTION_BAR) to enable hide on content scroll");
684 }
685 mHideOnContentScroll = hideOnContentScroll;
686 mOverlayLayout.setHideOnContentScrollEnabled(hideOnContentScroll);
687 }
688
689 @Override
690 public boolean isHideOnContentScrollEnabled() {
691 return mOverlayLayout.isHideOnContentScrollEnabled();
692 }
693
694 @Override
695 public int getHideOffset() {
696 return mOverlayLayout.getActionBarHideOffset();
697 }
698
699 @Override
700 public void setHideOffset(int offset) {
701 if (offset != 0 && !mOverlayLayout.isInOverlayMode()) {
702 throw new IllegalStateException("Action bar must be in overlay mode " +
703 "(Window.FEATURE_OVERLAY_ACTION_BAR) to set a non-zero hide offset");
704 }
705 mOverlayLayout.setActionBarHideOffset(offset);
706 }
707
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700708 private static boolean checkShowingFlags(boolean hiddenByApp, boolean hiddenBySystem,
709 boolean showingForMode) {
710 if (showingForMode) {
711 return true;
712 } else if (hiddenByApp || hiddenBySystem) {
713 return false;
714 } else {
715 return true;
716 }
717 }
718
719 private void updateVisibility(boolean fromSystem) {
720 // Based on the current state, should we be hidden or shown?
721 final boolean shown = checkShowingFlags(mHiddenByApp, mHiddenBySystem,
722 mShowingForMode);
723
724 if (shown) {
725 if (!mNowShowing) {
726 mNowShowing = true;
727 doShow(fromSystem);
728 }
729 } else {
730 if (mNowShowing) {
731 mNowShowing = false;
732 doHide(fromSystem);
733 }
734 }
735 }
736
737 public void doShow(boolean fromSystem) {
Adam Powell07e1f982011-03-24 11:11:15 -0700738 if (mCurrentShowAnim != null) {
739 mCurrentShowAnim.end();
Adam Powell45f1e082010-12-10 14:20:13 -0800740 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700741 mContainerView.setVisibility(View.VISIBLE);
Adam Powell50efbed2011-02-08 16:20:15 -0800742
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700743 if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700744 || fromSystem)) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700745 mContainerView.setTranslationY(0); // because we're about to ask its window loc
746 float startingY = -mContainerView.getHeight();
Chet Haasee8118e12012-05-30 14:19:02 -0700747 if (fromSystem) {
748 int topLeft[] = {0, 0};
Adam Powell9b0dc282013-07-31 13:58:43 -0700749 mContainerView.getLocationInWindow(topLeft);
Chet Haasee8118e12012-05-30 14:19:02 -0700750 startingY -= topLeft[1];
751 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700752 mContainerView.setTranslationY(startingY);
Adam Powell50efbed2011-02-08 16:20:15 -0800753 AnimatorSet anim = new AnimatorSet();
Adam Powell9b0dc282013-07-31 13:58:43 -0700754 ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, 0);
755 a.addUpdateListener(mUpdateListener);
756 AnimatorSet.Builder b = anim.play(a);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800757 if (mContentAnimations && mContentView != null) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700758 b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
Chet Haasee8118e12012-05-30 14:19:02 -0700759 startingY, 0));
Adam Powell50efbed2011-02-08 16:20:15 -0800760 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700761 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700762 mSplitView.setTranslationY(mSplitView.getHeight());
Adam Powell993a63a2011-08-18 16:35:53 -0700763 mSplitView.setVisibility(View.VISIBLE);
Adam Powell9b0dc282013-07-31 13:58:43 -0700764 b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y, 0));
Adam Powell640a66e2011-04-29 10:18:53 -0700765 }
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700766 anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
Chet Haasee8118e12012-05-30 14:19:02 -0700767 com.android.internal.R.interpolator.decelerate_cubic));
768 anim.setDuration(250);
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700769 // If this is being shown from the system, add a small delay.
770 // This is because we will also be animating in the status bar,
771 // and these two elements can't be done in lock-step. So we give
772 // a little time for the status bar to start its animation before
773 // the action bar animates. (This corresponds to the corresponding
774 // case when hiding, where the status bar has a small delay before
775 // starting.)
Adam Powell50efbed2011-02-08 16:20:15 -0800776 anim.addListener(mShowListener);
Adam Powell07e1f982011-03-24 11:11:15 -0700777 mCurrentShowAnim = anim;
Adam Powell50efbed2011-02-08 16:20:15 -0800778 anim.start();
779 } else {
Adam Powell9b0dc282013-07-31 13:58:43 -0700780 mContainerView.setAlpha(1);
781 mContainerView.setTranslationY(0);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800782 if (mContentAnimations && mContentView != null) {
Dianne Hackborn80d55062012-05-22 18:03:20 -0700783 mContentView.setTranslationY(0);
784 }
785 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
786 mSplitView.setAlpha(1);
787 mSplitView.setTranslationY(0);
788 mSplitView.setVisibility(View.VISIBLE);
789 }
Adam Powell50efbed2011-02-08 16:20:15 -0800790 mShowListener.onAnimationEnd(null);
Adam Powelle6ec7322010-12-07 15:29:26 -0800791 }
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700792 if (mOverlayLayout != null) {
Adam Powellb36e4f92014-05-01 10:23:33 -0700793 mOverlayLayout.requestApplyInsets();
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700794 }
Adam Powell6b336f82010-08-10 20:13:01 -0700795 }
796
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700797 public void doHide(boolean fromSystem) {
Adam Powell07e1f982011-03-24 11:11:15 -0700798 if (mCurrentShowAnim != null) {
799 mCurrentShowAnim.end();
Adam Powelle6ec7322010-12-07 15:29:26 -0800800 }
Adam Powell50efbed2011-02-08 16:20:15 -0800801
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -0700802 if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700803 || fromSystem)) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700804 mContainerView.setAlpha(1);
Adam Powell01feaee2011-02-10 15:05:05 -0800805 mContainerView.setTransitioning(true);
Adam Powell50efbed2011-02-08 16:20:15 -0800806 AnimatorSet anim = new AnimatorSet();
Adam Powell9b0dc282013-07-31 13:58:43 -0700807 float endingY = -mContainerView.getHeight();
Chet Haasee8118e12012-05-30 14:19:02 -0700808 if (fromSystem) {
809 int topLeft[] = {0, 0};
Adam Powell9b0dc282013-07-31 13:58:43 -0700810 mContainerView.getLocationInWindow(topLeft);
Chet Haasee8118e12012-05-30 14:19:02 -0700811 endingY -= topLeft[1];
812 }
Adam Powell9b0dc282013-07-31 13:58:43 -0700813 ObjectAnimator a = ObjectAnimator.ofFloat(mContainerView, View.TRANSLATION_Y, endingY);
814 a.addUpdateListener(mUpdateListener);
815 AnimatorSet.Builder b = anim.play(a);
Dianne Hackborndf7221c2013-02-26 14:53:55 -0800816 if (mContentAnimations && mContentView != null) {
Adam Powell9b0dc282013-07-31 13:58:43 -0700817 b.with(ObjectAnimator.ofFloat(mContentView, View.TRANSLATION_Y,
Chet Haasee8118e12012-05-30 14:19:02 -0700818 0, endingY));
Adam Powell50efbed2011-02-08 16:20:15 -0800819 }
Adam Powell1ab418a2011-06-09 20:49:49 -0700820 if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
Adam Powell640a66e2011-04-29 10:18:53 -0700821 mSplitView.setAlpha(1);
Adam Powell9b0dc282013-07-31 13:58:43 -0700822 b.with(ObjectAnimator.ofFloat(mSplitView, View.TRANSLATION_Y,
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700823 mSplitView.getHeight()));
Adam Powell640a66e2011-04-29 10:18:53 -0700824 }
Dianne Hackborn8eedb8b2012-04-16 19:31:58 -0700825 anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
Chet Haasee8118e12012-05-30 14:19:02 -0700826 com.android.internal.R.interpolator.accelerate_cubic));
827 anim.setDuration(250);
Adam Powell50efbed2011-02-08 16:20:15 -0800828 anim.addListener(mHideListener);
Adam Powell07e1f982011-03-24 11:11:15 -0700829 mCurrentShowAnim = anim;
Adam Powell50efbed2011-02-08 16:20:15 -0800830 anim.start();
831 } else {
832 mHideListener.onAnimationEnd(null);
Adam Powelle6ec7322010-12-07 15:29:26 -0800833 }
Adam Powell6b336f82010-08-10 20:13:01 -0700834 }
835
836 public boolean isShowing() {
Adam Powellb36e4f92014-05-01 10:23:33 -0700837 return mNowShowing && getHideOffset() < getHeight();
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800838 }
839
Adam Powell640a66e2011-04-29 10:18:53 -0700840 void animateToMode(boolean toActionMode) {
Adam Powell060e3ca2011-07-19 20:39:16 -0700841 if (toActionMode) {
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700842 showForActionMode();
843 } else {
844 hideForActionMode();
Adam Powell07e1f982011-03-24 11:11:15 -0700845 }
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800846
Adam Powelle021e6e2014-05-23 17:27:24 -0700847 mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
Adam Powell640a66e2011-04-29 10:18:53 -0700848 mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
Adam Powelle021e6e2014-05-23 17:27:24 -0700849 if (mTabScrollView != null && !mDecorToolbar.hasEmbeddedTabs() &&
850 isCollapsed((View) mDecorToolbar)) {
Adam Powellf6ce6a92011-06-29 10:25:01 -0700851 mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
852 }
Adam Powell6b336f82010-08-10 20:13:01 -0700853 }
854
Adam Powelle021e6e2014-05-23 17:27:24 -0700855 private boolean isCollapsed(View view) {
856 return view == null || view.getVisibility() == View.GONE || view.getMeasuredHeight() == 0;
857 }
858
Adam Powell88ab6972011-07-28 11:25:01 -0700859 public Context getThemedContext() {
860 if (mThemedContext == null) {
861 TypedValue outValue = new TypedValue();
862 Resources.Theme currentTheme = mContext.getTheme();
863 currentTheme.resolveAttribute(com.android.internal.R.attr.actionBarWidgetTheme,
864 outValue, true);
865 final int targetThemeRes = outValue.resourceId;
866
867 if (targetThemeRes != 0 && mContext.getThemeResId() != targetThemeRes) {
868 mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes);
869 } else {
870 mThemedContext = mContext;
871 }
872 }
873 return mThemedContext;
874 }
875
Adam Powell27cba382013-01-22 18:55:20 -0800876 @Override
877 public boolean isTitleTruncated() {
Adam Powelle021e6e2014-05-23 17:27:24 -0700878 return mDecorToolbar != null && mDecorToolbar.isTitleTruncated();
Adam Powell27cba382013-01-22 18:55:20 -0800879 }
880
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700881 @Override
882 public void setHomeAsUpIndicator(Drawable indicator) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700883 mDecorToolbar.setNavigationIcon(indicator);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700884 }
885
886 @Override
887 public void setHomeAsUpIndicator(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700888 mDecorToolbar.setNavigationIcon(resId);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700889 }
890
891 @Override
892 public void setHomeActionContentDescription(CharSequence description) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700893 mDecorToolbar.setNavigationContentDescription(description);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700894 }
895
896 @Override
897 public void setHomeActionContentDescription(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -0700898 mDecorToolbar.setNavigationContentDescription(resId);
Adam Powelle0e2f4f2013-04-05 16:27:35 -0700899 }
900
Adam Powellb36e4f92014-05-01 10:23:33 -0700901 @Override
902 public void onContentScrollStarted() {
903 if (mCurrentShowAnim != null) {
904 mCurrentShowAnim.cancel();
905 mCurrentShowAnim = null;
906 }
907 }
908
909 @Override
910 public void onContentScrollStopped() {
911 }
912
Adam Powell89e06452010-06-23 20:24:52 -0700913 /**
914 * @hide
915 */
Adam Powell5d279772010-07-27 16:34:07 -0700916 public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
Adam Powell6e346362010-07-23 10:18:23 -0700917 private ActionMode.Callback mCallback;
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700918 private MenuBuilder mMenu;
Adam Powell29ed7572010-07-14 16:24:56 -0700919 private WeakReference<View> mCustomView;
Adam Powell89e06452010-06-23 20:24:52 -0700920
Adam Powell5d279772010-07-27 16:34:07 -0700921 public ActionModeImpl(ActionMode.Callback callback) {
Adam Powell89e06452010-06-23 20:24:52 -0700922 mCallback = callback;
Adam Powellf2423682011-08-11 14:29:45 -0700923 mMenu = new MenuBuilder(getThemedContext())
Adam Powell4d9861e2010-08-17 11:14:40 -0700924 .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
Adam Powell2c9c9fe2010-07-16 10:17:57 -0700925 mMenu.setCallback(this);
Adam Powell89e06452010-06-23 20:24:52 -0700926 }
Adam Powell9168f0b2010-08-02 15:46:24 -0700927
928 @Override
929 public MenuInflater getMenuInflater() {
Adam Powellf2423682011-08-11 14:29:45 -0700930 return new MenuInflater(getThemedContext());
Adam Powell9168f0b2010-08-02 15:46:24 -0700931 }
932
Adam Powell89e06452010-06-23 20:24:52 -0700933 @Override
934 public Menu getMenu() {
935 return mMenu;
936 }
937
938 @Override
939 public void finish() {
Adam Powell5d279772010-07-27 16:34:07 -0700940 if (mActionMode != this) {
941 // Not the active action mode - no-op
Adam Powell93b6bc32010-07-22 11:36:35 -0700942 return;
943 }
944
Dianne Hackborn139e5aa2012-05-05 20:36:38 -0700945 // If this change in state is going to cause the action bar
946 // to be hidden, defer the onDestroy callback until the animation
947 // is finished and associated relayout is about to happen. This lets
948 // apps better anticipate visibility and layout behavior.
949 if (!checkShowingFlags(mHiddenByApp, mHiddenBySystem, false)) {
950 // With the current state but the action bar hidden, our
951 // overall showing state is going to be false.
Adam Powell060e3ca2011-07-19 20:39:16 -0700952 mDeferredDestroyActionMode = this;
953 mDeferredModeDestroyCallback = mCallback;
954 } else {
955 mCallback.onDestroyActionMode(this);
956 }
Adam Powelld8b3f2e2010-12-02 13:37:03 -0800957 mCallback = null;
Adam Powell640a66e2011-04-29 10:18:53 -0700958 animateToMode(false);
Adam Powell0e94b512010-06-29 17:58:20 -0700959
960 // Clear out the context mode views after the animation finishes
Adam Powell640a66e2011-04-29 10:18:53 -0700961 mContextView.closeMode();
Adam Powelle021e6e2014-05-23 17:27:24 -0700962 ((View) mDecorToolbar).sendAccessibilityEvent(
963 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
Adam Powellb36e4f92014-05-01 10:23:33 -0700964 mOverlayLayout.setHideOnContentScrollEnabled(mHideOnContentScroll);
Adam Powellf6ce6a92011-06-29 10:25:01 -0700965
Adam Powell5d279772010-07-27 16:34:07 -0700966 mActionMode = null;
Adam Powell89e06452010-06-23 20:24:52 -0700967 }
968
969 @Override
970 public void invalidate() {
Adam Powell5ee36c42011-06-02 12:59:43 -0700971 mMenu.stopDispatchingItemsChanged();
972 try {
973 mCallback.onPrepareActionMode(this, mMenu);
974 } finally {
975 mMenu.startDispatchingItemsChanged();
976 }
977 }
978
979 public boolean dispatchOnCreate() {
980 mMenu.stopDispatchingItemsChanged();
981 try {
982 return mCallback.onCreateActionMode(this, mMenu);
983 } finally {
984 mMenu.startDispatchingItemsChanged();
Adam Powell89e06452010-06-23 20:24:52 -0700985 }
986 }
987
988 @Override
989 public void setCustomView(View view) {
Adam Powell640a66e2011-04-29 10:18:53 -0700990 mContextView.setCustomView(view);
Adam Powell29ed7572010-07-14 16:24:56 -0700991 mCustomView = new WeakReference<View>(view);
Adam Powell89e06452010-06-23 20:24:52 -0700992 }
993
994 @Override
995 public void setSubtitle(CharSequence subtitle) {
Adam Powell640a66e2011-04-29 10:18:53 -0700996 mContextView.setSubtitle(subtitle);
Adam Powell89e06452010-06-23 20:24:52 -0700997 }
998
999 @Override
1000 public void setTitle(CharSequence title) {
Adam Powell640a66e2011-04-29 10:18:53 -07001001 mContextView.setTitle(title);
Adam Powell89e06452010-06-23 20:24:52 -07001002 }
Adam Powell29ed7572010-07-14 16:24:56 -07001003
1004 @Override
Adam Powellc9ae2a22010-07-28 14:44:21 -07001005 public void setTitle(int resId) {
Adam Powell48e8ac32011-01-14 12:10:24 -08001006 setTitle(mContext.getResources().getString(resId));
Adam Powellc9ae2a22010-07-28 14:44:21 -07001007 }
1008
1009 @Override
1010 public void setSubtitle(int resId) {
Adam Powell48e8ac32011-01-14 12:10:24 -08001011 setSubtitle(mContext.getResources().getString(resId));
Adam Powellc9ae2a22010-07-28 14:44:21 -07001012 }
1013
1014 @Override
Adam Powell29ed7572010-07-14 16:24:56 -07001015 public CharSequence getTitle() {
Adam Powell640a66e2011-04-29 10:18:53 -07001016 return mContextView.getTitle();
Adam Powell29ed7572010-07-14 16:24:56 -07001017 }
1018
1019 @Override
1020 public CharSequence getSubtitle() {
Adam Powell640a66e2011-04-29 10:18:53 -07001021 return mContextView.getSubtitle();
Adam Powell29ed7572010-07-14 16:24:56 -07001022 }
Adam Powell89e06452010-06-23 20:24:52 -07001023
Adam Powell29ed7572010-07-14 16:24:56 -07001024 @Override
Adam Powellb98a81f2012-02-24 11:09:07 -08001025 public void setTitleOptionalHint(boolean titleOptional) {
Adam Powell785c4472012-05-02 21:25:39 -07001026 super.setTitleOptionalHint(titleOptional);
Adam Powellb98a81f2012-02-24 11:09:07 -08001027 mContextView.setTitleOptional(titleOptional);
1028 }
1029
1030 @Override
1031 public boolean isTitleOptional() {
1032 return mContextView.isTitleOptional();
1033 }
1034
1035 @Override
Adam Powell29ed7572010-07-14 16:24:56 -07001036 public View getCustomView() {
1037 return mCustomView != null ? mCustomView.get() : null;
1038 }
1039
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001040 public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -08001041 if (mCallback != null) {
1042 return mCallback.onActionItemClicked(this, item);
1043 } else {
1044 return false;
1045 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001046 }
1047
1048 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
1049 }
1050
1051 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -08001052 if (mCallback == null) {
1053 return false;
1054 }
1055
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001056 if (!subMenu.hasVisibleItems()) {
1057 return true;
Adam Powell89e06452010-06-23 20:24:52 -07001058 }
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001059
Adam Powellf2423682011-08-11 14:29:45 -07001060 new MenuPopupHelper(getThemedContext(), subMenu).show();
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001061 return true;
1062 }
1063
1064 public void onCloseSubMenu(SubMenuBuilder menu) {
1065 }
1066
1067 public void onMenuModeChange(MenuBuilder menu) {
Adam Powelld8b3f2e2010-12-02 13:37:03 -08001068 if (mCallback == null) {
1069 return;
1070 }
Adam Powellf6148c52010-08-11 21:10:16 -07001071 invalidate();
Adam Powell640a66e2011-04-29 10:18:53 -07001072 mContextView.showOverflowMenu();
Adam Powell2c9c9fe2010-07-16 10:17:57 -07001073 }
Adam Powell661c9082010-07-02 10:09:44 -07001074 }
1075
1076 /**
1077 * @hide
1078 */
1079 public class TabImpl extends ActionBar.Tab {
Adam Powell2b6230e2010-09-07 17:55:25 -07001080 private ActionBar.TabListener mCallback;
1081 private Object mTag;
Adam Powell661c9082010-07-02 10:09:44 -07001082 private Drawable mIcon;
1083 private CharSequence mText;
Adam Powell94e56ef2011-09-06 21:22:22 -07001084 private CharSequence mContentDesc;
Adam Powell0d8ec1d2011-05-03 14:49:13 -07001085 private int mPosition = -1;
Adam Powell2b6230e2010-09-07 17:55:25 -07001086 private View mCustomView;
Adam Powell661c9082010-07-02 10:09:44 -07001087
1088 @Override
Adam Powell2b6230e2010-09-07 17:55:25 -07001089 public Object getTag() {
1090 return mTag;
1091 }
1092
1093 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001094 public Tab setTag(Object tag) {
Adam Powell2b6230e2010-09-07 17:55:25 -07001095 mTag = tag;
Adam Powell9ab97872010-10-26 21:47:29 -07001096 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -07001097 }
1098
1099 public ActionBar.TabListener getCallback() {
1100 return mCallback;
1101 }
1102
1103 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001104 public Tab setTabListener(ActionBar.TabListener callback) {
Adam Powell2b6230e2010-09-07 17:55:25 -07001105 mCallback = callback;
Adam Powell9ab97872010-10-26 21:47:29 -07001106 return this;
Adam Powell2b6230e2010-09-07 17:55:25 -07001107 }
1108
1109 @Override
1110 public View getCustomView() {
1111 return mCustomView;
1112 }
1113
1114 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001115 public Tab setCustomView(View view) {
Adam Powell2b6230e2010-09-07 17:55:25 -07001116 mCustomView = view;
Adam Powellf8ac6b72011-05-23 18:14:09 -07001117 if (mPosition >= 0) {
1118 mTabScrollView.updateTab(mPosition);
1119 }
Adam Powell9ab97872010-10-26 21:47:29 -07001120 return this;
Adam Powell661c9082010-07-02 10:09:44 -07001121 }
1122
1123 @Override
Adam Powell32555f32010-11-17 13:49:22 -08001124 public Tab setCustomView(int layoutResId) {
Adam Powellf2423682011-08-11 14:29:45 -07001125 return setCustomView(LayoutInflater.from(getThemedContext())
1126 .inflate(layoutResId, null));
Adam Powell32555f32010-11-17 13:49:22 -08001127 }
1128
1129 @Override
Adam Powell661c9082010-07-02 10:09:44 -07001130 public Drawable getIcon() {
1131 return mIcon;
1132 }
1133
1134 @Override
1135 public int getPosition() {
1136 return mPosition;
1137 }
1138
1139 public void setPosition(int position) {
1140 mPosition = position;
1141 }
1142
1143 @Override
1144 public CharSequence getText() {
1145 return mText;
1146 }
1147
1148 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001149 public Tab setIcon(Drawable icon) {
Adam Powell661c9082010-07-02 10:09:44 -07001150 mIcon = icon;
Adam Powellf8ac6b72011-05-23 18:14:09 -07001151 if (mPosition >= 0) {
1152 mTabScrollView.updateTab(mPosition);
1153 }
Adam Powell9ab97872010-10-26 21:47:29 -07001154 return this;
Adam Powell661c9082010-07-02 10:09:44 -07001155 }
1156
1157 @Override
Adam Powell32555f32010-11-17 13:49:22 -08001158 public Tab setIcon(int resId) {
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001159 return setIcon(mContext.getDrawable(resId));
Adam Powell32555f32010-11-17 13:49:22 -08001160 }
1161
1162 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001163 public Tab setText(CharSequence text) {
Adam Powell661c9082010-07-02 10:09:44 -07001164 mText = text;
Adam Powellf8ac6b72011-05-23 18:14:09 -07001165 if (mPosition >= 0) {
1166 mTabScrollView.updateTab(mPosition);
1167 }
Adam Powell9ab97872010-10-26 21:47:29 -07001168 return this;
Adam Powell661c9082010-07-02 10:09:44 -07001169 }
1170
1171 @Override
Adam Powell32555f32010-11-17 13:49:22 -08001172 public Tab setText(int resId) {
1173 return setText(mContext.getResources().getText(resId));
1174 }
1175
1176 @Override
Adam Powell661c9082010-07-02 10:09:44 -07001177 public void select() {
1178 selectTab(this);
Adam Powell89e06452010-06-23 20:24:52 -07001179 }
Adam Powell94e56ef2011-09-06 21:22:22 -07001180
1181 @Override
1182 public Tab setContentDescription(int resId) {
1183 return setContentDescription(mContext.getResources().getText(resId));
1184 }
1185
1186 @Override
1187 public Tab setContentDescription(CharSequence contentDesc) {
1188 mContentDesc = contentDesc;
1189 if (mPosition >= 0) {
1190 mTabScrollView.updateTab(mPosition);
1191 }
1192 return this;
1193 }
1194
1195 @Override
1196 public CharSequence getContentDescription() {
1197 return mContentDesc;
1198 }
Adam Powell89e06452010-06-23 20:24:52 -07001199 }
Adam Powell9ab97872010-10-26 21:47:29 -07001200
1201 @Override
1202 public void setCustomView(View view) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001203 mDecorToolbar.setCustomView(view);
Adam Powell9ab97872010-10-26 21:47:29 -07001204 }
1205
1206 @Override
1207 public void setCustomView(View view, LayoutParams layoutParams) {
1208 view.setLayoutParams(layoutParams);
Adam Powelle021e6e2014-05-23 17:27:24 -07001209 mDecorToolbar.setCustomView(view);
Adam Powell9ab97872010-10-26 21:47:29 -07001210 }
1211
1212 @Override
Adam Powell8515ee82010-11-30 14:09:55 -08001213 public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001214 mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
Adam Powell9ab97872010-10-26 21:47:29 -07001215 }
1216
1217 @Override
1218 public int getSelectedNavigationIndex() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001219 switch (mDecorToolbar.getNavigationMode()) {
Adam Powell9ab97872010-10-26 21:47:29 -07001220 case NAVIGATION_MODE_TABS:
Adam Powell04587962010-11-11 22:15:07 -08001221 return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
Adam Powell9ab97872010-10-26 21:47:29 -07001222 case NAVIGATION_MODE_LIST:
Adam Powelle021e6e2014-05-23 17:27:24 -07001223 return mDecorToolbar.getDropdownSelectedPosition();
Adam Powell9ab97872010-10-26 21:47:29 -07001224 default:
1225 return -1;
1226 }
1227 }
1228
1229 @Override
1230 public int getNavigationItemCount() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001231 switch (mDecorToolbar.getNavigationMode()) {
Adam Powell9ab97872010-10-26 21:47:29 -07001232 case NAVIGATION_MODE_TABS:
1233 return mTabs.size();
1234 case NAVIGATION_MODE_LIST:
Adam Powelle021e6e2014-05-23 17:27:24 -07001235 return mDecorToolbar.getDropdownItemCount();
Adam Powell9ab97872010-10-26 21:47:29 -07001236 default:
1237 return 0;
1238 }
1239 }
1240
1241 @Override
Adam Powell0c24a552010-11-03 16:44:11 -07001242 public int getTabCount() {
1243 return mTabs.size();
1244 }
1245
1246 @Override
Adam Powell9ab97872010-10-26 21:47:29 -07001247 public void setNavigationMode(int mode) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001248 final int oldMode = mDecorToolbar.getNavigationMode();
Adam Powell0c24a552010-11-03 16:44:11 -07001249 switch (oldMode) {
1250 case NAVIGATION_MODE_TABS:
1251 mSavedTabPosition = getSelectedNavigationIndex();
1252 selectTab(null);
Adam Powellf5645cb2011-08-10 22:49:02 -07001253 mTabScrollView.setVisibility(View.GONE);
Adam Powell0c24a552010-11-03 16:44:11 -07001254 break;
1255 }
Dianne Hackborn3a3a6cf2012-03-26 10:24:04 -07001256 if (oldMode != mode && !mHasEmbeddedTabs) {
1257 if (mOverlayLayout != null) {
1258 mOverlayLayout.requestFitSystemWindows();
1259 }
1260 }
Adam Powelle021e6e2014-05-23 17:27:24 -07001261 mDecorToolbar.setNavigationMode(mode);
Adam Powell0c24a552010-11-03 16:44:11 -07001262 switch (mode) {
1263 case NAVIGATION_MODE_TABS:
Adam Powellf8ac6b72011-05-23 18:14:09 -07001264 ensureTabsExist();
Adam Powellf5645cb2011-08-10 22:49:02 -07001265 mTabScrollView.setVisibility(View.VISIBLE);
Adam Powell0c24a552010-11-03 16:44:11 -07001266 if (mSavedTabPosition != INVALID_POSITION) {
1267 setSelectedNavigationItem(mSavedTabPosition);
1268 mSavedTabPosition = INVALID_POSITION;
1269 }
1270 break;
1271 }
Adam Powelle021e6e2014-05-23 17:27:24 -07001272 mDecorToolbar.setCollapsible(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
Adam Powellb36e4f92014-05-01 10:23:33 -07001273 mOverlayLayout.setHasNonEmbeddedTabs(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
Adam Powell9ab97872010-10-26 21:47:29 -07001274 }
1275
1276 @Override
1277 public Tab getTabAt(int index) {
1278 return mTabs.get(index);
1279 }
Adam Powell0c24a552010-11-03 16:44:11 -07001280
Adam Powell0c24a552010-11-03 16:44:11 -07001281
Adam Powell1969b872011-03-22 11:52:48 -07001282 @Override
1283 public void setIcon(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001284 mDecorToolbar.setIcon(resId);
Adam Powell1969b872011-03-22 11:52:48 -07001285 }
Adam Powell0c24a552010-11-03 16:44:11 -07001286
Adam Powell1969b872011-03-22 11:52:48 -07001287 @Override
1288 public void setIcon(Drawable icon) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001289 mDecorToolbar.setIcon(icon);
Adam Powell1969b872011-03-22 11:52:48 -07001290 }
1291
Adam Powell04fe6eb2013-05-31 14:39:48 -07001292 public boolean hasIcon() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001293 return mDecorToolbar.hasIcon();
Adam Powell04fe6eb2013-05-31 14:39:48 -07001294 }
1295
Adam Powell1969b872011-03-22 11:52:48 -07001296 @Override
1297 public void setLogo(int resId) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001298 mDecorToolbar.setLogo(resId);
Adam Powell1969b872011-03-22 11:52:48 -07001299 }
1300
1301 @Override
1302 public void setLogo(Drawable logo) {
Adam Powelle021e6e2014-05-23 17:27:24 -07001303 mDecorToolbar.setLogo(logo);
Adam Powell0c24a552010-11-03 16:44:11 -07001304 }
Adam Powelldd8fab22012-03-22 17:47:27 -07001305
Adam Powell04fe6eb2013-05-31 14:39:48 -07001306 public boolean hasLogo() {
Adam Powelle021e6e2014-05-23 17:27:24 -07001307 return mDecorToolbar.hasLogo();
Adam Powell04fe6eb2013-05-31 14:39:48 -07001308 }
1309
Adam Powelldd8fab22012-03-22 17:47:27 -07001310 public void setDefaultDisplayHomeAsUpEnabled(boolean enable) {
1311 if (!mDisplayHomeAsUpSet) {
1312 setDisplayHomeAsUpEnabled(enable);
1313 }
1314 }
Adam Powelle021e6e2014-05-23 17:27:24 -07001315
1316 static class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
1317 private final OnNavigationListener mListener;
1318
1319 public NavItemSelectedListener(OnNavigationListener listener) {
1320 mListener = listener;
1321 }
1322
1323 @Override
1324 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
1325 if (mListener != null) {
1326 mListener.onNavigationItemSelected(position, id);
1327 }
1328 }
1329
1330 @Override
1331 public void onNothingSelected(AdapterView<?> parent) {
1332 // Do nothing
1333 }
1334 }
Adam Powell89e06452010-06-23 20:24:52 -07001335}