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