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