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 Attwell 17429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellpackage com.android.contacts.common.list; 18429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 19429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.content.Context; 20429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.content.res.Resources; 21429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.graphics.Canvas; 22429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.graphics.Paint; 23429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.util.AttributeSet; 24429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.view.View; 25429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport android.widget.LinearLayout; 26429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 27429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellimport com.android.contacts.common.R; 28429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 29429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwellpublic class ViewPagerTabStrip extends LinearLayout { 30429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private int mSelectedUnderlineThickness; 31429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private final Paint mSelectedUnderlinePaint; 32429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 33429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private int mIndexForSelection; 34429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell private float mSelectionOffset; 35429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 36429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public ViewPagerTabStrip(Context context) { 37429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell this(context, null); 38429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 39429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 40429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell public ViewPagerTabStrip(Context context, AttributeSet attrs) { 41429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell super(context, attrs); 42429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 43429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell final Resources res = context.getResources(); 44429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 45429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mSelectedUnderlineThickness = 46429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell res.getDimensionPixelSize(R.dimen.tab_selected_underline_height); 47429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int underlineColor = res.getColor(R.color.tab_selected_underline_color); 48429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int backgroundColor = res.getColor(R.color.actionbar_background_color); 49429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 50429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mSelectedUnderlinePaint = new Paint(); 51429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mSelectedUnderlinePaint.setColor(underlineColor); 52429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 53429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell setBackgroundColor(backgroundColor); 54429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell setWillNotDraw(false); 55429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 56429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 57429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell /** 58429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * Notifies this view that view pager has been scrolled. We save the tab index 59429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * and selection offset for interpolating the position and width of selection 60429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell * underline. 61429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell */ 62429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 63429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mIndexForSelection = position; 64429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell mSelectionOffset = positionOffset; 65429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell invalidate(); 66429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 67429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 68429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell @Override 69429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell protected void onDraw(Canvas canvas) { 70429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int childCount = getChildCount(); 71429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 72429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell // Thick colored underline below the current selection 73429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell if (childCount > 0) { 74429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell View selectedTitle = getChildAt(mIndexForSelection); 75d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee 76d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee if (selectedTitle == null) { 77d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee // The view pager's tab count changed but we weren't notified yet. Ignore this draw 78d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee // pass, when we get a new selection we will update and draw the selection strip in 79d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee // the correct place. 80d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee return; 81d87801db55f135fd8390105973f0df3fcd5b6a1bYorke Lee } 82429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int selectedLeft = selectedTitle.getLeft(); 83429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int selectedRight = selectedTitle.getRight(); 844d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee final boolean isRtl = isRtl(); 854d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee final boolean hasNextTab = isRtl ? mIndexForSelection > 0 864d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee : (mIndexForSelection < (getChildCount() - 1)); 874d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee if ((mSelectionOffset > 0.0f) && hasNextTab) { 88429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell // Draw the selection partway between the tabs 894d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee View nextTitle = getChildAt(mIndexForSelection + (isRtl ? -1 : 1)); 90429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int nextLeft = nextTitle.getLeft(); 91429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int nextRight = nextTitle.getRight(); 92429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 93429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell selectedLeft = (int) (mSelectionOffset * nextLeft + 94429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell (1.0f - mSelectionOffset) * selectedLeft); 95429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell selectedRight = (int) (mSelectionOffset * nextRight + 96429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell (1.0f - mSelectionOffset) * selectedRight); 97429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 98429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell 99429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell int height = getHeight(); 100429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell canvas.drawRect(selectedLeft, height - mSelectedUnderlineThickness, 101429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell selectedRight, height, mSelectedUnderlinePaint); 102429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 103429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell } 1044d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee 1054d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee private boolean isRtl() { 1064d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; 1074d0ec405721176fcbf4c70bade5d34da68d523c3Yorke Lee } 108429302fd99805fc6d88e974335289e22ff59c1eeBrian Attwell}