1429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell/* 2429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Copyright (C) 2014 The Android Open Source Project 3429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * 4429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Licensed under the Apache License, Version 2.0 (the "License"); 5429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * you may not use this file except in compliance with the License. 6429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * You may obtain a copy of the License at 7429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * 8429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * http://www.apache.org/licenses/LICENSE-2.0 9429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * 10429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Unless required by applicable law or agreed to in writing, software 11429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * distributed under the License is distributed on an "AS IS" BASIS, 12429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * See the License for the specific language governing permissions and 14429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * limitations under the License. 15429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell */ 16429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellpackage com.android.contacts.common.list; 17429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 18429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.content.Context; 19429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.content.res.ColorStateList; 20429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.content.res.TypedArray; 21429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.graphics.Outline; 22429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.support.v4.view.PagerAdapter; 23429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.support.v4.view.ViewPager; 24429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.util.AttributeSet; 25429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.util.TypedValue; 26429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.view.Gravity; 273a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chenimport android.view.LayoutInflater; 28429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.view.View; 29429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.view.ViewOutlineProvider; 30429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.widget.FrameLayout; 31429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.widget.HorizontalScrollView; 32429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.widget.LinearLayout; 33429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.widget.TextView; 34429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.widget.Toast; 35429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 36429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport com.android.contacts.common.R; 37e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wangimport com.android.contacts.common.compat.CompatUtils; 38429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 39429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell/** 40429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Lightweight implementation of ViewPager tabs. This looks similar to traditional actionBar tabs, 41429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * but allows for the view containing the tabs to be placed anywhere on screen. Text-related 42429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * attributes can also be assigned in XML - these will get propogated to the child TextViews 43429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * automatically. 44429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell */ 45429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellpublic class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener { 46429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 47429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell ViewPager mPager; 48429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private ViewPagerTabStrip mTabStrip; 49429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 50429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell /** 51429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Linearlayout that will contain the TextViews serving as tabs. This is the only child 52429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * of the parent HorizontalScrollView. 53429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell */ 54429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int mTextStyle; 55429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final ColorStateList mTextColor; 56429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int mTextSize; 57429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final boolean mTextAllCaps; 58429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int mPrevSelected = -1; 59429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int mSidePadding; 60429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 6107ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee private int[] mTabIcons; 623a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen // For displaying the unread count next to the tab icon. 633a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen private int[] mUnreadCounts; 6407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee 65e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang private static final ViewOutlineProvider VIEW_BOUNDS_OUTLINE_PROVIDER; 66e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang static { 67e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang if (CompatUtils.isLollipopCompatible()) { 68e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang VIEW_BOUNDS_OUTLINE_PROVIDER = new ViewOutlineProvider() { 69e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang @Override 70e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang public void getOutline(View view, Outline outline) { 71e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang outline.setRect(0, 0, view.getWidth(), view.getHeight()); 72e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 73e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang }; 74e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } else { 75e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang VIEW_BOUNDS_OUTLINE_PROVIDER = null; 76429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 77e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 78429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 79429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private static final int TAB_SIDE_PADDING_IN_DPS = 10; 80429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 81429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell // TODO: This should use <declare-styleable> in the future 82429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private static final int[] ATTRS = new int[] { 83429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell android.R.attr.textSize, 84429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell android.R.attr.textStyle, 85429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell android.R.attr.textColor, 86429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell android.R.attr.textAllCaps 87429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell }; 88429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 89429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell /** 90429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Simulates actionbar tab behavior by showing a toast with the tab title when long clicked. 91429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell */ 92429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private class OnTabLongClickListener implements OnLongClickListener { 93429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int mPosition; 94429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 95429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public OnTabLongClickListener(int position) { 96429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mPosition = position; 97429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 98429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 99429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell @Override 100429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public boolean onLongClick(View v) { 101429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int[] screenPos = new int[2]; 102429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell getLocationOnScreen(screenPos); 103429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 104429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final Context context = getContext(); 105429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int width = getWidth(); 106429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int height = getHeight(); 107429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; 108429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 109429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell Toast toast = Toast.makeText(context, mPager.getAdapter().getPageTitle(mPosition), 110429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell Toast.LENGTH_SHORT); 111429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 112429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell // Show the toast under the tab 113429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell toast.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 114429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell (screenPos[0] + width / 2) - screenWidth / 2, screenPos[1] + height); 115429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 116429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell toast.show(); 117429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell return true; 118429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 119429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 120429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 121429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public ViewPagerTabs(Context context) { 122429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell this(context, null); 123429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 124429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 125429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public ViewPagerTabs(Context context, AttributeSet attrs) { 126429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell this(context, attrs, 0); 127429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 128429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 129429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public ViewPagerTabs(Context context, AttributeSet attrs, int defStyle) { 130429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell super(context, attrs, defStyle); 131429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell setFillViewport(true); 132429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 133429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mSidePadding = (int) (getResources().getDisplayMetrics().density * TAB_SIDE_PADDING_IN_DPS); 134429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 135429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); 136429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTextSize = a.getDimensionPixelSize(0, 0); 137429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTextStyle = a.getInt(1, 0); 138429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTextColor = a.getColorStateList(2); 139429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTextAllCaps = a.getBoolean(3, false); 140429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 141429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTabStrip = new ViewPagerTabStrip(context); 142429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell addView(mTabStrip, 143429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)); 144429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell a.recycle(); 145429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 146e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang if (CompatUtils.isLollipopCompatible()) { 147e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang // enable shadow casting from view bounds 148e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang setOutlineProvider(VIEW_BOUNDS_OUTLINE_PROVIDER); 149e0bb103a1403d3657cafb27cda6dc6b5fb1d5462Wenyi Wang } 150429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 151429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 152429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public void setViewPager(ViewPager viewPager) { 153429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mPager = viewPager; 154429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell addTabs(mPager.getAdapter()); 155429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 156429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 1573a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen /** 1583a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen * Set the tab icons and initialize an array for unread counts the same length as the icon 1593a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen * array. 1603a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen * 1613a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen * @param tabIcons An array representing the tab icons in order. 1623a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen */ 1633a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen public void configureTabIcons(int[] tabIcons) { 16407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee mTabIcons = tabIcons; 1653a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen mUnreadCounts = new int[tabIcons.length]; 1663a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen } 1673a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen 1683a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen public void setUnreadCount(int count, int position) { 1693a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen if (mUnreadCounts == null || position >= mUnreadCounts.length) { 1703a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen return; 1713a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen } 1723a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen mUnreadCounts[position] = count; 17307ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee } 17407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee 175429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private void addTabs(PagerAdapter adapter) { 176429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTabStrip.removeAllViews(); 177429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 178429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int count = adapter.getCount(); 179429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell for (int i = 0; i < count; i++) { 180429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell addTab(adapter.getPageTitle(i), i); 181429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 182429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 183429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 184429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private void addTab(CharSequence tabTitle, final int position) { 18507ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee View tabView; 18607ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee if (mTabIcons != null && position < mTabIcons.length) { 1873a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen View layout = LayoutInflater.from(getContext()).inflate( 1883a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen R.layout.unread_count_tab, null); 1893a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen View iconView = layout.findViewById(R.id.icon); 19007ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee iconView.setBackgroundResource(mTabIcons[position]); 19107ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee iconView.setContentDescription(tabTitle); 1923a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen TextView textView = (TextView) layout.findViewById(R.id.count); 1933a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen if (mUnreadCounts != null && mUnreadCounts[position] > 0) { 1943a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen textView.setText(Integer.toString(mUnreadCounts[position])); 1953a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen textView.setVisibility(View.VISIBLE); 196d7f41e603111e0651979b98306e912eec5d4a569Nancy Chen iconView.setContentDescription(getResources().getQuantityString( 197d7f41e603111e0651979b98306e912eec5d4a569Nancy Chen R.plurals.tab_title_with_unread_items, 198d7f41e603111e0651979b98306e912eec5d4a569Nancy Chen mUnreadCounts[position], 199d7f41e603111e0651979b98306e912eec5d4a569Nancy Chen tabTitle.toString(), 200d7f41e603111e0651979b98306e912eec5d4a569Nancy Chen mUnreadCounts[position])); 2013a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen } else { 2023a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen textView.setVisibility(View.INVISIBLE); 203d7f41e603111e0651979b98306e912eec5d4a569Nancy Chen iconView.setContentDescription(tabTitle); 2043a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen } 2053a20bedbe63d3a92391aca2429a5a5e5c4f165c5Nancy Chen tabView = layout; 20607ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee } else { 20707ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee final TextView textView = new TextView(getContext()); 20807ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setText(tabTitle); 20907ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setBackgroundResource(R.drawable.view_pager_tab_background); 21007ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee 21107ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee // Assign various text appearance related attributes to child views. 21207ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee if (mTextStyle > 0) { 21307ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setTypeface(textView.getTypeface(), mTextStyle); 21407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee } 21507ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee if (mTextSize > 0) { 21607ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); 21707ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee } 21807ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee if (mTextColor != null) { 21907ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setTextColor(mTextColor); 22007ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee } 22107ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setAllCaps(mTextAllCaps); 22207ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee textView.setGravity(Gravity.CENTER); 22307ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee 22407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee tabView = textView; 22507ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee } 22607ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee 22707ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee tabView.setOnClickListener(new OnClickListener() { 228429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell @Override 229429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public void onClick(View v) { 2304d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee mPager.setCurrentItem(getRtlPosition(position)); 231429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 232429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell }); 233429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 23407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee tabView.setOnLongClickListener(new OnTabLongClickListener(position)); 235429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 23607ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee tabView.setPadding(mSidePadding, 0, mSidePadding, 0); 237d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen 238d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen mTabStrip.addView(tabView, position, new LinearLayout.LayoutParams( 239d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1)); 24007ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee 241429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell // Default to the first child being selected 242429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell if (position == 0) { 243429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mPrevSelected = 0; 24407ddd3016f4db8de95636a1c7eabf5ebf6813ddbAndrew Lee tabView.setSelected(true); 245429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 246429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 247429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 248d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen /** 24956dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen * Remove a tab at a certain index. 25056dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen * 25156dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen * @param index The index of the tab view we wish to remove. 25256dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen */ 25356dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen public void removeTab(int index) { 25456dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen View view = mTabStrip.getChildAt(index); 25556dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen if (view != null) { 25656dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen mTabStrip.removeView(view); 25756dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen } 25856dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen } 25956dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen 26056dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen /** 261d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen * Refresh a tab at a certain index by removing it and reconstructing it. 262d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen * 263d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen * @param index The index of the tab view we wish to update. 264d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen */ 265d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen public void updateTab(int index) { 26656dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen removeTab(index); 26756dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen 26856dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen if (index < mPager.getAdapter().getCount()) { 26956dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen addTab(mPager.getAdapter().getPageTitle(index), index); 27056dd74c1da68a61aa33ed2a5b75505424e748184Nancy Chen } 271d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen } 272d6ffb82e7684ea4a5caa9313d9bfc87980cadc91Nancy Chen 273429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell @Override 274429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 2754d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee position = getRtlPosition(position); 276429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int tabStripChildCount = mTabStrip.getChildCount(); 277429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) { 278429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell return; 279429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 280429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 281429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTabStrip.onPageScrolled(position, positionOffset, positionOffsetPixels); 282429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 283429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 284429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell @Override 285429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public void onPageSelected(int position) { 2864d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee position = getRtlPosition(position); 28764355c717f4f739baae02d347744cfcc577ffe0bJay Shrauner int tabStripChildCount = mTabStrip.getChildCount(); 28864355c717f4f739baae02d347744cfcc577ffe0bJay Shrauner if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) { 28964355c717f4f739baae02d347744cfcc577ffe0bJay Shrauner return; 29064355c717f4f739baae02d347744cfcc577ffe0bJay Shrauner } 29164355c717f4f739baae02d347744cfcc577ffe0bJay Shrauner 29264355c717f4f739baae02d347744cfcc577ffe0bJay Shrauner if (mPrevSelected >= 0 && mPrevSelected < tabStripChildCount) { 293429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mTabStrip.getChildAt(mPrevSelected).setSelected(false); 294429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 295429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final View selectedChild = mTabStrip.getChildAt(position); 296429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell selectedChild.setSelected(true); 297429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 298429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell // Update scroll position 299429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2; 300429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell smoothScrollTo(scrollPos, 0); 301429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mPrevSelected = position; 302429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 303429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 304429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell @Override 305429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public void onPageScrollStateChanged(int state) { 306429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 3074d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee 3084d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee private int getRtlPosition(int position) { 3094d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 3104d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee return mTabStrip.getChildCount() - 1 - position; 3114d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee } 3124d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee return position; 3134d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee } 314429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell} 315429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 316