TabScrollView.java revision fe25199a6f975c67d28afcc1de56b0f987b66cd8
1fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb/*
2fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * Copyright (C) 2010 The Android Open Source Project
3fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *
4fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
5fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * you may not use this file except in compliance with the License.
6fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * You may obtain a copy of the License at
7fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *
8fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
9fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb *
10fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * Unless required by applicable law or agreed to in writing, software
11fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
12fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * See the License for the specific language governing permissions and
14fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * limitations under the License.
15fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb */
16fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
17fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbpackage com.android.browser;
18fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
19fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.content.Context;
20fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.util.AttributeSet;
21fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.view.View;
22fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.widget.HorizontalScrollView;
23fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbimport android.widget.LinearLayout;
24fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
25fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb/**
26fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb * custom view for displaying tabs in the tabbed title bar
27fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb */
28fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolbpublic class TabScrollView extends HorizontalScrollView {
29fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
30fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private Context mContext;
31fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
32fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private LinearLayout mContentView;
33fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
34fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private int mSelected;
35fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
36fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    /**
37fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     * @param context
38fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     * @param attrs
39fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     * @param defStyle
40fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     */
41fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    public TabScrollView(Context context, AttributeSet attrs, int defStyle) {
42fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        super(context, attrs, defStyle);
43fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        init(context);
44fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
45fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
46fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    /**
47fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     * @param context
48fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     * @param attrs
49fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     */
50fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    public TabScrollView(Context context, AttributeSet attrs) {
51fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        super(context, attrs);
52fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        init(context);
53fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
54fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
55fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    /**
56fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     * @param context
57fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb     */
58fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    public TabScrollView(Context context) {
59fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        super(context);
60fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        init(context);
61fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
62fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
63fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    private void init(Context ctx) {
64fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContext = ctx;
65fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        setHorizontalScrollBarEnabled(false);
66fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView = new LinearLayout(mContext);
67fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView.setOrientation(LinearLayout.HORIZONTAL);
68fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
69fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb                LayoutParams.WRAP_CONTENT));
70fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        addView(mContentView);
71fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mSelected = -1;
72fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
73fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
74fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    @Override
75fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
76fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        super.onLayout(changed, left, top, right, bottom);
77fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        ensureChildVisible(getSelectedTab());
78fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
79fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
80fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    void setSelectedTab(int position) {
81fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        View v = getSelectedTab();
82fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        if (v != null) {
83fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            v.setSelected(false);
84fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        }
85fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mSelected = position;
86fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        v = getSelectedTab();
87fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        if (v != null) {
88fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            v.setSelected(true);
89fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        }
90fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        requestLayout();
91fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
92fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
93fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    View getSelectedTab() {
94fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        if ((mSelected >= 0) && (mSelected < mContentView.getChildCount())) {
95fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            return mContentView.getChildAt(mSelected);
96fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        } else {
97fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            return null;
98fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        }
99fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
100fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
101fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    void clearTabs() {
102fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView.removeAllViews();
103fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
104fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
105fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    void addTab(View tab) {
106fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView.addView(tab);
107fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        tab.setSelected(false);
108fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
109fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
110fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    void addTab(View tab, int pos) {
111fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView.addView(tab, pos);
112fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        tab.setSelected(false);
113fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
114fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
115fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    void removeTab(View tab) {
116fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        mContentView.removeView(tab);
117fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
118fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
119fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    void ensureChildVisible(View child) {
120fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        if (child != null) {
121fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            int childl = child.getLeft();
122fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            int childr = childl + child.getWidth();
123fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            int viewl = getScrollX();
124fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            int viewr = viewl + getWidth();
125fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            if (childl < viewl) {
126fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb                // need scrolling to left
127fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb                scrollTo(childl, 0);
128fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            } else if (childr > viewr) {
129fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb                // need scrolling to right
130fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb                scrollTo(childr - viewr + viewl, 0);
131fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb            }
132fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb        }
133fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb    }
134fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
135fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb
136fe25199a6f975c67d28afcc1de56b0f987b66cd8Michael Kolb}
137