Merge "Action bar tab layout"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 87369ab..3877bd0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1398,6 +1398,10 @@
public void onConfigurationChanged(Configuration newConfig) {
mCalled = true;
+ if (mActionBar != null) {
+ mActionBar.onConfigurationChanged(newConfig);
+ }
+
mFragments.dispatchConfigurationChanged(newConfig);
if (mWindow != null) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index bac849e..6f30452 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -696,7 +696,8 @@
mTotalLength += mDividerHeight;
}
- if (useLargestChild && heightMode == MeasureSpec.AT_MOST) {
+ if (useLargestChild &&
+ (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED)) {
mTotalLength = 0;
for (int i = 0; i < count; ++i) {
@@ -809,6 +810,31 @@
} else {
alternativeMaxWidth = Math.max(alternativeMaxWidth,
weightedMaxWidth);
+
+
+ // We have no limit, so make all weighted views as tall as the largest child.
+ // Children will have already been measured once.
+ if (useLargestChild && widthMode == MeasureSpec.UNSPECIFIED) {
+ for (int i = 0; i < count; i++) {
+ final View child = getVirtualChildAt(i);
+
+ if (child == null || child.getVisibility() == View.GONE) {
+ continue;
+ }
+
+ final LinearLayout.LayoutParams lp =
+ (LinearLayout.LayoutParams) child.getLayoutParams();
+
+ float childExtra = lp.weight;
+ if (childExtra > 0) {
+ child.measure(
+ MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(),
+ MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(largestChildHeight,
+ MeasureSpec.EXACTLY));
+ }
+ }
+ }
}
if (!allFillParent && widthMode != MeasureSpec.EXACTLY) {
@@ -1044,7 +1070,8 @@
maxHeight = Math.max(maxHeight, ascent + descent);
}
- if (useLargestChild && widthMode == MeasureSpec.AT_MOST) {
+ if (useLargestChild &&
+ (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.UNSPECIFIED)) {
mTotalLength = 0;
for (int i = 0; i < count; ++i) {
@@ -1200,6 +1227,29 @@
}
} else {
alternativeMaxHeight = Math.max(alternativeMaxHeight, weightedMaxHeight);
+
+ // We have no limit, so make all weighted views as wide as the largest child.
+ // Children will have already been measured once.
+ if (useLargestChild && widthMode == MeasureSpec.UNSPECIFIED) {
+ for (int i = 0; i < count; i++) {
+ final View child = getVirtualChildAt(i);
+
+ if (child == null || child.getVisibility() == View.GONE) {
+ continue;
+ }
+
+ final LinearLayout.LayoutParams lp =
+ (LinearLayout.LayoutParams) child.getLayoutParams();
+
+ float childExtra = lp.weight;
+ if (childExtra > 0) {
+ child.measure(
+ MeasureSpec.makeMeasureSpec(largestChildWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(),
+ MeasureSpec.EXACTLY));
+ }
+ }
+ }
}
if (!allFillParent && heightMode != MeasureSpec.EXACTLY) {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 1e576ce..183cfbd 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -16,25 +16,27 @@
package com.android.internal.app;
+import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuPopupHelper;
import com.android.internal.view.menu.SubMenuBuilder;
-import com.android.internal.widget.AbsActionBarView;
import com.android.internal.widget.ActionBarContainer;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.ScrollingTabContainerView;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Dialog;
import android.app.FragmentTransaction;
import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.ActionMode;
@@ -43,10 +45,7 @@
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
import android.view.Window;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.HorizontalScrollView;
import android.widget.SpinnerAdapter;
import java.lang.ref.WeakReference;
@@ -71,7 +70,7 @@
private ActionBarContextView mContextView;
private ActionBarContainer mSplitView;
private View mContentView;
- private ViewGroup mExternalTabView;
+ private ScrollingTabContainerView mTabScrollView;
private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
@@ -90,16 +89,17 @@
private static final int INVALID_POSITION = -1;
private int mContextDisplayMode;
+ private boolean mHasEmbeddedTabs;
+ private int mContentHeight;
final Handler mHandler = new Handler();
+ Runnable mTabSelector;
private Animator mCurrentShowAnim;
private Animator mCurrentModeAnim;
private boolean mShowHideAnimationEnabled;
boolean mWasHiddenBeforeMode;
- private static final TimeInterpolator sFadeOutInterpolator = new DecelerateInterpolator();
-
final AnimatorListener mHideListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -150,21 +150,59 @@
"with a compatible window decor layout");
}
+ mHasEmbeddedTabs = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.action_bar_embed_tabs);
mActionView.setContextView(mContextView);
mContextDisplayMode = mActionView.isSplitActionBar() ?
CONTEXT_DISPLAY_SPLIT : CONTEXT_DISPLAY_NORMAL;
- if (!mActionView.hasEmbeddedTabs()) {
- HorizontalScrollView tabScroller = new HorizontalScrollView(mContext);
- ViewGroup tabContainer = mActionView.createTabContainer();
- tabScroller.setHorizontalFadingEdgeEnabled(true);
- tabScroller.addView(tabContainer);
+ TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar);
+ mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
+ a.recycle();
+ }
+
+ public void onConfigurationChanged(Configuration newConfig) {
+ mHasEmbeddedTabs = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.action_bar_embed_tabs);
+
+ // Switch tab layout configuration if needed
+ if (!mHasEmbeddedTabs) {
+ mActionView.setEmbeddedTabView(null);
+ mContainerView.setTabContainer(mTabScrollView);
+ } else {
+ mContainerView.setTabContainer(null);
+ if (mTabScrollView != null) {
+ mTabScrollView.setVisibility(View.VISIBLE);
+ }
+ mActionView.setEmbeddedTabView(mTabScrollView);
+ }
+
+ TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar);
+ mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
+ a.recycle();
+
+ if (mTabScrollView != null) {
+ mTabScrollView.getLayoutParams().height = mContentHeight;
+ mTabScrollView.requestLayout();
+ }
+ }
+
+ private void ensureTabsExist() {
+ if (mTabScrollView != null) {
+ return;
+ }
+
+ ScrollingTabContainerView tabScroller = mActionView.createTabContainer();
+
+ if (mHasEmbeddedTabs) {
+ tabScroller.setVisibility(View.VISIBLE);
+ mActionView.setEmbeddedTabView(tabScroller);
+ } else {
tabScroller.setVisibility(getNavigationMode() == NAVIGATION_MODE_TABS ?
View.VISIBLE : View.GONE);
- mActionView.setExternalTabLayout(tabContainer);
mContainerView.setTabContainer(tabScroller);
- mExternalTabView = tabScroller;
}
+ mTabScrollView = tabScroller;
}
/**
@@ -269,7 +307,7 @@
selectTab(null);
}
mTabs.clear();
- mActionView.removeAllTabs();
+ mTabScrollView.removeAllTabs();
mSavedTabPosition = INVALID_POSITION;
}
@@ -365,7 +403,8 @@
@Override
public void addTab(Tab tab, boolean setSelected) {
- mActionView.addTab(tab, setSelected);
+ ensureTabsExist();
+ mTabScrollView.addTab(tab, setSelected);
configureTab(tab, mTabs.size());
if (setSelected) {
selectTab(tab);
@@ -374,7 +413,8 @@
@Override
public void addTab(Tab tab, int position, boolean setSelected) {
- mActionView.addTab(tab, position, setSelected);
+ ensureTabsExist();
+ mTabScrollView.addTab(tab, position, setSelected);
configureTab(tab, position);
if (setSelected) {
selectTab(tab);
@@ -393,9 +433,14 @@
@Override
public void removeTabAt(int position) {
+ if (mTabScrollView == null) {
+ // No tabs around to remove
+ return;
+ }
+
int selectedTabPosition = mSelectedTab != null
? mSelectedTab.getPosition() : mSavedTabPosition;
- mActionView.removeTabAt(position);
+ mTabScrollView.removeTabAt(position);
TabImpl removedTab = mTabs.remove(position);
if (removedTab != null) {
removedTab.setPosition(-1);
@@ -424,9 +469,10 @@
if (mSelectedTab == tab) {
if (mSelectedTab != null) {
mSelectedTab.getCallback().onTabReselected(mSelectedTab, trans);
+ mTabScrollView.animateToTab(tab.getPosition());
}
} else {
- mActionView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
+ mTabScrollView.setTabSelected(tab != null ? tab.getPosition() : Tab.INVALID_POSITION);
if (mSelectedTab != null) {
mSelectedTab.getCallback().onTabUnselected(mSelectedTab, trans);
}
@@ -705,7 +751,9 @@
@Override
public Tab setCustomView(View view) {
mCustomView = view;
- if (mPosition >= 0) mActionView.updateTab(mPosition);
+ if (mPosition >= 0) {
+ mTabScrollView.updateTab(mPosition);
+ }
return this;
}
@@ -736,7 +784,9 @@
@Override
public Tab setIcon(Drawable icon) {
mIcon = icon;
- if (mPosition >= 0) mActionView.updateTab(mPosition);
+ if (mPosition >= 0) {
+ mTabScrollView.updateTab(mPosition);
+ }
return this;
}
@@ -748,7 +798,9 @@
@Override
public Tab setText(CharSequence text) {
mText = text;
- if (mPosition >= 0) mActionView.updateTab(mPosition);
+ if (mPosition >= 0) {
+ mTabScrollView.updateTab(mPosition);
+ }
return this;
}
@@ -818,15 +870,16 @@
mSavedTabPosition = getSelectedNavigationIndex();
selectTab(null);
if (!mActionView.hasEmbeddedTabs()) {
- mExternalTabView.setVisibility(View.GONE);
+ mTabScrollView.setVisibility(View.GONE);
}
break;
}
mActionView.setNavigationMode(mode);
switch (mode) {
case NAVIGATION_MODE_TABS:
+ ensureTabsExist();
if (!mActionView.hasEmbeddedTabs()) {
- mExternalTabView.setVisibility(View.VISIBLE);
+ mTabScrollView.setVisibility(View.VISIBLE);
}
if (mSavedTabPosition != INVALID_POSITION) {
setSelectedNavigationItem(mSavedTabPosition);
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index f1887eb..ff04735 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -78,7 +78,7 @@
private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.LEFT | Gravity.CENTER_VERTICAL;
- private final int mContentHeight;
+ private int mContentHeight;
private int mNavigationMode;
private int mDisplayOptions = ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP;
@@ -95,8 +95,7 @@
private TextView mSubtitleView;
private Spinner mSpinner;
private LinearLayout mListNavLayout;
- private HorizontalScrollView mTabScrollView;
- private ViewGroup mTabLayout;
+ private ScrollingTabContainerView mTabScrollView;
private View mCustomNavView;
private ProgressBar mProgressView;
private ProgressBar mIndeterminateProgressView;
@@ -122,6 +121,8 @@
private SpinnerAdapter mSpinnerAdapter;
private OnNavigationListener mCallback;
+ private Runnable mTabSelector;
+
private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView parent, View view, int position, long id) {
@@ -199,8 +200,6 @@
mProgressBarPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_progressBarPadding, 0);
mItemPadding = a.getDimensionPixelOffset(R.styleable.ActionBar_itemPadding, 0);
- mIncludeTabs = a.getBoolean(R.styleable.ActionBar_embeddedTabs, true);
-
setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, DISPLAY_DEFAULT));
final int customNavId = a.getResourceId(R.styleable.ActionBar_customNavigationLayout, 0);
@@ -229,6 +228,12 @@
}
@Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ removeCallbacks(mTabSelector);
+ }
+
+ @Override
public boolean shouldDelayChildPressedState() {
return false;
}
@@ -247,6 +252,11 @@
addView(mIndeterminateProgressView);
}
+ public void setContentHeight(int height) {
+ mContentHeight = height;
+ requestLayout();
+ }
+
public void setSplitActionBar(boolean splitActionBar) {
if (mSplitActionBar != splitActionBar) {
if (mMenuView != null) {
@@ -271,8 +281,9 @@
return mIncludeTabs;
}
- public void setExternalTabLayout(ViewGroup tabLayout) {
- mTabLayout = tabLayout;
+ public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
+ mTabScrollView = tabs;
+ mIncludeTabs = tabs != null;
}
public void setCallback(OnNavigationListener callback) {
@@ -489,7 +500,7 @@
}
break;
case ActionBar.NAVIGATION_MODE_TABS:
- if (mTabScrollView != null) {
+ if (mTabScrollView != null && mIncludeTabs) {
removeView(mTabScrollView);
}
}
@@ -513,8 +524,7 @@
addView(mListNavLayout);
break;
case ActionBar.NAVIGATION_MODE_TABS:
- ensureTabsExist();
- if (mTabScrollView != null) {
+ if (mTabScrollView != null && mIncludeTabs) {
addView(mTabScrollView);
}
break;
@@ -523,24 +533,17 @@
requestLayout();
}
}
-
- private void ensureTabsExist() {
- if (!mIncludeTabs) return;
- if (mTabScrollView == null) {
- mTabScrollView = new HorizontalScrollView(getContext());
- mTabScrollView.setHorizontalFadingEdgeEnabled(true);
- mTabLayout = createTabContainer();
- mTabScrollView.addView(mTabLayout);
- }
- }
-
- public ViewGroup createTabContainer() {
- ViewGroup result = new LinearLayout(getContext(), null,
+ public ScrollingTabContainerView createTabContainer() {
+ final LinearLayout tabLayout = new LinearLayout(getContext(), null,
com.android.internal.R.attr.actionBarTabBarStyle);
- result.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
- mContentHeight));
- return result;
+ tabLayout.setMeasureWithLargestChildEnabled(true);
+ tabLayout.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT, mContentHeight));
+
+ final ScrollingTabContainerView scroller = new ScrollingTabContainerView(mContext);
+ scroller.setTabLayout(tabLayout);
+ return scroller;
}
public void setDropdownAdapter(SpinnerAdapter adapter) {
@@ -574,51 +577,6 @@
return mDisplayOptions;
}
- private TabView createTabView(ActionBar.Tab tab) {
- final TabView tabView = new TabView(getContext(), tab);
- tabView.setFocusable(true);
-
- if (mTabClickListener == null) {
- mTabClickListener = new TabClickListener();
- }
- tabView.setOnClickListener(mTabClickListener);
- return tabView;
- }
-
- public void addTab(ActionBar.Tab tab, boolean setSelected) {
- ensureTabsExist();
- View tabView = createTabView(tab);
- mTabLayout.addView(tabView);
- if (setSelected) {
- tabView.setSelected(true);
- }
- }
-
- public void addTab(ActionBar.Tab tab, int position, boolean setSelected) {
- ensureTabsExist();
- final TabView tabView = createTabView(tab);
- mTabLayout.addView(tabView, position);
- if (setSelected) {
- tabView.setSelected(true);
- }
- }
-
- public void updateTab(int position) {
- ((TabView) mTabLayout.getChildAt(position)).update();
- }
-
- public void removeTabAt(int position) {
- if (mTabLayout != null) {
- mTabLayout.removeViewAt(position);
- }
- }
-
- public void removeAllTabs() {
- if (mTabLayout != null) {
- mTabLayout.removeAllViews();
- }
- }
-
@Override
protected LayoutParams generateDefaultLayoutParams() {
// Used by custom nav views if they don't supply layout params. Everything else
@@ -667,15 +625,6 @@
addView(mTitleLayout);
}
- public void setTabSelected(int position) {
- ensureTabsExist();
- final int tabCount = mTabLayout.getChildCount();
- for (int i = 0; i < tabCount; i++) {
- final View child = mTabLayout.getChildAt(i);
- child.setSelected(i == position);
- }
- }
-
public void setContextView(ActionBarContextView view) {
mContextView = view;
}
@@ -948,97 +897,6 @@
}
}
- private static class TabView extends LinearLayout {
- private ActionBar.Tab mTab;
- private TextView mTextView;
- private ImageView mIconView;
- private View mCustomView;
-
- public TabView(Context context, ActionBar.Tab tab) {
- super(context, null, com.android.internal.R.attr.actionBarTabStyle);
- mTab = tab;
-
- update();
-
- setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.MATCH_PARENT, 1));
- }
-
- public void update() {
- final ActionBar.Tab tab = mTab;
- final View custom = tab.getCustomView();
- if (custom != null) {
- addView(custom);
- mCustomView = custom;
- if (mTextView != null) mTextView.setVisibility(GONE);
- if (mIconView != null) {
- mIconView.setVisibility(GONE);
- mIconView.setImageDrawable(null);
- }
- } else {
- if (mCustomView != null) {
- removeView(mCustomView);
- mCustomView = null;
- }
-
- final Drawable icon = tab.getIcon();
- final CharSequence text = tab.getText();
-
- if (icon != null) {
- if (mIconView == null) {
- ImageView iconView = new ImageView(getContext());
- LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.CENTER_VERTICAL;
- iconView.setLayoutParams(lp);
- addView(iconView, 0);
- mIconView = iconView;
- }
- mIconView.setImageDrawable(icon);
- mIconView.setVisibility(VISIBLE);
- } else if (mIconView != null) {
- mIconView.setVisibility(GONE);
- mIconView.setImageDrawable(null);
- }
-
- if (text != null) {
- if (mTextView == null) {
- TextView textView = new TextView(getContext(), null,
- com.android.internal.R.attr.actionBarTabTextStyle);
- textView.setSingleLine();
- textView.setEllipsize(TruncateAt.END);
- LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.CENTER_VERTICAL;
- textView.setLayoutParams(lp);
- addView(textView);
- mTextView = textView;
- }
- mTextView.setText(text);
- mTextView.setVisibility(VISIBLE);
- } else {
- mTextView.setVisibility(GONE);
- }
- }
- }
-
- public ActionBar.Tab getTab() {
- return mTab;
- }
- }
-
- private class TabClickListener implements OnClickListener {
- public void onClick(View view) {
- TabView tabView = (TabView) view;
- tabView.getTab().select();
- final int tabCount = mTabLayout.getChildCount();
- for (int i = 0; i < tabCount; i++) {
- final View child = mTabLayout.getChildAt(i);
- child.setSelected(child == view);
- }
- }
- }
-
private static class HomeView extends FrameLayout {
private View mUpView;
private View mIconView;
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
new file mode 100644
index 0000000..c7d37f2
--- /dev/null
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2011 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.android.internal.widget;
+
+import android.app.ActionBar;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils.TruncateAt;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.HorizontalScrollView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class ScrollingTabContainerView extends HorizontalScrollView {
+ Runnable mTabSelector;
+ private TabClickListener mTabClickListener;
+
+ private LinearLayout mTabLayout;
+
+ int mMaxTabWidth;
+
+ public ScrollingTabContainerView(Context context) {
+ super(context);
+ setHorizontalScrollBarEnabled(false);
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ setFillViewport(widthMode == MeasureSpec.EXACTLY);
+
+ final int childCount = getChildCount();
+ if (childCount > 1 &&
+ (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
+ if (childCount > 2) {
+ mMaxTabWidth = (int) (MeasureSpec.getSize(widthMeasureSpec) * 0.4f);
+ } else {
+ mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
+ }
+ } else {
+ mMaxTabWidth = -1;
+ }
+
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ public void setTabSelected(int position) {
+ if (mTabLayout == null) {
+ return;
+ }
+
+ final int tabCount = mTabLayout.getChildCount();
+ for (int i = 0; i < tabCount; i++) {
+ final View child = mTabLayout.getChildAt(i);
+ final boolean isSelected = i == position;
+ child.setSelected(isSelected);
+ if (isSelected) {
+ animateToTab(position);
+ }
+ }
+ }
+
+ public void animateToTab(int position) {
+ final View tabView = mTabLayout.getChildAt(position);
+ if (mTabSelector != null) {
+ removeCallbacks(mTabSelector);
+ }
+ mTabSelector = new Runnable() {
+ public void run() {
+ final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
+ smoothScrollTo(scrollPos, 0);
+ mTabSelector = null;
+ }
+ };
+ post(mTabSelector);
+ }
+
+ public void setTabLayout(LinearLayout tabLayout) {
+ if (mTabLayout != tabLayout) {
+ if (mTabLayout != null) {
+ ((ViewGroup) mTabLayout.getParent()).removeView(mTabLayout);
+ }
+ if (tabLayout != null) {
+ addView(tabLayout);
+ }
+ mTabLayout = tabLayout;
+ }
+ }
+
+ public LinearLayout getTabLayout() {
+ return mTabLayout;
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mTabSelector != null) {
+ removeCallbacks(mTabSelector);
+ }
+ }
+
+ private TabView createTabView(ActionBar.Tab tab) {
+ final TabView tabView = new TabView(getContext(), tab);
+ tabView.setFocusable(true);
+
+ if (mTabClickListener == null) {
+ mTabClickListener = new TabClickListener();
+ }
+ tabView.setOnClickListener(mTabClickListener);
+ return tabView;
+ }
+
+ public void addTab(ActionBar.Tab tab, boolean setSelected) {
+ View tabView = createTabView(tab);
+ mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0,
+ LayoutParams.MATCH_PARENT, 1));
+ if (setSelected) {
+ tabView.setSelected(true);
+ }
+ }
+
+ public void addTab(ActionBar.Tab tab, int position, boolean setSelected) {
+ final TabView tabView = createTabView(tab);
+ mTabLayout.addView(tabView, position, new LinearLayout.LayoutParams(
+ 0, LayoutParams.MATCH_PARENT, 1));
+ if (setSelected) {
+ tabView.setSelected(true);
+ }
+ }
+
+ public void updateTab(int position) {
+ ((TabView) mTabLayout.getChildAt(position)).update();
+ }
+
+ public void removeTabAt(int position) {
+ if (mTabLayout != null) {
+ mTabLayout.removeViewAt(position);
+ }
+ }
+
+ public void removeAllTabs() {
+ if (mTabLayout != null) {
+ mTabLayout.removeAllViews();
+ }
+ }
+
+ private class TabView extends LinearLayout {
+ private ActionBar.Tab mTab;
+ private TextView mTextView;
+ private ImageView mIconView;
+ private View mCustomView;
+
+ public TabView(Context context, ActionBar.Tab tab) {
+ super(context, null, com.android.internal.R.attr.actionBarTabStyle);
+ mTab = tab;
+
+ update();
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ // Re-measure if we went beyond our maximum size.
+ if (mMaxTabWidth > 0 && getMeasuredWidth() > mMaxTabWidth) {
+ super.onMeasure(MeasureSpec.makeMeasureSpec(mMaxTabWidth, MeasureSpec.EXACTLY),
+ heightMeasureSpec);
+ }
+ }
+
+ public void update() {
+ final ActionBar.Tab tab = mTab;
+ final View custom = tab.getCustomView();
+ if (custom != null) {
+ addView(custom);
+ mCustomView = custom;
+ if (mTextView != null) mTextView.setVisibility(GONE);
+ if (mIconView != null) {
+ mIconView.setVisibility(GONE);
+ mIconView.setImageDrawable(null);
+ }
+ } else {
+ if (mCustomView != null) {
+ removeView(mCustomView);
+ mCustomView = null;
+ }
+
+ final Drawable icon = tab.getIcon();
+ final CharSequence text = tab.getText();
+
+ if (icon != null) {
+ if (mIconView == null) {
+ ImageView iconView = new ImageView(getContext());
+ LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ lp.gravity = Gravity.CENTER_VERTICAL;
+ iconView.setLayoutParams(lp);
+ addView(iconView, 0);
+ mIconView = iconView;
+ }
+ mIconView.setImageDrawable(icon);
+ mIconView.setVisibility(VISIBLE);
+ } else if (mIconView != null) {
+ mIconView.setVisibility(GONE);
+ mIconView.setImageDrawable(null);
+ }
+
+ if (text != null) {
+ if (mTextView == null) {
+ TextView textView = new TextView(getContext(), null,
+ com.android.internal.R.attr.actionBarTabTextStyle);
+ textView.setSingleLine();
+ textView.setEllipsize(TruncateAt.END);
+ LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ lp.gravity = Gravity.CENTER_VERTICAL;
+ textView.setLayoutParams(lp);
+ addView(textView);
+ mTextView = textView;
+ }
+ mTextView.setText(text);
+ mTextView.setVisibility(VISIBLE);
+ } else {
+ mTextView.setVisibility(GONE);
+ }
+ }
+ }
+
+ public ActionBar.Tab getTab() {
+ return mTab;
+ }
+ }
+
+ private class TabClickListener implements OnClickListener {
+ public void onClick(View view) {
+ TabView tabView = (TabView) view;
+ tabView.getTab().select();
+ final int tabCount = mTabLayout.getChildCount();
+ for (int i = 0; i < tabCount; i++) {
+ final View child = mTabLayout.getChildAt(i);
+ child.setSelected(child == view);
+ }
+ }
+ }
+}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index ebb70e3..c1e81c3 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4913,9 +4913,6 @@
<!-- Specifies padding that should be applied to the left and right sides of
system-provided items in the bar. -->
<attr name="itemPadding" format="dimension" />
- <!-- Specifies whether tabs should be embedded within the bar itself (true)
- or displayed elsewhere (false). -->
- <attr name="embeddedTabs" format="boolean" />
</declare-styleable>
<declare-styleable name="ActionMode">
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 26b5d95..e95094f0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1078,7 +1078,6 @@
<item name="android:progressBarStyle">@android:style/Widget.ProgressBar.Horizontal</item>
<item name="android:indeterminateProgressStyle">@android:style/Widget.ProgressBar.Small</item>
<item name="android:homeLayout">@android:layout/action_bar_home</item>
- <item name="android:embeddedTabs">@android:bool/action_bar_embed_tabs</item>
</style>
<style name="Widget.ActionMode">
@@ -1122,6 +1121,7 @@
</style>
<style name="Widget.ActionBarView_TabView">
+ <item name="android:gravity">center_horizontal</item>
<item name="android:background">@drawable/minitab_lt</item>
<item name="android:paddingLeft">4dip</item>
<item name="android:paddingRight">4dip</item>
@@ -1795,6 +1795,9 @@
</style>
<style name="Widget.Holo.ActionBarView_TabBar" parent="Widget.ActionBarView_TabBar">
+ <item name="android:divider">?android:attr/dividerVertical</item>
+ <item name="android:showDividers">middle</item>
+ <item name="android:dividerPadding">8dip</item>
</style>
<style name="Widget.Holo.ActionBarView_TabText" parent="Widget.ActionBarView_TabText">