124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell/*
224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * Copyright (C) 2012 The Android Open Source Project
324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell *
424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * you may not use this file except in compliance with the License.
624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * You may obtain a copy of the License at
724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell *
824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell *
1024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * Unless required by applicable law or agreed to in writing, software
1124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
1224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * See the License for the specific language governing permissions and
1424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * limitations under the License.
1524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell */
1624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
1724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellpackage android.support.v4.view;
1824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
1924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.content.Context;
2024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.graphics.Canvas;
2124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.graphics.Paint;
2224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.graphics.Rect;
231e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powellimport android.graphics.drawable.Drawable;
2424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.util.AttributeSet;
251e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powellimport android.view.MotionEvent;
2624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.view.View;
271e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powellimport android.view.ViewConfiguration;
2824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
2924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell/**
3024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * PagerTabStrip is an interactive indicator of the current, next,
3124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * and previous pages of a {@link ViewPager}. It is intended to be used as a
3224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * child view of a ViewPager widget in your XML layout.
3324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * Add it as a child of a ViewPager in your layout file and set its
3424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom
3524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * of the ViewPager. The title from each page is supplied by the method
3624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * {@link PagerAdapter#getPageTitle(int)} in the adapter supplied to
3724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * the ViewPager.
3824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell *
3924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * <p>For a non-interactive indicator, see {@link PagerTitleStrip}.</p>
4024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell */
4124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellpublic class PagerTabStrip extends PagerTitleStrip {
421e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private static final String TAG = "PagerTabStrip";
431e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
4424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int INDICATOR_HEIGHT = 3; // dp
4524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int MIN_PADDING_BOTTOM = INDICATOR_HEIGHT + 3; // dp
4624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int TAB_PADDING = 16; // dp
4724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int TAB_SPACING = 32; // dp
4824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int MIN_TEXT_SPACING = TAB_SPACING + TAB_PADDING * 2; // dp
491e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private static final int FULL_UNDERLINE_HEIGHT = 1; // dp
501e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private static final int MIN_STRIP_HEIGHT = 32; // dp
5124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
5224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mIndicatorColor;
5324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mIndicatorHeight;
5424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
5524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mMinPaddingBottom;
5624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mMinTextSpacing;
571e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private int mMinStripHeight;
5824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
5924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mTabPadding;
6024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
6124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private final Paint mTabPaint = new Paint();
6224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private final Rect mTempRect = new Rect();
6324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
6424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mTabAlpha = 0xFF;
6524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
661e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private boolean mDrawFullUnderline = false;
671e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private boolean mDrawFullUnderlineSet = false;
681e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private int mFullUnderlineHeight;
691e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
701e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private boolean mIgnoreTap;
711e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private float mInitialMotionX;
721e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private float mInitialMotionY;
731e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private int mTouchSlop;
741e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
7524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public PagerTabStrip(Context context) {
7624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        this(context, null);
7724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
7824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
7924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public PagerTabStrip(Context context, AttributeSet attrs) {
8024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super(context, attrs);
8124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
8224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mIndicatorColor = mTextColor;
8324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPaint.setColor(mIndicatorColor);
8424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
8524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        // Note: this follows the rules for Resources#getDimensionPixelOffset/Size:
8624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        //       sizes round up, offsets round down.
8724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final float density = context.getResources().getDisplayMetrics().density;
8824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mIndicatorHeight = (int) (INDICATOR_HEIGHT * density + 0.5f);
8924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mMinPaddingBottom = (int) (MIN_PADDING_BOTTOM * density + 0.5f);
9024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mMinTextSpacing = (int) (MIN_TEXT_SPACING * density);
9124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPadding = (int) (TAB_PADDING * density + 0.5f);
921e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mFullUnderlineHeight = (int) (FULL_UNDERLINE_HEIGHT * density + 0.5f);
931e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mMinStripHeight = (int) (MIN_STRIP_HEIGHT * density + 0.5f);
941e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
9524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
9624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        // Enforce restrictions
9724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
9824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setTextSpacing(getTextSpacing());
9924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
10024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setWillNotDraw(false);
10124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
10224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mPrevText.setFocusable(true);
10324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mPrevText.setOnClickListener(new OnClickListener() {
10424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            @Override
10524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            public void onClick(View v) {
10624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell                mPager.setCurrentItem(mPager.getCurrentItem() - 1);
10724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            }
10824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        });
10924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
11024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mNextText.setFocusable(true);
11124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mNextText.setOnClickListener(new OnClickListener() {
11224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            @Override
11324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            public void onClick(View v) {
11424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell                mPager.setCurrentItem(mPager.getCurrentItem() + 1);
11524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            }
11624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        });
1171e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1181e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (getBackground() == null) {
1191e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = true;
1201e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
12124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
12224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
12324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    /**
12424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * Set the color of the tab indicator bar.
12524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     *
12624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * @param color Color to set as an 0xRRGGBB value. The high byte (alpha) is ignored.
12724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     */
12824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public void setTabIndicatorColor(int color) {
12924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mIndicatorColor = color;
13024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPaint.setColor(mIndicatorColor);
13124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        invalidate();
13224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
13324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
13424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    /**
13524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * Set the color of the tab indicator bar from a color resource.
13624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     *
13724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * @param resId Resource ID of a color resource to load
13824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     */
13924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public void setTabIndicatorColorResource(int resId) {
14024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setTabIndicatorColor(getContext().getResources().getColor(resId));
14124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
14224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
14324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    /**
14424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * @return The current tab indicator color as an 0xRRGGBB value.
14524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     */
14624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public int getTabIndicatorColor() {
14724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        return mIndicatorColor;
14824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
14924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
15024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
15124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public void setPadding(int left, int top, int right, int bottom) {
15224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        if (bottom < mMinPaddingBottom) {
15324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            bottom = mMinPaddingBottom;
15424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        }
15524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.setPadding(left, top, right, bottom);
15624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
15724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
15824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
15924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public void setTextSpacing(int textSpacing) {
16024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        if (textSpacing < mMinTextSpacing) {
16124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            textSpacing = mMinTextSpacing;
16224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        }
16324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.setTextSpacing(textSpacing);
16424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
16524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
16624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
1671e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public void setBackgroundDrawable(Drawable d) {
1681e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        super.setBackgroundDrawable(d);
1691e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (!mDrawFullUnderlineSet) {
1701e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = d == null;
1711e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
1721e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
1731e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1741e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
1751e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public void setBackgroundColor(int color) {
1761e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        super.setBackgroundColor(color);
1771e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (!mDrawFullUnderlineSet) {
1781e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = (color & 0xFF000000) == 0;
1791e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
1801e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
1811e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1821e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
1831e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public void setBackgroundResource(int resId) {
1841e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        super.setBackgroundResource(resId);
1851e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (!mDrawFullUnderlineSet) {
1861e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = resId == 0;
1871e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
1881e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
1891e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1901e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    /**
1911e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * Set whether this tab strip should draw a full-width underline in the
1921e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * current tab indicator color.
1931e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     *
1941e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * @param drawFull true to draw a full-width underline, false otherwise
1951e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     */
1961e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public void setDrawFullUnderline(boolean drawFull) {
1971e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mDrawFullUnderline = drawFull;
1981e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mDrawFullUnderlineSet = true;
1991e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        invalidate();
2001e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2011e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2021e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    /**
2031e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * Return whether or not this tab strip will draw a full-width underline.
2041e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * This defaults to true if no background is set.
2051e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     *
2061e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * @return true if this tab strip will draw a full-width underline in the
2071e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * current tab indicator color.
2081e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     */
2091e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public boolean getDrawFullUnderline() {
2101e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        return mDrawFullUnderline;
2111e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2121e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2131e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
2141e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    int getMinHeight() {
2151e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        return Math.max(super.getMinHeight(), mMinStripHeight);
2161e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2171e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2181e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
2191e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public boolean onTouchEvent(MotionEvent ev) {
2201e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final int action = ev.getAction();
2211e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (action != MotionEvent.ACTION_DOWN && mIgnoreTap) {
2221e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            return false;
2231e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
2241e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2251e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        // Any tap within touch slop to either side of the current item
2261e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        // will scroll to prev/next.
2271e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final float x = ev.getX();
2281e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final float y = ev.getY();
2291e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        switch (action) {
2301e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            case MotionEvent.ACTION_DOWN:
2311e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                mInitialMotionX = x;
2321e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                mInitialMotionY = y;
2331e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                mIgnoreTap = false;
2341e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                break;
2351e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2361e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            case MotionEvent.ACTION_MOVE:
2371e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                if (Math.abs(x - mInitialMotionX) > mTouchSlop ||
2381e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                        Math.abs(y - mInitialMotionY) > mTouchSlop) {
2391e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                    mIgnoreTap = true;
2401e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                }
2411e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                break;
2421e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2431e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            case MotionEvent.ACTION_UP:
2441e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                if (x < mCurrText.getLeft() - mTabPadding) {
2451e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                    mPager.setCurrentItem(mPager.getCurrentItem() - 1);
2461e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                } else if (x > mCurrText.getRight() + mTabPadding) {
2471e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                    mPager.setCurrentItem(mPager.getCurrentItem() + 1);
2481e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                }
2491e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                break;
2501e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
2511e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2521e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        return true;
2531e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2541e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2551e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
25624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    protected void onDraw(Canvas canvas) {
25724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.onDraw(canvas);
25824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
2591e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final int height = getHeight();
2601e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final int bottom = height;
26124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final int left = mCurrText.getLeft() - mTabPadding;
26224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final int right = mCurrText.getRight() + mTabPadding;
26324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final int top = bottom - mIndicatorHeight;
26424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
26524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPaint.setColor(mTabAlpha << 24 | (mIndicatorColor & 0xFFFFFF));
26624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        canvas.drawRect(left, top, right, bottom, mTabPaint);
2671e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2681e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (mDrawFullUnderline) {
2691e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mTabPaint.setColor(0xFF << 24 | (mIndicatorColor & 0xFFFFFF));
270661eaf5536d7c5648ca977ae9c806d235783db5cAdam Powell            canvas.drawRect(getPaddingLeft(), height - mFullUnderlineHeight,
271661eaf5536d7c5648ca977ae9c806d235783db5cAdam Powell                    getWidth() - getPaddingRight(), height, mTabPaint);
2721e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
27324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
27424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
27524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
27624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    void updateTextPositions(int position, float positionOffset, boolean force) {
27724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final Rect r = mTempRect;
27824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int bottom = getHeight();
27924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int left = mCurrText.getLeft() - mTabPadding;
28024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int right = mCurrText.getRight() + mTabPadding;
28124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int top = bottom - mIndicatorHeight;
28224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
28324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        r.set(left, top, right, bottom);
28424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
28524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.updateTextPositions(position, positionOffset, force);
28624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabAlpha = (int) (Math.abs(positionOffset - 0.5f) * 2 * 0xFF);
28724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
28824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        left = mCurrText.getLeft() - mTabPadding;
28924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        right = mCurrText.getRight() + mTabPadding;
29024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        r.union(left, top, right, bottom);
29124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
29224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        invalidate(r);
29324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
29424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell}
295