2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.actionbarsherlock.internal.app;
19 import java.lang.ref.WeakReference;
20 import java.util.ArrayList;
21 import android.app.Activity;
22 import android.app.Dialog;
23 import android.content.Context;
24 import android.content.res.Configuration;
25 import android.content.res.Resources;
26 import android.graphics.drawable.Drawable;
27 import android.os.Build;
28 import android.os.Handler;
29 import android.support.v4.app.FragmentTransaction;
30 import android.util.TypedValue;
31 import android.view.ContextThemeWrapper;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.view.Window;
35 import android.view.accessibility.AccessibilityEvent;
36 import android.widget.SpinnerAdapter;
37 import com.actionbarsherlock.R;
38 import com.actionbarsherlock.app.ActionBar;
39 import com.actionbarsherlock.app.SherlockFragmentActivity;
40 import com.actionbarsherlock.internal.nineoldandroids.animation.Animator;
41 import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorListenerAdapter;
42 import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet;
43 import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator;
44 import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener;
45 import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout;
46 import com.actionbarsherlock.internal.view.menu.MenuBuilder;
47 import com.actionbarsherlock.internal.view.menu.MenuPopupHelper;
48 import com.actionbarsherlock.internal.view.menu.SubMenuBuilder;
49 import com.actionbarsherlock.internal.widget.ActionBarContainer;
50 import com.actionbarsherlock.internal.widget.ActionBarContextView;
51 import com.actionbarsherlock.internal.widget.ActionBarView;
52 import com.actionbarsherlock.internal.widget.ScrollingTabContainerView;
53 import com.actionbarsherlock.view.ActionMode;
54 import com.actionbarsherlock.view.Menu;
55 import com.actionbarsherlock.view.MenuInflater;
56 import com.actionbarsherlock.view.MenuItem;
57 import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean;
60 * ActionBarImpl is the ActionBar implementation used
61 * by devices of all screen sizes. If it detects a compatible decor,
62 * it will split contextual modes across both the ActionBarView at
63 * the top of the screen and a horizontal LinearLayout at the bottom
64 * which is normally hidden.
66 public class ActionBarImpl extends ActionBar {
67 //UNUSED private static final String TAG = "ActionBarImpl";
69 private Context mContext;
70 private Context mThemedContext;
71 private Activity mActivity;
72 //UNUSED private Dialog mDialog;
74 private ActionBarContainer mContainerView;
75 private ActionBarView mActionView;
76 private ActionBarContextView mContextView;
77 private ActionBarContainer mSplitView;
78 private NineFrameLayout mContentView;
79 private ScrollingTabContainerView mTabScrollView;
81 private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
83 private TabImpl mSelectedTab;
84 private int mSavedTabPosition = INVALID_POSITION;
86 ActionModeImpl mActionMode;
87 ActionMode mDeferredDestroyActionMode;
88 ActionMode.Callback mDeferredModeDestroyCallback;
90 private boolean mLastMenuVisibility;
91 private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
92 new ArrayList<OnMenuVisibilityListener>();
94 private static final int CONTEXT_DISPLAY_NORMAL = 0;
95 private static final int CONTEXT_DISPLAY_SPLIT = 1;
97 private static final int INVALID_POSITION = -1;
99 private int mContextDisplayMode;
100 private boolean mHasEmbeddedTabs;
102 final Handler mHandler = new Handler();
103 Runnable mTabSelector;
105 private Animator mCurrentShowAnim;
106 private Animator mCurrentModeAnim;
107 private boolean mShowHideAnimationEnabled;
108 boolean mWasHiddenBeforeMode;
110 final AnimatorListener mHideListener = new AnimatorListenerAdapter() {
112 public void onAnimationEnd(Animator animation) {
113 if (mContentView != null) {
114 mContentView.setTranslationY(0);
115 mContainerView.setTranslationY(0);
117 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
118 mSplitView.setVisibility(View.GONE);
120 mContainerView.setVisibility(View.GONE);
121 mContainerView.setTransitioning(false);
122 mCurrentShowAnim = null;
123 completeDeferredDestroyActionMode();
127 final AnimatorListener mShowListener = new AnimatorListenerAdapter() {
129 public void onAnimationEnd(Animator animation) {
130 mCurrentShowAnim = null;
131 mContainerView.requestLayout();
135 public ActionBarImpl(Activity activity, int features) {
136 mActivity = activity;
137 Window window = activity.getWindow();
138 View decor = window.getDecorView();
141 //window.hasFeature() workaround for pre-3.0
142 if ((features & (1 << Window.FEATURE_ACTION_BAR_OVERLAY)) == 0) {
143 mContentView = (NineFrameLayout)decor.findViewById(android.R.id.content);
147 public ActionBarImpl(Dialog dialog) {
148 //UNUSED mDialog = dialog;
149 init(dialog.getWindow().getDecorView());
152 private void init(View decor) {
153 mContext = decor.getContext();
154 mActionView = (ActionBarView) decor.findViewById(R.id.abs__action_bar);
155 mContextView = (ActionBarContextView) decor.findViewById(
156 R.id.abs__action_context_bar);
157 mContainerView = (ActionBarContainer) decor.findViewById(
158 R.id.abs__action_bar_container);
159 mSplitView = (ActionBarContainer) decor.findViewById(
160 R.id.abs__split_action_bar);
162 if (mActionView == null || mContextView == null || mContainerView == null) {
163 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
164 "with a compatible window decor layout");
167 mActionView.setContextView(mContextView);
168 mContextDisplayMode = mActionView.isSplitActionBar() ?
169 CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
171 // Older apps get the home button interaction enabled by default.
172 // Newer apps need to enable it explicitly.
173 setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion < 14);
175 setHasEmbeddedTabs(getResources_getBoolean(mContext,
176 R.bool.abs__action_bar_embed_tabs));
179 public void onConfigurationChanged(Configuration newConfig) {
180 setHasEmbeddedTabs(getResources_getBoolean(mContext,
181 R.bool.abs__action_bar_embed_tabs));
183 //Manually dispatch a configuration change to the action bar view on pre-2.2
184 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
185 mActionView.onConfigurationChanged(newConfig);
186 if (mContextView != null) {
187 mContextView.onConfigurationChanged(newConfig);
192 private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) {
193 mHasEmbeddedTabs = hasEmbeddedTabs;
194 // Switch tab layout configuration if needed
195 if (!mHasEmbeddedTabs) {
196 mActionView.setEmbeddedTabView(null);
197 mContainerView.setTabContainer(mTabScrollView);
199 mContainerView.setTabContainer(null);
200 mActionView.setEmbeddedTabView(mTabScrollView);
202 final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS;
203 if (mTabScrollView != null) {
204 mTabScrollView.setVisibility(isInTabMode ? View.VISIBLE : View.GONE);
206 mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode);
209 private void ensureTabsExist() {
210 if (mTabScrollView != null) {
214 ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext);
216 if (mHasEmbeddedTabs) {
217 tabScroller.setVisibility(View.VISIBLE);
218 mActionView.setEmbeddedTabView(tabScroller);
220 tabScroller.setVisibility(getNavigationMode() == NAVIGATION_MODE_TABS ?
221 View.VISIBLE : View.GONE);
222 mContainerView.setTabContainer(tabScroller);
224 mTabScrollView = tabScroller;
227 void completeDeferredDestroyActionMode() {
228 if (mDeferredModeDestroyCallback != null) {
229 mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode);
230 mDeferredDestroyActionMode = null;
231 mDeferredModeDestroyCallback = null;
236 * Enables or disables animation between show/hide states.
237 * If animation is disabled using this method, animations in progress
240 * @param enabled true to animate, false to not animate.
242 public void setShowHideAnimationEnabled(boolean enabled) {
243 mShowHideAnimationEnabled = enabled;
244 if (!enabled && mCurrentShowAnim != null) {
245 mCurrentShowAnim.end();
249 public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
250 mMenuVisibilityListeners.add(listener);
253 public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
254 mMenuVisibilityListeners.remove(listener);
257 public void dispatchMenuVisibilityChanged(boolean isVisible) {
258 if (isVisible == mLastMenuVisibility) {
261 mLastMenuVisibility = isVisible;
263 final int count = mMenuVisibilityListeners.size();
264 for (int i = 0; i < count; i++) {
265 mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible);
270 public void setCustomView(int resId) {
271 setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false));
275 public void setDisplayUseLogoEnabled(boolean useLogo) {
276 setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO);
280 public void setDisplayShowHomeEnabled(boolean showHome) {
281 setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME);
285 public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
286 setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP);
290 public void setDisplayShowTitleEnabled(boolean showTitle) {
291 setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE);
295 public void setDisplayShowCustomEnabled(boolean showCustom) {
296 setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM);
300 public void setHomeButtonEnabled(boolean enable) {
301 mActionView.setHomeButtonEnabled(enable);
305 public void setTitle(int resId) {
306 setTitle(mContext.getString(resId));
310 public void setSubtitle(int resId) {
311 setSubtitle(mContext.getString(resId));
314 public void setSelectedNavigationItem(int position) {
315 switch (mActionView.getNavigationMode()) {
316 case NAVIGATION_MODE_TABS:
317 selectTab(mTabs.get(position));
319 case NAVIGATION_MODE_LIST:
320 mActionView.setDropdownSelectedPosition(position);
323 throw new IllegalStateException(
324 "setSelectedNavigationIndex not valid for current navigation mode");
328 public void removeAllTabs() {
332 private void cleanupTabs() {
333 if (mSelectedTab != null) {
337 if (mTabScrollView != null) {
338 mTabScrollView.removeAllTabs();
340 mSavedTabPosition = INVALID_POSITION;
343 public void setTitle(CharSequence title) {
344 mActionView.setTitle(title);
347 public void setSubtitle(CharSequence subtitle) {
348 mActionView.setSubtitle(subtitle);
351 public void setDisplayOptions(int options) {
352 mActionView.setDisplayOptions(options);
355 public void setDisplayOptions(int options, int mask) {
356 final int current = mActionView.getDisplayOptions();
357 mActionView.setDisplayOptions((options & mask) | (current & ~mask));
360 public void setBackgroundDrawable(Drawable d) {
361 mContainerView.setPrimaryBackground(d);
364 public void setStackedBackgroundDrawable(Drawable d) {
365 mContainerView.setStackedBackground(d);
368 public void setSplitBackgroundDrawable(Drawable d) {
369 if (mSplitView != null) {
370 mSplitView.setSplitBackground(d);
374 public View getCustomView() {
375 return mActionView.getCustomNavigationView();
378 public CharSequence getTitle() {
379 return mActionView.getTitle();
382 public CharSequence getSubtitle() {
383 return mActionView.getSubtitle();
386 public int getNavigationMode() {
387 return mActionView.getNavigationMode();
390 public int getDisplayOptions() {
391 return mActionView.getDisplayOptions();
394 public ActionMode startActionMode(ActionMode.Callback callback) {
395 boolean wasHidden = false;
396 if (mActionMode != null) {
397 wasHidden = mWasHiddenBeforeMode;
398 mActionMode.finish();
401 mContextView.killMode();
402 ActionModeImpl mode = new ActionModeImpl(callback);
403 if (mode.dispatchOnCreate()) {
404 mWasHiddenBeforeMode = !isShowing() || wasHidden;
406 mContextView.initForMode(mode);
408 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
410 mSplitView.setVisibility(View.VISIBLE);
412 mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
419 private void configureTab(Tab tab, int position) {
420 final TabImpl tabi = (TabImpl) tab;
421 final ActionBar.TabListener callback = tabi.getCallback();
423 if (callback == null) {
424 throw new IllegalStateException("Action Bar Tab must have a Callback");
427 tabi.setPosition(position);
428 mTabs.add(position, tabi);
430 final int count = mTabs.size();
431 for (int i = position + 1; i < count; i++) {
432 mTabs.get(i).setPosition(i);
437 public void addTab(Tab tab) {
438 addTab(tab, mTabs.isEmpty());
442 public void addTab(Tab tab, int position) {
443 addTab(tab, position, mTabs.isEmpty());
447 public void addTab(Tab tab, boolean setSelected) {
449 mTabScrollView.addTab(tab, setSelected);
450 configureTab(tab, mTabs.size());
457 public void addTab(Tab tab, int position, boolean setSelected) {
459 mTabScrollView.addTab(tab, position, setSelected);
460 configureTab(tab, position);
467 public Tab newTab() {
468 return new TabImpl();
472 public void removeTab(Tab tab) {
473 removeTabAt(tab.getPosition());
477 public void removeTabAt(int position) {
478 if (mTabScrollView == null) {
479 // No tabs around to remove
483 int selectedTabPosition = mSelectedTab != null
484 ? mSelectedTab.getPosition() : mSavedTabPosition;
485 mTabScrollView.removeTabAt(position);
486 TabImpl removedTab = mTabs.remove(position);
487 if (removedTab != null) {
488 removedTab.setPosition(-1);
491 final int newTabCount = mTabs.size();
492 for (int i = position; i < newTabCount; i++) {
493 mTabs.get(i).setPosition(i);
496 if (selectedTabPosition == position) {
497 selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
502 public void selectTab(Tab tab) {
503 if (getNavigationMode() != NAVIGATION_MODE_TABS) {
504 mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
508 FragmentTransaction trans = null;
509 if (mActivity instanceof SherlockFragmentActivity) {
510 trans = ((SherlockFragmentActivity)mActivity).getSupportFragmentManager().beginTransaction()
511 .disallowAddToBackStack();
514 if (mSelectedTab == tab) {
515 if (mSelectedTab != null) {
516 mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
517 mTabScrollView.animateToTab(tab.getPosition());
520 mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
521 if (mSelectedTab != null) {
522 mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
524 mSelectedTab = (TabImpl) tab;
525 if (mSelectedTab != null) {
526 mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans);
530 if (trans != null && !trans.isEmpty()) {
536 public Tab getSelectedTab() {
541 public int getHeight() {
542 return mContainerView.getHeight();
550 void show(boolean markHiddenBeforeMode) {
551 if (mCurrentShowAnim != null) {
552 mCurrentShowAnim.end();
554 if (mContainerView.getVisibility() == View.VISIBLE) {
555 if (markHiddenBeforeMode) mWasHiddenBeforeMode = false;
558 mContainerView.setVisibility(View.VISIBLE);
560 if (mShowHideAnimationEnabled) {
561 mContainerView.setAlpha(0);
562 AnimatorSet anim = new AnimatorSet();
563 AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1));
564 if (mContentView != null) {
565 b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
566 -mContainerView.getHeight(), 0));
567 mContainerView.setTranslationY(-mContainerView.getHeight());
568 b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0));
570 if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
571 mSplitView.setAlpha(0);
572 mSplitView.setVisibility(View.VISIBLE);
573 b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1));
575 anim.addListener(mShowListener);
576 mCurrentShowAnim = anim;
579 mContainerView.setAlpha(1);
580 mContainerView.setTranslationY(0);
581 mShowListener.onAnimationEnd(null);
587 if (mCurrentShowAnim != null) {
588 mCurrentShowAnim.end();
590 if (mContainerView.getVisibility() == View.GONE) {
594 if (mShowHideAnimationEnabled) {
595 mContainerView.setAlpha(1);
596 mContainerView.setTransitioning(true);
597 AnimatorSet anim = new AnimatorSet();
598 AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0));
599 if (mContentView != null) {
600 b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
601 0, -mContainerView.getHeight()));
602 b.with(ObjectAnimator.ofFloat(mContainerView, "translationY",
603 -mContainerView.getHeight()));
605 if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
606 mSplitView.setAlpha(1);
607 b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0));
609 anim.addListener(mHideListener);
610 mCurrentShowAnim = anim;
613 mHideListener.onAnimationEnd(null);
617 public boolean isShowing() {
618 return mContainerView.getVisibility() == View.VISIBLE;
621 void animateToMode(boolean toActionMode) {
625 if (mCurrentModeAnim != null) {
626 mCurrentModeAnim.end();
629 mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
630 mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
631 if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) {
632 mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
636 public Context getThemedContext() {
637 if (mThemedContext == null) {
638 TypedValue outValue = new TypedValue();
639 Resources.Theme currentTheme = mContext.getTheme();
640 currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme,
642 final int targetThemeRes = outValue.resourceId;
644 if (targetThemeRes != 0) { //XXX && mContext.getThemeResId() != targetThemeRes) {
645 mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes);
647 mThemedContext = mContext;
650 return mThemedContext;
656 public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
657 private ActionMode.Callback mCallback;
658 private MenuBuilder mMenu;
659 private WeakReference<View> mCustomView;
661 public ActionModeImpl(ActionMode.Callback callback) {
662 mCallback = callback;
663 mMenu = new MenuBuilder(getThemedContext())
664 .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
665 mMenu.setCallback(this);
669 public MenuInflater getMenuInflater() {
670 return new MenuInflater(getThemedContext());
674 public Menu getMenu() {
679 public void finish() {
680 if (mActionMode != this) {
681 // Not the active action mode - no-op
685 // If we were hidden before the mode was shown, defer the onDestroy
686 // callback until the animation is finished and associated relayout
687 // is about to happen. This lets apps better anticipate visibility
688 // and layout behavior.
689 if (mWasHiddenBeforeMode) {
690 mDeferredDestroyActionMode = this;
691 mDeferredModeDestroyCallback = mCallback;
693 mCallback.onDestroyActionMode(this);
696 animateToMode(false);
698 // Clear out the context mode views after the animation finishes
699 mContextView.closeMode();
700 mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
704 if (mWasHiddenBeforeMode) {
710 public void invalidate() {
711 mMenu.stopDispatchingItemsChanged();
713 mCallback.onPrepareActionMode(this, mMenu);
715 mMenu.startDispatchingItemsChanged();
719 public boolean dispatchOnCreate() {
720 mMenu.stopDispatchingItemsChanged();
722 return mCallback.onCreateActionMode(this, mMenu);
724 mMenu.startDispatchingItemsChanged();
729 public void setCustomView(View view) {
730 mContextView.setCustomView(view);
731 mCustomView = new WeakReference<View>(view);
735 public void setSubtitle(CharSequence subtitle) {
736 mContextView.setSubtitle(subtitle);
740 public void setTitle(CharSequence title) {
741 mContextView.setTitle(title);
745 public void setTitle(int resId) {
746 setTitle(mContext.getResources().getString(resId));
750 public void setSubtitle(int resId) {
751 setSubtitle(mContext.getResources().getString(resId));
755 public CharSequence getTitle() {
756 return mContextView.getTitle();
760 public CharSequence getSubtitle() {
761 return mContextView.getSubtitle();
765 public View getCustomView() {
766 return mCustomView != null ? mCustomView.get() : null;
769 public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
770 if (mCallback != null) {
771 return mCallback.onActionItemClicked(this, item);
777 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
780 public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
781 if (mCallback == null) {
785 if (!subMenu.hasVisibleItems()) {
789 new MenuPopupHelper(getThemedContext(), subMenu).show();
793 public void onCloseSubMenu(SubMenuBuilder menu) {
796 public void onMenuModeChange(MenuBuilder menu) {
797 if (mCallback == null) {
801 mContextView.showOverflowMenu();
808 public class TabImpl extends ActionBar.Tab {
809 private ActionBar.TabListener mCallback;
811 private Drawable mIcon;
812 private CharSequence mText;
813 private CharSequence mContentDesc;
814 private int mPosition = -1;
815 private View mCustomView;
818 public Object getTag() {
823 public Tab setTag(Object tag) {
828 public ActionBar.TabListener getCallback() {
833 public Tab setTabListener(ActionBar.TabListener callback) {
834 mCallback = callback;
839 public View getCustomView() {
844 public Tab setCustomView(View view) {
846 if (mPosition >= 0) {
847 mTabScrollView.updateTab(mPosition);
853 public Tab setCustomView(int layoutResId) {
854 return setCustomView(LayoutInflater.from(getThemedContext())
855 .inflate(layoutResId, null));
859 public Drawable getIcon() {
864 public int getPosition() {
868 public void setPosition(int position) {
869 mPosition = position;
873 public CharSequence getText() {
878 public Tab setIcon(Drawable icon) {
880 if (mPosition >= 0) {
881 mTabScrollView.updateTab(mPosition);
887 public Tab setIcon(int resId) {
888 return setIcon(mContext.getResources().getDrawable(resId));
892 public Tab setText(CharSequence text) {
894 if (mPosition >= 0) {
895 mTabScrollView.updateTab(mPosition);
901 public Tab setText(int resId) {
902 return setText(mContext.getResources().getText(resId));
906 public void select() {
911 public Tab setContentDescription(int resId) {
912 return setContentDescription(mContext.getResources().getText(resId));
916 public Tab setContentDescription(CharSequence contentDesc) {
917 mContentDesc = contentDesc;
918 if (mPosition >= 0) {
919 mTabScrollView.updateTab(mPosition);
925 public CharSequence getContentDescription() {
931 public void setCustomView(View view) {
932 mActionView.setCustomNavigationView(view);
936 public void setCustomView(View view, LayoutParams layoutParams) {
937 view.setLayoutParams(layoutParams);
938 mActionView.setCustomNavigationView(view);
942 public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
943 mActionView.setDropdownAdapter(adapter);
944 mActionView.setCallback(callback);
948 public int getSelectedNavigationIndex() {
949 switch (mActionView.getNavigationMode()) {
950 case NAVIGATION_MODE_TABS:
951 return mSelectedTab != null ? mSelectedTab.getPosition() : -1;
952 case NAVIGATION_MODE_LIST:
953 return mActionView.getDropdownSelectedPosition();
960 public int getNavigationItemCount() {
961 switch (mActionView.getNavigationMode()) {
962 case NAVIGATION_MODE_TABS:
964 case NAVIGATION_MODE_LIST:
965 SpinnerAdapter adapter = mActionView.getDropdownAdapter();
966 return adapter != null ? adapter.getCount() : 0;
973 public int getTabCount() {
978 public void setNavigationMode(int mode) {
979 final int oldMode = mActionView.getNavigationMode();
981 case NAVIGATION_MODE_TABS:
982 mSavedTabPosition = getSelectedNavigationIndex();
984 mTabScrollView.setVisibility(View.GONE);
987 mActionView.setNavigationMode(mode);
989 case NAVIGATION_MODE_TABS:
991 mTabScrollView.setVisibility(View.VISIBLE);
992 if (mSavedTabPosition != INVALID_POSITION) {
993 setSelectedNavigationItem(mSavedTabPosition);
994 mSavedTabPosition = INVALID_POSITION;
998 mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs);
1002 public Tab getTabAt(int index) {
1003 return mTabs.get(index);
1008 public void setIcon(int resId) {
1009 mActionView.setIcon(resId);
1013 public void setIcon(Drawable icon) {
1014 mActionView.setIcon(icon);
1018 public void setLogo(int resId) {
1019 mActionView.setLogo(resId);
1023 public void setLogo(Drawable logo) {
1024 mActionView.setLogo(logo);