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;
2470acb0c19be3831a2080e4f902324de16bfbf62eTor Norbyeimport android.support.annotation.ColorInt;
25a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.ColorRes;
26a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbyeimport android.support.annotation.DrawableRes;
27e5faeaff97f60817cde21f0f92513845355a7d0dAurimas Liutikasimport android.support.v4.content.ContextCompat;
2824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.util.AttributeSet;
291e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powellimport android.view.MotionEvent;
3024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellimport android.view.View;
311e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powellimport android.view.ViewConfiguration;
3224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
3324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell/**
3424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * PagerTabStrip is an interactive indicator of the current, next,
3524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * and previous pages of a {@link ViewPager}. It is intended to be used as a
3624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * child view of a ViewPager widget in your XML layout.
3724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * Add it as a child of a ViewPager in your layout file and set its
3824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom
3924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * of the ViewPager. The title from each page is supplied by the method
4024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * {@link PagerAdapter#getPageTitle(int)} in the adapter supplied to
4124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * the ViewPager.
4224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell *
4324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell * <p>For a non-interactive indicator, see {@link PagerTitleStrip}.</p>
4424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell */
4524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powellpublic class PagerTabStrip extends PagerTitleStrip {
461e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private static final String TAG = "PagerTabStrip";
471e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
4824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int INDICATOR_HEIGHT = 3; // dp
4924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int MIN_PADDING_BOTTOM = INDICATOR_HEIGHT + 3; // dp
5024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int TAB_PADDING = 16; // dp
5124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int TAB_SPACING = 32; // dp
5224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private static final int MIN_TEXT_SPACING = TAB_SPACING + TAB_PADDING * 2; // dp
531e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private static final int FULL_UNDERLINE_HEIGHT = 1; // dp
541e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private static final int MIN_STRIP_HEIGHT = 32; // dp
5524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
5624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mIndicatorColor;
5724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mIndicatorHeight;
5824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
5924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mMinPaddingBottom;
6024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mMinTextSpacing;
611e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private int mMinStripHeight;
6224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
6324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mTabPadding;
6424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
6524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private final Paint mTabPaint = new Paint();
6624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private final Rect mTempRect = new Rect();
6724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
6824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    private int mTabAlpha = 0xFF;
6924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
701e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private boolean mDrawFullUnderline = false;
711e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private boolean mDrawFullUnderlineSet = false;
721e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private int mFullUnderlineHeight;
731e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
741e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private boolean mIgnoreTap;
751e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private float mInitialMotionX;
761e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private float mInitialMotionY;
771e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    private int mTouchSlop;
781e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
7924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public PagerTabStrip(Context context) {
8024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        this(context, null);
8124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
8224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
8324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public PagerTabStrip(Context context, AttributeSet attrs) {
8424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super(context, attrs);
8524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
8624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mIndicatorColor = mTextColor;
8724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPaint.setColor(mIndicatorColor);
8824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
8924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        // Note: this follows the rules for Resources#getDimensionPixelOffset/Size:
9024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        //       sizes round up, offsets round down.
9124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final float density = context.getResources().getDisplayMetrics().density;
9224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mIndicatorHeight = (int) (INDICATOR_HEIGHT * density + 0.5f);
9324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mMinPaddingBottom = (int) (MIN_PADDING_BOTTOM * density + 0.5f);
9424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mMinTextSpacing = (int) (MIN_TEXT_SPACING * density);
9524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPadding = (int) (TAB_PADDING * density + 0.5f);
961e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mFullUnderlineHeight = (int) (FULL_UNDERLINE_HEIGHT * density + 0.5f);
971e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mMinStripHeight = (int) (MIN_STRIP_HEIGHT * density + 0.5f);
981e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
9924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
10024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        // Enforce restrictions
10124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
10224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setTextSpacing(getTextSpacing());
10324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
10424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        setWillNotDraw(false);
10524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
10624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mPrevText.setFocusable(true);
10724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mPrevText.setOnClickListener(new OnClickListener() {
10824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            @Override
10924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            public void onClick(View v) {
11024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell                mPager.setCurrentItem(mPager.getCurrentItem() - 1);
11124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            }
11224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        });
11324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
11424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mNextText.setFocusable(true);
11524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mNextText.setOnClickListener(new OnClickListener() {
11624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            @Override
11724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            public void onClick(View v) {
11824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell                mPager.setCurrentItem(mPager.getCurrentItem() + 1);
11924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            }
12024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        });
1211e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1221e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (getBackground() == null) {
1231e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = true;
1241e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
12524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
12624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
12724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    /**
12824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * Set the color of the tab indicator bar.
12924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     *
13024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * @param color Color to set as an 0xRRGGBB value. The high byte (alpha) is ignored.
13124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     */
13270acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setTabIndicatorColor(@ColorInt int color) {
13324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mIndicatorColor = color;
13424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPaint.setColor(mIndicatorColor);
13524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        invalidate();
13624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
13724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
13824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    /**
13924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * Set the color of the tab indicator bar from a color resource.
14024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     *
14124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * @param resId Resource ID of a color resource to load
14224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     */
143a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye    public void setTabIndicatorColorResource(@ColorRes int resId) {
144e5faeaff97f60817cde21f0f92513845355a7d0dAurimas Liutikas        setTabIndicatorColor(ContextCompat.getColor(getContext(), resId));
14524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
14624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
14724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    /**
14824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     * @return The current tab indicator color as an 0xRRGGBB value.
14924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell     */
15070acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    @ColorInt
15124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public int getTabIndicatorColor() {
15224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        return mIndicatorColor;
15324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
15424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
15524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
15624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public void setPadding(int left, int top, int right, int bottom) {
15724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        if (bottom < mMinPaddingBottom) {
15824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            bottom = mMinPaddingBottom;
15924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        }
16024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.setPadding(left, top, right, bottom);
16124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
16224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
16324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
16424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    public void setTextSpacing(int textSpacing) {
16524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        if (textSpacing < mMinTextSpacing) {
16624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell            textSpacing = mMinTextSpacing;
16724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        }
16824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.setTextSpacing(textSpacing);
16924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
17024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
17124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
1721e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public void setBackgroundDrawable(Drawable d) {
1731e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        super.setBackgroundDrawable(d);
1741e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (!mDrawFullUnderlineSet) {
1751e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = d == null;
1761e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
1771e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
1781e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1791e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
18070acb0c19be3831a2080e4f902324de16bfbf62eTor Norbye    public void setBackgroundColor(@ColorInt int color) {
1811e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        super.setBackgroundColor(color);
1821e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (!mDrawFullUnderlineSet) {
1831e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = (color & 0xFF000000) == 0;
1841e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
1851e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
1861e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1871e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
188a3ff3273e976adf19770651dcf473fa67b38eb22Tor Norbye    public void setBackgroundResource(@DrawableRes int resId) {
1891e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        super.setBackgroundResource(resId);
1901e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (!mDrawFullUnderlineSet) {
1911e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mDrawFullUnderline = resId == 0;
1921e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
1931e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
1941e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
1951e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    /**
1961e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * Set whether this tab strip should draw a full-width underline in the
1971e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * current tab indicator color.
1981e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     *
1991e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * @param drawFull true to draw a full-width underline, false otherwise
2001e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     */
2011e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public void setDrawFullUnderline(boolean drawFull) {
2021e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mDrawFullUnderline = drawFull;
2031e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        mDrawFullUnderlineSet = true;
2041e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        invalidate();
2051e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2061e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2071e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    /**
2081e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * Return whether or not this tab strip will draw a full-width underline.
2091e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * This defaults to true if no background is set.
2101e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     *
2111e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * @return true if this tab strip will draw a full-width underline in the
2121e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     * current tab indicator color.
2131e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell     */
2141e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public boolean getDrawFullUnderline() {
2151e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        return mDrawFullUnderline;
2161e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2171e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2181e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
2191e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    int getMinHeight() {
2201e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        return Math.max(super.getMinHeight(), mMinStripHeight);
2211e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2221e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2231e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
2241e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    public boolean onTouchEvent(MotionEvent ev) {
2251e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final int action = ev.getAction();
2261e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (action != MotionEvent.ACTION_DOWN && mIgnoreTap) {
2271e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            return false;
2281e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
2291e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2301e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        // Any tap within touch slop to either side of the current item
2311e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        // will scroll to prev/next.
2321e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final float x = ev.getX();
2331e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final float y = ev.getY();
2341e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        switch (action) {
2351e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            case MotionEvent.ACTION_DOWN:
2361e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                mInitialMotionX = x;
2371e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                mInitialMotionY = y;
2381e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                mIgnoreTap = false;
2391e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                break;
2401e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2411e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            case MotionEvent.ACTION_MOVE:
2424d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas                if (Math.abs(x - mInitialMotionX) > mTouchSlop
2434d2c7b7c4f194034c5f17c4bee7320d808aabe4cAurimas Liutikas                        || Math.abs(y - mInitialMotionY) > mTouchSlop) {
2441e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                    mIgnoreTap = true;
2451e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                }
2461e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                break;
2471e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2481e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            case MotionEvent.ACTION_UP:
2491e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                if (x < mCurrText.getLeft() - mTabPadding) {
2501e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                    mPager.setCurrentItem(mPager.getCurrentItem() - 1);
2511e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                } else if (x > mCurrText.getRight() + mTabPadding) {
2521e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                    mPager.setCurrentItem(mPager.getCurrentItem() + 1);
2531e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                }
2541e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell                break;
2551e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
2561e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2571e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        return true;
2581e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    }
2591e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2601e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell    @Override
26124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    protected void onDraw(Canvas canvas) {
26224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.onDraw(canvas);
26324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
2641e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final int height = getHeight();
2651e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        final int bottom = height;
26624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final int left = mCurrText.getLeft() - mTabPadding;
26724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final int right = mCurrText.getRight() + mTabPadding;
26824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final int top = bottom - mIndicatorHeight;
26924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
27024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabPaint.setColor(mTabAlpha << 24 | (mIndicatorColor & 0xFFFFFF));
27124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        canvas.drawRect(left, top, right, bottom, mTabPaint);
2721e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell
2731e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        if (mDrawFullUnderline) {
2741e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell            mTabPaint.setColor(0xFF << 24 | (mIndicatorColor & 0xFFFFFF));
275661eaf5536d7c5648ca977ae9c806d235783db5cAdam Powell            canvas.drawRect(getPaddingLeft(), height - mFullUnderlineHeight,
276661eaf5536d7c5648ca977ae9c806d235783db5cAdam Powell                    getWidth() - getPaddingRight(), height, mTabPaint);
2771e37da8d4fbd23a4440f32eba784520dc7a03265Adam Powell        }
27824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
27924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
28024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    @Override
28124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    void updateTextPositions(int position, float positionOffset, boolean force) {
28224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        final Rect r = mTempRect;
28324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int bottom = getHeight();
28424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int left = mCurrText.getLeft() - mTabPadding;
28524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int right = mCurrText.getRight() + mTabPadding;
28624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        int top = bottom - mIndicatorHeight;
28724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
28824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        r.set(left, top, right, bottom);
28924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
29024cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        super.updateTextPositions(position, positionOffset, force);
29124cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        mTabAlpha = (int) (Math.abs(positionOffset - 0.5f) * 2 * 0xFF);
29224cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
29324cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        left = mCurrText.getLeft() - mTabPadding;
29424cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        right = mCurrText.getRight() + mTabPadding;
29524cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        r.union(left, top, right, bottom);
29624cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell
29724cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell        invalidate(r);
29824cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell    }
29924cc55cb5775a71ff144a3588003fa8e52951c7dAdam Powell}
300