summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lee <anwlee@google.com>2014-05-29 17:55:49 -0700
committerAndrew Lee <anwlee@google.com>2014-05-30 10:17:35 -0700
commit7d164bbbe5f93dc3447c1d7931aea97f092677ad (patch)
treeeef57d78e97c03aac106cdffafe673564ae85c14
parent09a4b071d8efcccb5ec620602a9c0dd63836f46a (diff)
downloadpackages_apps_Dialer-7d164bbbe5f93dc3447c1d7931aea97f092677ad.tar.gz
packages_apps_Dialer-7d164bbbe5f93dc3447c1d7931aea97f092677ad.tar.bz2
packages_apps_Dialer-7d164bbbe5f93dc3447c1d7931aea97f092677ad.zip
Add dynamically scrolling underline to view pager tabs.
- Implementation is lifted and simplified from Play Store's implementation of PlayTabContainer and PlayTabStrip (see links in bug) - Replace mChild in ViewPagerTabs with the TabStrip. - Add new transparent background (with ripple) for tabs. - Restyle tab thickness (to 2dp) and color (to yellow) accent.. Bug: 15167378 Change-Id: I50136294a7210ead67553a82916fd09d52077860
-rw-r--r--res/drawable/view_pager_tab_background.xml25
-rw-r--r--res/values/colors.xml4
-rw-r--r--src/com/android/dialer/list/ViewPagerTabStrip.java105
-rw-r--r--src/com/android/dialer/list/ViewPagerTabs.java26
4 files changed, 151 insertions, 9 deletions
diff --git a/res/drawable/view_pager_tab_background.xml b/res/drawable/view_pager_tab_background.xml
new file mode 100644
index 000000000..7dae671ad
--- /dev/null
+++ b/res/drawable/view_pager_tab_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:tint="@color/tab_ripple_color">
+ <item>
+ <selector>
+ <item android:state_focused="true"
+ android:drawable="@drawable/tab_unselected_focused" />
+ </selector>
+ </item>
+</ripple> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index c79f4cff4..8bba479c7 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -100,6 +100,8 @@
<!-- Color for icons in the actionbar -->
<color name="actionbar_icon_color">#ffffff</color>
- <!-- 10% opacity, theme color. -->
<color name="dialer_dialpad_touch_tint">#1a1dc7db</color>
+
+ <color name="tab_ripple_color">@color/dialer_accent_color</color>
+ <color name="tab_selected_underline_color">@color/dialer_accent_color</color>
</resources>
diff --git a/src/com/android/dialer/list/ViewPagerTabStrip.java b/src/com/android/dialer/list/ViewPagerTabStrip.java
new file mode 100644
index 000000000..ac16694b3
--- /dev/null
+++ b/src/com/android/dialer/list/ViewPagerTabStrip.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.list;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.dialer.R;
+
+public class ViewPagerTabStrip extends LinearLayout {
+ private int mSelectedUnderlineThickness;
+ private final Paint mSelectedUnderlinePaint;
+
+ private int mIndexForSelection;
+ private float mSelectionOffset;
+
+ public ViewPagerTabStrip(Context context) {
+ this(context, null);
+ }
+
+ public ViewPagerTabStrip(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ final Resources res = context.getResources();
+
+ mSelectedUnderlineThickness =
+ res.getDimensionPixelSize(R.dimen.tab_selected_underline_height);
+ int underlineColor = res.getColor(R.color.tab_selected_underline_color);
+ int backgroundColor = res.getColor(R.color.actionbar_background_color);
+
+ mSelectedUnderlinePaint = new Paint();
+ mSelectedUnderlinePaint.setColor(underlineColor);
+
+ setBackgroundColor(backgroundColor);
+ setWillNotDraw(false);
+ }
+
+ /**
+ * Notifies this view that view pager has been scrolled. We save the tab index
+ * and selection offset for interpolating the position and width of selection
+ * underline.
+ */
+ void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ mIndexForSelection = position;
+ mSelectionOffset = positionOffset;
+ invalidate();
+ }
+
+ /**
+ * Notifies this view that a new page has been selected in the view pager. We save the tab
+ * index and reset the selection offset to 0.
+ */
+ void onPageSelected(int position) {
+ mIndexForSelection = position;
+ mSelectionOffset = 0;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int childCount = getChildCount();
+
+ // Thick colored underline below the current selection
+ if (childCount > 0) {
+ View selectedTitle = getChildAt(mIndexForSelection);
+ int selectedLeft = selectedTitle.getLeft();
+ int selectedRight = selectedTitle.getRight();
+ if ((mSelectionOffset > 0.0f) &&
+ (mIndexForSelection < (getChildCount() - 1))) {
+ // Draw the selection partway between the tabs
+ View nextTitle = getChildAt(mIndexForSelection + 1);
+ int nextLeft = nextTitle.getLeft();
+ int nextRight = nextTitle.getRight();
+
+ selectedLeft = (int) (mSelectionOffset * nextLeft +
+ (1.0f - mSelectionOffset) * selectedLeft);
+ selectedRight = (int) (mSelectionOffset * nextRight +
+ (1.0f - mSelectionOffset) * selectedRight);
+ }
+
+ int height = getHeight();
+ canvas.drawRect(selectedLeft, height - mSelectedUnderlineThickness,
+ selectedRight, height, mSelectedUnderlinePaint);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/dialer/list/ViewPagerTabs.java b/src/com/android/dialer/list/ViewPagerTabs.java
index b54580249..c95a80bda 100644
--- a/src/com/android/dialer/list/ViewPagerTabs.java
+++ b/src/com/android/dialer/list/ViewPagerTabs.java
@@ -26,11 +26,12 @@ import com.android.dialer.R;
public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
ViewPager mPager;
+ private ViewPagerTabStrip mTabStrip;
+
/**
* Linearlayout that will contain the TextViews serving as tabs. This is the only child
* of the parent HorizontalScrollView.
*/
- LinearLayout mChild;
final int mTextStyle;
final ColorStateList mTextColor;
final int mTextSize;
@@ -100,8 +101,8 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
mTextColor = a.getColorStateList(2);
mTextAllCaps = a.getBoolean(3, false);
- mChild = new LinearLayout(context);
- addView(mChild,
+ mTabStrip = new ViewPagerTabStrip(context);
+ addView(mTabStrip,
new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
a.recycle();
}
@@ -112,7 +113,7 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
}
private void addTabs(PagerAdapter adapter) {
- mChild.removeAllViews();
+ mTabStrip.removeAllViews();
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
@@ -123,7 +124,7 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
private void addTab(CharSequence tabTitle, final int position) {
final TextView textView = new TextView(getContext());
textView.setText(tabTitle);
- textView.setBackgroundResource(R.drawable.action_bar_tab);
+ textView.setBackgroundResource(R.drawable.view_pager_tab_background);
textView.setGravity(Gravity.CENTER);
textView.setOnClickListener(new OnClickListener() {
@Override
@@ -146,7 +147,7 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
}
textView.setAllCaps(mTextAllCaps);
textView.setPadding(mSidePadding, 0, mSidePadding, 0);
- mChild.addView(textView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
+ mTabStrip.addView(textView, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT, 1));
// Default to the first child being selected
if (position == 0) {
@@ -157,15 +158,23 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ int tabStripChildCount = mTabStrip.getChildCount();
+ if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+ return;
+ }
+
+ mTabStrip.onPageScrolled(position, positionOffset, positionOffsetPixels);
+ smoothScrollTo(position, 0);
}
@Override
public void onPageSelected(int position) {
if (mPrevSelected >= 0) {
- mChild.getChildAt(mPrevSelected).setSelected(false);
+ mTabStrip.getChildAt(mPrevSelected).setSelected(false);
}
- final View selectedChild = mChild.getChildAt(position);
+ final View selectedChild = mTabStrip.getChildAt(position);
selectedChild.setSelected(true);
+
// Update scroll position
final int scrollPos = selectedChild.getLeft() - (getWidth() - selectedChild.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
@@ -176,3 +185,4 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
public void onPageScrollStateChanged(int state) {
}
}
+