ScrollingTabContainerView.java revision faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3
1f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell/* 2f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * Copyright (C) 2011 The Android Open Source Project 3f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * 4f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * you may not use this file except in compliance with the License. 6f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * You may obtain a copy of the License at 7f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * 8f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 9f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * 10f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * Unless required by applicable law or agreed to in writing, software 11f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * See the License for the specific language governing permissions and 14f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell * limitations under the License. 15f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell */ 16f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellpackage com.android.internal.widget; 17f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 18faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powellimport com.android.internal.R; 19faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell 20f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powellimport android.animation.Animator; 21f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powellimport android.animation.ObjectAnimator; 22f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powellimport android.animation.TimeInterpolator; 23f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.app.ActionBar; 24f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.content.Context; 25faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powellimport android.content.res.Configuration; 26faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powellimport android.content.res.TypedArray; 27f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.graphics.drawable.Drawable; 28f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.text.TextUtils.TruncateAt; 29f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.view.Gravity; 30f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.view.View; 31f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.view.ViewGroup; 32f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powellimport android.view.animation.DecelerateInterpolator; 33f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.widget.HorizontalScrollView; 34f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.widget.ImageView; 35f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.widget.LinearLayout; 36f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellimport android.widget.TextView; 37f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 38f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powellpublic class ScrollingTabContainerView extends HorizontalScrollView { 39f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell Runnable mTabSelector; 40f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private TabClickListener mTabClickListener; 41f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 42f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private LinearLayout mTabLayout; 43f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 44f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell int mMaxTabWidth; 45f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 46f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell protected Animator mVisibilityAnim; 47f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener(); 48f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 49f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell private static final TimeInterpolator sAlphaInterpolator = new DecelerateInterpolator(); 50f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 51f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell private static final int FADE_DURATION = 200; 52f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 53f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public ScrollingTabContainerView(Context context) { 54f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell super(context); 55f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell setHorizontalScrollBarEnabled(false); 56f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 57f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 58f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell @Override 59f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 60f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 61f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell setFillViewport(widthMode == MeasureSpec.EXACTLY); 62f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 63f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final int childCount = getChildCount(); 64f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (childCount > 1 && 65f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) { 66f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (childCount > 2) { 67f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mMaxTabWidth = (int) (MeasureSpec.getSize(widthMeasureSpec) * 0.4f); 68f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } else { 69f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2; 70f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 71f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } else { 72f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mMaxTabWidth = -1; 73f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 74f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 75f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell super.onMeasure(widthMeasureSpec, heightMeasureSpec); 76f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 77f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 78f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void setTabSelected(int position) { 79f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabLayout == null) { 80f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell return; 81f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 82f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 83f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final int tabCount = mTabLayout.getChildCount(); 84f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell for (int i = 0; i < tabCount; i++) { 85f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final View child = mTabLayout.getChildAt(i); 86f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final boolean isSelected = i == position; 87f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell child.setSelected(isSelected); 88f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (isSelected) { 89f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell animateToTab(position); 90f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 91f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 92f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 93f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 9445c0b1954d7dfa6e2590ed76b915a98ae971414cAdam Powell public void setContentHeight(int contentHeight) { 9545c0b1954d7dfa6e2590ed76b915a98ae971414cAdam Powell mTabLayout.getLayoutParams().height = contentHeight; 9645c0b1954d7dfa6e2590ed76b915a98ae971414cAdam Powell requestLayout(); 9745c0b1954d7dfa6e2590ed76b915a98ae971414cAdam Powell } 9845c0b1954d7dfa6e2590ed76b915a98ae971414cAdam Powell 99faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell @Override 100faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell protected void onConfigurationChanged(Configuration newConfig) { 101faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell super.onConfigurationChanged(newConfig); 102faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell 103faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell // Action bar can change size on configuration changes. 104faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell // Reread the desired height from the theme-specified style. 105faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar, 106faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell com.android.internal.R.attr.actionBarStyle, 0); 107faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0)); 108faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell a.recycle(); 109faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell } 110faa6ffa484f6f2a334c8bf2c7a9dc693a61608f3Adam Powell 111f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell public void animateToVisibility(int visibility) { 112f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell if (mVisibilityAnim != null) { 113f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell mVisibilityAnim.cancel(); 114f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 115f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell if (visibility == VISIBLE) { 116f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell if (getVisibility() != VISIBLE) { 117f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell setAlpha(0); 118f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 119f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 1); 120f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.setDuration(FADE_DURATION); 121f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.setInterpolator(sAlphaInterpolator); 122f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 123f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); 124f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.start(); 125f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } else { 126f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell ObjectAnimator anim = ObjectAnimator.ofFloat(this, "alpha", 0); 127f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.setDuration(FADE_DURATION); 128f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.setInterpolator(sAlphaInterpolator); 129f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 130f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.addListener(mVisAnimListener.withFinalVisibility(visibility)); 131f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell anim.start(); 132f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 133f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 134f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 135f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void animateToTab(int position) { 136f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final View tabView = mTabLayout.getChildAt(position); 137f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabSelector != null) { 138f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell removeCallbacks(mTabSelector); 139f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 140f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabSelector = new Runnable() { 141f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void run() { 142f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2; 143f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell smoothScrollTo(scrollPos, 0); 144f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabSelector = null; 145f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 146f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell }; 147f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell post(mTabSelector); 148f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 149f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 150f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void setTabLayout(LinearLayout tabLayout) { 151f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabLayout != tabLayout) { 152f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabLayout != null) { 153f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell ((ViewGroup) mTabLayout.getParent()).removeView(mTabLayout); 154f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 155f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (tabLayout != null) { 156f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell addView(tabLayout); 157f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 158f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabLayout = tabLayout; 159f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 160f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 161f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 162f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public LinearLayout getTabLayout() { 163f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell return mTabLayout; 164f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 165f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 166f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell @Override 167f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void onDetachedFromWindow() { 168f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell super.onDetachedFromWindow(); 169f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabSelector != null) { 170f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell removeCallbacks(mTabSelector); 171f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 172f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 173f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 174f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private TabView createTabView(ActionBar.Tab tab) { 175f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final TabView tabView = new TabView(getContext(), tab); 176f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell tabView.setFocusable(true); 177f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 178f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabClickListener == null) { 179f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabClickListener = new TabClickListener(); 180f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 181f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell tabView.setOnClickListener(mTabClickListener); 182f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell return tabView; 183f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 184f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 185f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void addTab(ActionBar.Tab tab, boolean setSelected) { 186f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell View tabView = createTabView(tab); 187f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, 188f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell LayoutParams.MATCH_PARENT, 1)); 189f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (setSelected) { 190f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell tabView.setSelected(true); 191f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 192f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 193f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 194f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void addTab(ActionBar.Tab tab, int position, boolean setSelected) { 195f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final TabView tabView = createTabView(tab); 196f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabLayout.addView(tabView, position, new LinearLayout.LayoutParams( 197f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 0, LayoutParams.MATCH_PARENT, 1)); 198f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (setSelected) { 199f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell tabView.setSelected(true); 200f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 201f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 202f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 203f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void updateTab(int position) { 204f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell ((TabView) mTabLayout.getChildAt(position)).update(); 205f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 206f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 207f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void removeTabAt(int position) { 208f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabLayout != null) { 209f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabLayout.removeViewAt(position); 210f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 211f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 212f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 213f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void removeAllTabs() { 214f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTabLayout != null) { 215f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTabLayout.removeAllViews(); 216f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 217f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 218f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 219f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private class TabView extends LinearLayout { 220f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private ActionBar.Tab mTab; 221f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private TextView mTextView; 222f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private ImageView mIconView; 223f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private View mCustomView; 224f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 225f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public TabView(Context context, ActionBar.Tab tab) { 226f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell super(context, null, com.android.internal.R.attr.actionBarTabStyle); 227f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTab = tab; 228f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 229f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell update(); 230f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 231f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 232f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell @Override 233f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 234f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell super.onMeasure(widthMeasureSpec, heightMeasureSpec); 235f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 236f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell // Re-measure if we went beyond our maximum size. 237f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mMaxTabWidth > 0 && getMeasuredWidth() > mMaxTabWidth) { 238f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell super.onMeasure(MeasureSpec.makeMeasureSpec(mMaxTabWidth, MeasureSpec.EXACTLY), 239f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell heightMeasureSpec); 240f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 241f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 242f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 243f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void update() { 244f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final ActionBar.Tab tab = mTab; 245f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final View custom = tab.getCustomView(); 246f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (custom != null) { 247f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell addView(custom); 248f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mCustomView = custom; 249f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTextView != null) mTextView.setVisibility(GONE); 250f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mIconView != null) { 251f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView.setVisibility(GONE); 252f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView.setImageDrawable(null); 253f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 254f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } else { 255f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mCustomView != null) { 256f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell removeView(mCustomView); 257f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mCustomView = null; 258f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 259f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 260f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final Drawable icon = tab.getIcon(); 261f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final CharSequence text = tab.getText(); 262f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 263f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (icon != null) { 264f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mIconView == null) { 265f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell ImageView iconView = new ImageView(getContext()); 266f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, 267f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell LayoutParams.WRAP_CONTENT); 268f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell lp.gravity = Gravity.CENTER_VERTICAL; 269f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell iconView.setLayoutParams(lp); 270f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell addView(iconView, 0); 271f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView = iconView; 272f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 273f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView.setImageDrawable(icon); 274f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView.setVisibility(VISIBLE); 275f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } else if (mIconView != null) { 276f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView.setVisibility(GONE); 277f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mIconView.setImageDrawable(null); 278f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 279f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 280f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (text != null) { 281f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell if (mTextView == null) { 282f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell TextView textView = new TextView(getContext(), null, 283f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell com.android.internal.R.attr.actionBarTabTextStyle); 284f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell textView.setEllipsize(TruncateAt.END); 285f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, 286f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell LayoutParams.WRAP_CONTENT); 287f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell lp.gravity = Gravity.CENTER_VERTICAL; 288f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell textView.setLayoutParams(lp); 289f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell addView(textView); 290f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTextView = textView; 291f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 292f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTextView.setText(text); 293f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTextView.setVisibility(VISIBLE); 294251df77861525cca79d38bcee7c45c16c6752e40Adam Powell } else if (mTextView != null) { 295f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell mTextView.setVisibility(GONE); 296251df77861525cca79d38bcee7c45c16c6752e40Adam Powell mTextView.setText(null); 297f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 298f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 299f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 300f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 301f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public ActionBar.Tab getTab() { 302f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell return mTab; 303f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 304f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 305f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell 306f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell private class TabClickListener implements OnClickListener { 307f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell public void onClick(View view) { 308f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell TabView tabView = (TabView) view; 309f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell tabView.getTab().select(); 310f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final int tabCount = mTabLayout.getChildCount(); 311f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell for (int i = 0; i < tabCount; i++) { 312f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell final View child = mTabLayout.getChildAt(i); 313f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell child.setSelected(child == view); 314f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 315f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 316f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell } 317f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 318f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell protected class VisibilityAnimListener implements Animator.AnimatorListener { 319f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell private boolean mCanceled = false; 320f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell private int mFinalVisibility; 321f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 322f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell public VisibilityAnimListener withFinalVisibility(int visibility) { 323f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell mFinalVisibility = visibility; 324f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell return this; 325f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 326f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 327f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell @Override 328f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell public void onAnimationStart(Animator animation) { 329f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell setVisibility(VISIBLE); 330f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell mVisibilityAnim = animation; 331f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell mCanceled = false; 332f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 333f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 334f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell @Override 335f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell public void onAnimationEnd(Animator animation) { 336f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell if (mCanceled) return; 337f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 338f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell mVisibilityAnim = null; 339f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell setVisibility(mFinalVisibility); 340f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 341f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 342f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell @Override 343f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell public void onAnimationCancel(Animator animation) { 344f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell mCanceled = true; 345f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 346f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell 347f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell @Override 348f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell public void onAnimationRepeat(Animator animation) { 349f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 350f6ce6a9bacbb220c6ea7b552c481237f23e64ae7Adam Powell } 351f8ac6b7394cfd37f01471bb35475ff2930eee140Adam Powell} 352