diff options
Diffstat (limited to 'libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java')
-rw-r--r-- | libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java | 1026 |
1 files changed, 1026 insertions, 0 deletions
diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java new file mode 100644 index 000000000..d022a2465 --- /dev/null +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/app/ActionBarImpl.java @@ -0,0 +1,1026 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.actionbarsherlock.internal.app; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Handler; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentTransaction; +import android.util.TypedValue; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.accessibility.AccessibilityEvent; +import android.widget.SpinnerAdapter; +import com.actionbarsherlock.R; +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator; +import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorListenerAdapter; +import com.actionbarsherlock.internal.nineoldandroids.animation.AnimatorSet; +import com.actionbarsherlock.internal.nineoldandroids.animation.ObjectAnimator; +import com.actionbarsherlock.internal.nineoldandroids.animation.Animator.AnimatorListener; +import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; +import com.actionbarsherlock.internal.view.menu.MenuBuilder; +import com.actionbarsherlock.internal.view.menu.MenuPopupHelper; +import com.actionbarsherlock.internal.view.menu.SubMenuBuilder; +import com.actionbarsherlock.internal.widget.ActionBarContainer; +import com.actionbarsherlock.internal.widget.ActionBarContextView; +import com.actionbarsherlock.internal.widget.ActionBarView; +import com.actionbarsherlock.internal.widget.ScrollingTabContainerView; +import com.actionbarsherlock.view.ActionMode; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; +import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoolean; + +/** + * ActionBarImpl is the ActionBar implementation used + * by devices of all screen sizes. If it detects a compatible decor, + * it will split contextual modes across both the ActionBarView at + * the top of the screen and a horizontal LinearLayout at the bottom + * which is normally hidden. + */ +public class ActionBarImpl extends ActionBar { + //UNUSED private static final String TAG = "ActionBarImpl"; + + private Context mContext; + private Context mThemedContext; + private Activity mActivity; + //UNUSED private Dialog mDialog; + + private ActionBarContainer mContainerView; + private ActionBarView mActionView; + private ActionBarContextView mContextView; + private ActionBarContainer mSplitView; + private NineFrameLayout mContentView; + private ScrollingTabContainerView mTabScrollView; + + private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>(); + + private TabImpl mSelectedTab; + private int mSavedTabPosition = INVALID_POSITION; + + ActionModeImpl mActionMode; + ActionMode mDeferredDestroyActionMode; + ActionMode.Callback mDeferredModeDestroyCallback; + + private boolean mLastMenuVisibility; + private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners = + new ArrayList<OnMenuVisibilityListener>(); + + private static final int CONTEXT_DISPLAY_NORMAL = 0; + private static final int CONTEXT_DISPLAY_SPLIT = 1; + + private static final int INVALID_POSITION = -1; + + private int mContextDisplayMode; + private boolean mHasEmbeddedTabs; + + final Handler mHandler = new Handler(); + Runnable mTabSelector; + + private Animator mCurrentShowAnim; + private Animator mCurrentModeAnim; + private boolean mShowHideAnimationEnabled; + boolean mWasHiddenBeforeMode; + + final AnimatorListener mHideListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + if (mContentView != null) { + mContentView.setTranslationY(0); + mContainerView.setTranslationY(0); + } + if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { + mSplitView.setVisibility(View.GONE); + } + mContainerView.setVisibility(View.GONE); + mContainerView.setTransitioning(false); + mCurrentShowAnim = null; + completeDeferredDestroyActionMode(); + } + }; + + final AnimatorListener mShowListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mCurrentShowAnim = null; + mContainerView.requestLayout(); + } + }; + + public ActionBarImpl(Activity activity, int features) { + mActivity = activity; + Window window = activity.getWindow(); + View decor = window.getDecorView(); + init(decor); + + //window.hasFeature() workaround for pre-3.0 + if ((features & (1 << Window.FEATURE_ACTION_BAR_OVERLAY)) == 0) { + mContentView = (NineFrameLayout)decor.findViewById(android.R.id.content); + } + } + + public ActionBarImpl(Dialog dialog) { + //UNUSED mDialog = dialog; + init(dialog.getWindow().getDecorView()); + } + + private void init(View decor) { + mContext = decor.getContext(); + mActionView = (ActionBarView) decor.findViewById(R.id.abs__action_bar); + mContextView = (ActionBarContextView) decor.findViewById( + R.id.abs__action_context_bar); + mContainerView = (ActionBarContainer) decor.findViewById( + R.id.abs__action_bar_container); + mSplitView = (ActionBarContainer) decor.findViewById( + R.id.abs__split_action_bar); + + if (mActionView == null || mContextView == null || mContainerView == null) { + throw new IllegalStateException(getClass().getSimpleName() + " can only be used " + + "with a compatible window decor layout"); + } + + mActionView.setContextView(mContextView); + mContextDisplayMode = mActionView.isSplitActionBar() ? + CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL; + + // Older apps get the home button interaction enabled by default. + // Newer apps need to enable it explicitly. + setHomeButtonEnabled(mContext.getApplicationInfo().targetSdkVersion < 14); + + setHasEmbeddedTabs(getResources_getBoolean(mContext, + R.bool.abs__action_bar_embed_tabs)); + } + + public void onConfigurationChanged(Configuration newConfig) { + setHasEmbeddedTabs(getResources_getBoolean(mContext, + R.bool.abs__action_bar_embed_tabs)); + + //Manually dispatch a configuration change to the action bar view on pre-2.2 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { + mActionView.onConfigurationChanged(newConfig); + if (mContextView != null) { + mContextView.onConfigurationChanged(newConfig); + } + } + } + + private void setHasEmbeddedTabs(boolean hasEmbeddedTabs) { + mHasEmbeddedTabs = hasEmbeddedTabs; + // Switch tab layout configuration if needed + if (!mHasEmbeddedTabs) { + mActionView.setEmbeddedTabView(null); + mContainerView.setTabContainer(mTabScrollView); + } else { + mContainerView.setTabContainer(null); + mActionView.setEmbeddedTabView(mTabScrollView); + } + final boolean isInTabMode = getNavigationMode() == NAVIGATION_MODE_TABS; + if (mTabScrollView != null) { + mTabScrollView.setVisibility(isInTabMode ? View.VISIBLE : View.GONE); + } + mActionView.setCollapsable(!mHasEmbeddedTabs && isInTabMode); + } + + private void ensureTabsExist() { + if (mTabScrollView != null) { + return; + } + + ScrollingTabContainerView tabScroller = new ScrollingTabContainerView(mContext); + + if (mHasEmbeddedTabs) { + tabScroller.setVisibility(View.VISIBLE); + mActionView.setEmbeddedTabView(tabScroller); + } else { + tabScroller.setVisibility(getNavigationMode() == NAVIGATION_MODE_TABS ? + View.VISIBLE : View.GONE); + mContainerView.setTabContainer(tabScroller); + } + mTabScrollView = tabScroller; + } + + void completeDeferredDestroyActionMode() { + if (mDeferredModeDestroyCallback != null) { + mDeferredModeDestroyCallback.onDestroyActionMode(mDeferredDestroyActionMode); + mDeferredDestroyActionMode = null; + mDeferredModeDestroyCallback = null; + } + } + + /** + * Enables or disables animation between show/hide states. + * If animation is disabled using this method, animations in progress + * will be finished. + * + * @param enabled true to animate, false to not animate. + */ + public void setShowHideAnimationEnabled(boolean enabled) { + mShowHideAnimationEnabled = enabled; + if (!enabled && mCurrentShowAnim != null) { + mCurrentShowAnim.end(); + } + } + + public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.add(listener); + } + + public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) { + mMenuVisibilityListeners.remove(listener); + } + + public void dispatchMenuVisibilityChanged(boolean isVisible) { + if (isVisible == mLastMenuVisibility) { + return; + } + mLastMenuVisibility = isVisible; + + final int count = mMenuVisibilityListeners.size(); + for (int i = 0; i < count; i++) { + mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible); + } + } + + @Override + public void setCustomView(int resId) { + setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); + } + + @Override + public void setDisplayUseLogoEnabled(boolean useLogo) { + setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO); + } + + @Override + public void setDisplayShowHomeEnabled(boolean showHome) { + setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME); + } + + @Override + public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) { + setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP); + } + + @Override + public void setDisplayShowTitleEnabled(boolean showTitle) { + setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE); + } + + @Override + public void setDisplayShowCustomEnabled(boolean showCustom) { + setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM); + } + + @Override + public void setHomeButtonEnabled(boolean enable) { + mActionView.setHomeButtonEnabled(enable); + } + + @Override + public void setTitle(int resId) { + setTitle(mContext.getString(resId)); + } + + @Override + public void setSubtitle(int resId) { + setSubtitle(mContext.getString(resId)); + } + + public void setSelectedNavigationItem(int position) { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + selectTab(mTabs.get(position)); + break; + case NAVIGATION_MODE_LIST: + mActionView.setDropdownSelectedPosition(position); + break; + default: + throw new IllegalStateException( + "setSelectedNavigationIndex not valid for current navigation mode"); + } + } + + public void removeAllTabs() { + cleanupTabs(); + } + + private void cleanupTabs() { + if (mSelectedTab != null) { + selectTab(null); + } + mTabs.clear(); + if (mTabScrollView != null) { + mTabScrollView.removeAllTabs(); + } + mSavedTabPosition = INVALID_POSITION; + } + + public void setTitle(CharSequence title) { + mActionView.setTitle(title); + } + + public void setSubtitle(CharSequence subtitle) { + mActionView.setSubtitle(subtitle); + } + + public void setDisplayOptions(int options) { + mActionView.setDisplayOptions(options); + } + + public void setDisplayOptions(int options, int mask) { + final int current = mActionView.getDisplayOptions(); + mActionView.setDisplayOptions((options & mask) | (current & ~mask)); + } + + public void setBackgroundDrawable(Drawable d) { + mContainerView.setPrimaryBackground(d); + } + + public void setStackedBackgroundDrawable(Drawable d) { + mContainerView.setStackedBackground(d); + } + + public void setSplitBackgroundDrawable(Drawable d) { + if (mSplitView != null) { + mSplitView.setSplitBackground(d); + } + } + + public View getCustomView() { + return mActionView.getCustomNavigationView(); + } + + public CharSequence getTitle() { + return mActionView.getTitle(); + } + + public CharSequence getSubtitle() { + return mActionView.getSubtitle(); + } + + public int getNavigationMode() { + return mActionView.getNavigationMode(); + } + + public int getDisplayOptions() { + return mActionView.getDisplayOptions(); + } + + public ActionMode startActionMode(ActionMode.Callback callback) { + boolean wasHidden = false; + if (mActionMode != null) { + wasHidden = mWasHiddenBeforeMode; + mActionMode.finish(); + } + + mContextView.killMode(); + ActionModeImpl mode = new ActionModeImpl(callback); + if (mode.dispatchOnCreate()) { + mWasHiddenBeforeMode = !isShowing() || wasHidden; + mode.invalidate(); + mContextView.initForMode(mode); + animateToMode(true); + if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { + // TODO animate this + mSplitView.setVisibility(View.VISIBLE); + } + mContextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + mActionMode = mode; + return mode; + } + return null; + } + + private void configureTab(Tab tab, int position) { + final TabImpl tabi = (TabImpl) tab; + final ActionBar.TabListener callback = tabi.getCallback(); + + if (callback == null) { + throw new IllegalStateException("Action Bar Tab must have a Callback"); + } + + tabi.setPosition(position); + mTabs.add(position, tabi); + + final int count = mTabs.size(); + for (int i = position + 1; i < count; i++) { + mTabs.get(i).setPosition(i); + } + } + + @Override + public void addTab(Tab tab) { + addTab(tab, mTabs.isEmpty()); + } + + @Override + public void addTab(Tab tab, int position) { + addTab(tab, position, mTabs.isEmpty()); + } + + @Override + public void addTab(Tab tab, boolean setSelected) { + ensureTabsExist(); + mTabScrollView.addTab(tab, setSelected); + configureTab(tab, mTabs.size()); + if (setSelected) { + selectTab(tab); + } + } + + @Override + public void addTab(Tab tab, int position, boolean setSelected) { + ensureTabsExist(); + mTabScrollView.addTab(tab, position, setSelected); + configureTab(tab, position); + if (setSelected) { + selectTab(tab); + } + } + + @Override + public Tab newTab() { + return new TabImpl(); + } + + @Override + public void removeTab(Tab tab) { + removeTabAt(tab.getPosition()); + } + + @Override + public void removeTabAt(int position) { + if (mTabScrollView == null) { + // No tabs around to remove + return; + } + + int selectedTabPosition = mSelectedTab != null + ? mSelectedTab.getPosition() : mSavedTabPosition; + mTabScrollView.removeTabAt(position); + TabImpl removedTab = mTabs.remove(position); + if (removedTab != null) { + removedTab.setPosition(-1); + } + + final int newTabCount = mTabs.size(); + for (int i = position; i < newTabCount; i++) { + mTabs.get(i).setPosition(i); + } + + if (selectedTabPosition == position) { + selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1))); + } + } + + @Override + public void selectTab(Tab tab) { + if (getNavigationMode() != NAVIGATION_MODE_TABS) { + mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION; + return; + } + + FragmentTransaction trans = null; + if (mActivity instanceof FragmentActivity) { + trans = ((FragmentActivity)mActivity).getSupportFragmentManager().beginTransaction() + .disallowAddToBackStack(); + } + + if (mSelectedTab == tab) { + if (mSelectedTab != null) { + mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans); + mTabScrollView.animateToTab(tab.getPosition()); + } + } else { + mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION); + if (mSelectedTab != null) { + mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans); + } + mSelectedTab = (TabImpl) tab; + if (mSelectedTab != null) { + mSelectedTab.getCallback().onTabSelected(mSelectedTab, trans); + } + } + + if (trans != null && !trans.isEmpty()) { + trans.commit(); + } + } + + @Override + public Tab getSelectedTab() { + return mSelectedTab; + } + + @Override + public int getHeight() { + return mContainerView.getHeight(); + } + + @Override + public void show() { + show(true); + } + + void show(boolean markHiddenBeforeMode) { + if (mCurrentShowAnim != null) { + mCurrentShowAnim.end(); + } + if (mContainerView.getVisibility() == View.VISIBLE) { + if (markHiddenBeforeMode) mWasHiddenBeforeMode = false; + return; + } + mContainerView.setVisibility(View.VISIBLE); + + if (mShowHideAnimationEnabled) { + mContainerView.setAlpha(0); + AnimatorSet anim = new AnimatorSet(); + AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 1)); + if (mContentView != null) { + b.with(ObjectAnimator.ofFloat(mContentView, "translationY", + -mContainerView.getHeight(), 0)); + mContainerView.setTranslationY(-mContainerView.getHeight()); + b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", 0)); + } + if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) { + mSplitView.setAlpha(0); + mSplitView.setVisibility(View.VISIBLE); + b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1)); + } + anim.addListener(mShowListener); + mCurrentShowAnim = anim; + anim.start(); + } else { + mContainerView.setAlpha(1); + mContainerView.setTranslationY(0); + mShowListener.onAnimationEnd(null); + } + } + + @Override + public void hide() { + if (mCurrentShowAnim != null) { + mCurrentShowAnim.end(); + } + if (mContainerView.getVisibility() == View.GONE) { + return; + } + + if (mShowHideAnimationEnabled) { + mContainerView.setAlpha(1); + mContainerView.setTransitioning(true); + AnimatorSet anim = new AnimatorSet(); + AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mContainerView, "alpha", 0)); + if (mContentView != null) { + b.with(ObjectAnimator.ofFloat(mContentView, "translationY", + 0, -mContainerView.getHeight())); + b.with(ObjectAnimator.ofFloat(mContainerView, "translationY", + -mContainerView.getHeight())); + } + if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) { + mSplitView.setAlpha(1); + b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0)); + } + anim.addListener(mHideListener); + mCurrentShowAnim = anim; + anim.start(); + } else { + mHideListener.onAnimationEnd(null); + } + } + + public boolean isShowing() { + return mContainerView.getVisibility() == View.VISIBLE; + } + + void animateToMode(boolean toActionMode) { + if (toActionMode) { + show(false); + } + if (mCurrentModeAnim != null) { + mCurrentModeAnim.end(); + } + + mActionView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); + mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE); + if (mTabScrollView != null && !mActionView.hasEmbeddedTabs() && mActionView.isCollapsed()) { + mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE); + } + } + + public Context getThemedContext() { + if (mThemedContext == null) { + TypedValue outValue = new TypedValue(); + Resources.Theme currentTheme = mContext.getTheme(); + currentTheme.resolveAttribute(R.attr.actionBarWidgetTheme, + outValue, true); + final int targetThemeRes = outValue.resourceId; + + if (targetThemeRes != 0) { //XXX && mContext.getThemeResId() != targetThemeRes) { + mThemedContext = new ContextThemeWrapper(mContext, targetThemeRes); + } else { + mThemedContext = mContext; + } + } + return mThemedContext; + } + + /** + * @hide + */ + public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback { + private ActionMode.Callback mCallback; + private MenuBuilder mMenu; + private WeakReference<View> mCustomView; + + public ActionModeImpl(ActionMode.Callback callback) { + mCallback = callback; + mMenu = new MenuBuilder(getThemedContext()) + .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + mMenu.setCallback(this); + } + + @Override + public MenuInflater getMenuInflater() { + return new MenuInflater(getThemedContext()); + } + + @Override + public Menu getMenu() { + return mMenu; + } + + @Override + public void finish() { + if (mActionMode != this) { + // Not the active action mode - no-op + return; + } + + // If we were hidden before the mode was shown, defer the onDestroy + // callback until the animation is finished and associated relayout + // is about to happen. This lets apps better anticipate visibility + // and layout behavior. + if (mWasHiddenBeforeMode) { + mDeferredDestroyActionMode = this; + mDeferredModeDestroyCallback = mCallback; + } else { + mCallback.onDestroyActionMode(this); + } + mCallback = null; + animateToMode(false); + + // Clear out the context mode views after the animation finishes + mContextView.closeMode(); + mActionView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + + mActionMode = null; + + if (mWasHiddenBeforeMode) { + hide(); + } + } + + @Override + public void invalidate() { + mMenu.stopDispatchingItemsChanged(); + try { + mCallback.onPrepareActionMode(this, mMenu); + } finally { + mMenu.startDispatchingItemsChanged(); + } + } + + public boolean dispatchOnCreate() { + mMenu.stopDispatchingItemsChanged(); + try { + return mCallback.onCreateActionMode(this, mMenu); + } finally { + mMenu.startDispatchingItemsChanged(); + } + } + + @Override + public void setCustomView(View view) { + mContextView.setCustomView(view); + mCustomView = new WeakReference<View>(view); + } + + @Override + public void setSubtitle(CharSequence subtitle) { + mContextView.setSubtitle(subtitle); + } + + @Override + public void setTitle(CharSequence title) { + mContextView.setTitle(title); + } + + @Override + public void setTitle(int resId) { + setTitle(mContext.getResources().getString(resId)); + } + + @Override + public void setSubtitle(int resId) { + setSubtitle(mContext.getResources().getString(resId)); + } + + @Override + public CharSequence getTitle() { + return mContextView.getTitle(); + } + + @Override + public CharSequence getSubtitle() { + return mContextView.getSubtitle(); + } + + @Override + public View getCustomView() { + return mCustomView != null ? mCustomView.get() : null; + } + + public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { + if (mCallback != null) { + return mCallback.onActionItemClicked(this, item); + } else { + return false; + } + } + + public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { + } + + public boolean onSubMenuSelected(SubMenuBuilder subMenu) { + if (mCallback == null) { + return false; + } + + if (!subMenu.hasVisibleItems()) { + return true; + } + + new MenuPopupHelper(getThemedContext(), subMenu).show(); + return true; + } + + public void onCloseSubMenu(SubMenuBuilder menu) { + } + + public void onMenuModeChange(MenuBuilder menu) { + if (mCallback == null) { + return; + } + invalidate(); + mContextView.showOverflowMenu(); + } + } + + /** + * @hide + */ + public class TabImpl extends ActionBar.Tab { + private ActionBar.TabListener mCallback; + private Object mTag; + private Drawable mIcon; + private CharSequence mText; + private CharSequence mContentDesc; + private int mPosition = -1; + private View mCustomView; + + @Override + public Object getTag() { + return mTag; + } + + @Override + public Tab setTag(Object tag) { + mTag = tag; + return this; + } + + public ActionBar.TabListener getCallback() { + return mCallback; + } + + @Override + public Tab setTabListener(ActionBar.TabListener callback) { + mCallback = callback; + return this; + } + + @Override + public View getCustomView() { + return mCustomView; + } + + @Override + public Tab setCustomView(View view) { + mCustomView = view; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public Tab setCustomView(int layoutResId) { + return setCustomView(LayoutInflater.from(getThemedContext()) + .inflate(layoutResId, null)); + } + + @Override + public Drawable getIcon() { + return mIcon; + } + + @Override + public int getPosition() { + return mPosition; + } + + public void setPosition(int position) { + mPosition = position; + } + + @Override + public CharSequence getText() { + return mText; + } + + @Override + public Tab setIcon(Drawable icon) { + mIcon = icon; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public Tab setIcon(int resId) { + return setIcon(mContext.getResources().getDrawable(resId)); + } + + @Override + public Tab setText(CharSequence text) { + mText = text; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public Tab setText(int resId) { + return setText(mContext.getResources().getText(resId)); + } + + @Override + public void select() { + selectTab(this); + } + + @Override + public Tab setContentDescription(int resId) { + return setContentDescription(mContext.getResources().getText(resId)); + } + + @Override + public Tab setContentDescription(CharSequence contentDesc) { + mContentDesc = contentDesc; + if (mPosition >= 0) { + mTabScrollView.updateTab(mPosition); + } + return this; + } + + @Override + public CharSequence getContentDescription() { + return mContentDesc; + } + } + + @Override + public void setCustomView(View view) { + mActionView.setCustomNavigationView(view); + } + + @Override + public void setCustomView(View view, LayoutParams layoutParams) { + view.setLayoutParams(layoutParams); + mActionView.setCustomNavigationView(view); + } + + @Override + public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) { + mActionView.setDropdownAdapter(adapter); + mActionView.setCallback(callback); + } + + @Override + public int getSelectedNavigationIndex() { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + return mSelectedTab != null ? mSelectedTab.getPosition() : -1; + case NAVIGATION_MODE_LIST: + return mActionView.getDropdownSelectedPosition(); + default: + return -1; + } + } + + @Override + public int getNavigationItemCount() { + switch (mActionView.getNavigationMode()) { + case NAVIGATION_MODE_TABS: + return mTabs.size(); + case NAVIGATION_MODE_LIST: + SpinnerAdapter adapter = mActionView.getDropdownAdapter(); + return adapter != null ? adapter.getCount() : 0; + default: + return 0; + } + } + + @Override + public int getTabCount() { + return mTabs.size(); + } + + @Override + public void setNavigationMode(int mode) { + final int oldMode = mActionView.getNavigationMode(); + switch (oldMode) { + case NAVIGATION_MODE_TABS: + mSavedTabPosition = getSelectedNavigationIndex(); + selectTab(null); + mTabScrollView.setVisibility(View.GONE); + break; + } + mActionView.setNavigationMode(mode); + switch (mode) { + case NAVIGATION_MODE_TABS: + ensureTabsExist(); + mTabScrollView.setVisibility(View.VISIBLE); + if (mSavedTabPosition != INVALID_POSITION) { + setSelectedNavigationItem(mSavedTabPosition); + mSavedTabPosition = INVALID_POSITION; + } + break; + } + mActionView.setCollapsable(mode == NAVIGATION_MODE_TABS && !mHasEmbeddedTabs); + } + + @Override + public Tab getTabAt(int index) { + return mTabs.get(index); + } + + + @Override + public void setIcon(int resId) { + mActionView.setIcon(resId); + } + + @Override + public void setIcon(Drawable icon) { + mActionView.setIcon(icon); + } + + @Override + public void setLogo(int resId) { + mActionView.setLogo(resId); + } + + @Override + public void setLogo(Drawable logo) { + mActionView.setLogo(logo); + } +} |