public class

PagerTabStrip

extends PagerTitleStrip

 java.lang.Object

↳ViewGroup

androidx.viewpager.widget.PagerTitleStrip

↳androidx.viewpager.widget.PagerTabStrip

Gradle dependencies

compile group: 'androidx.viewpager', name: 'viewpager', version: '1.1.0-alpha01'

  • groupId: androidx.viewpager
  • artifactId: viewpager
  • version: 1.1.0-alpha01

Artifact androidx.viewpager:viewpager:1.1.0-alpha01 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.viewpager:viewpager com.android.support:viewpager

Androidx class mapping:

androidx.viewpager.widget.PagerTabStrip android.support.v4.view.PagerTabStrip

Overview

PagerTabStrip is an interactive indicator of the current, next, and previous pages of a ViewPager. It is intended to be used as a child view of a ViewPager widget in your XML layout. Add it as a child of a ViewPager in your layout file and set its android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom of the ViewPager. The title from each page is supplied by the method PagerAdapter.getPageTitle(int) in the adapter supplied to the ViewPager.

For a non-interactive indicator, see PagerTitleStrip.

Summary

Constructors
publicPagerTabStrip(Context context)

publicPagerTabStrip(Context context, AttributeSet attrs)

Methods
public booleangetDrawFullUnderline()

Return whether or not this tab strip will draw a full-width underline.

public intgetTabIndicatorColor()

protected voidonDraw(Canvas canvas)

public booleanonTouchEvent(MotionEvent ev)

public voidsetBackgroundColor(int color)

public voidsetBackgroundDrawable(Drawable d)

public voidsetBackgroundResource(int resId)

public voidsetDrawFullUnderline(boolean drawFull)

Set whether this tab strip should draw a full-width underline in the current tab indicator color.

public voidsetPadding(int left, int top, int right, int bottom)

public voidsetTabIndicatorColor(int color)

Set the color of the tab indicator bar.

public voidsetTabIndicatorColorResource(int resId)

Set the color of the tab indicator bar from a color resource.

public voidsetTextSpacing(int spacingPixels)

Set the required spacing between title segments.

from PagerTitleStripgetTextSpacing, onAttachedToWindow, onDetachedFromWindow, onLayout, onMeasure, requestLayout, setGravity, setNonPrimaryAlpha, setTextColor, setTextSize
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public PagerTabStrip(Context context)

public PagerTabStrip(Context context, AttributeSet attrs)

Methods

public void setTabIndicatorColor(int color)

Set the color of the tab indicator bar.

Parameters:

color: Color to set as an 0xRRGGBB value. The high byte (alpha) is ignored.

public void setTabIndicatorColorResource(int resId)

Set the color of the tab indicator bar from a color resource.

Parameters:

resId: Resource ID of a color resource to load

public int getTabIndicatorColor()

Returns:

The current tab indicator color as an 0xRRGGBB value.

public void setPadding(int left, int top, int right, int bottom)

public void setTextSpacing(int spacingPixels)

Set the required spacing between title segments.

Parameters:

spacingPixels: Spacing between each title displayed in pixels

public void setBackgroundDrawable(Drawable d)

public void setBackgroundColor(int color)

public void setBackgroundResource(int resId)

public void setDrawFullUnderline(boolean drawFull)

Set whether this tab strip should draw a full-width underline in the current tab indicator color.

Parameters:

drawFull: true to draw a full-width underline, false otherwise

public boolean getDrawFullUnderline()

Return whether or not this tab strip will draw a full-width underline. This defaults to true if no background is set.

Returns:

true if this tab strip will draw a full-width underline in the current tab indicator color.

public boolean onTouchEvent(MotionEvent ev)

protected void onDraw(Canvas canvas)

Source

/*
 * Copyright 2018 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 androidx.viewpager.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

/**
 * PagerTabStrip is an interactive indicator of the current, next,
 * and previous pages of a {@link ViewPager}. It is intended to be used as a
 * child view of a ViewPager widget in your XML layout.
 * Add it as a child of a ViewPager in your layout file and set its
 * android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom
 * of the ViewPager. The title from each page is supplied by the method
 * {@link PagerAdapter#getPageTitle(int)} in the adapter supplied to
 * the ViewPager.
 *
 * <p>For a non-interactive indicator, see {@link PagerTitleStrip}.</p>
 */
public class PagerTabStrip extends PagerTitleStrip {
    private static final int INDICATOR_HEIGHT = 3; // dp
    private static final int MIN_PADDING_BOTTOM = INDICATOR_HEIGHT + 3; // dp
    private static final int TAB_PADDING = 16; // dp
    private static final int TAB_SPACING = 32; // dp
    private static final int MIN_TEXT_SPACING = TAB_SPACING + TAB_PADDING * 2; // dp
    private static final int FULL_UNDERLINE_HEIGHT = 1; // dp
    private static final int MIN_STRIP_HEIGHT = 32; // dp

    private int mIndicatorColor;
    private int mIndicatorHeight;

    private int mMinPaddingBottom;
    private int mMinTextSpacing;
    private int mMinStripHeight;

    private int mTabPadding;

    private final Paint mTabPaint = new Paint();

    private int mTabAlpha = 0xFF;

    private boolean mDrawFullUnderline = false;
    private boolean mDrawFullUnderlineSet = false;
    private int mFullUnderlineHeight;

    private boolean mIgnoreTap;
    private float mInitialMotionX;
    private float mInitialMotionY;
    private int mTouchSlop;

    public PagerTabStrip(@NonNull Context context) {
        this(context, null);
    }

    public PagerTabStrip(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        mIndicatorColor = mTextColor;
        mTabPaint.setColor(mIndicatorColor);

        // Note: this follows the rules for Resources#getDimensionPixelOffset/Size:
        //       sizes round up, offsets round down.
        final float density = context.getResources().getDisplayMetrics().density;
        mIndicatorHeight = (int) (INDICATOR_HEIGHT * density + 0.5f);
        mMinPaddingBottom = (int) (MIN_PADDING_BOTTOM * density + 0.5f);
        mMinTextSpacing = (int) (MIN_TEXT_SPACING * density);
        mTabPadding = (int) (TAB_PADDING * density + 0.5f);
        mFullUnderlineHeight = (int) (FULL_UNDERLINE_HEIGHT * density + 0.5f);
        mMinStripHeight = (int) (MIN_STRIP_HEIGHT * density + 0.5f);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        // Enforce restrictions
        setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
        setTextSpacing(getTextSpacing());

        setWillNotDraw(false);

        mPrevText.setFocusable(true);
        mPrevText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mPager.setCurrentItem(mPager.getCurrentItem() - 1);
            }
        });

        mNextText.setFocusable(true);
        mNextText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mPager.setCurrentItem(mPager.getCurrentItem() + 1);
            }
        });

        if (getBackground() == null) {
            mDrawFullUnderline = true;
        }
    }

    /**
     * Set the color of the tab indicator bar.
     *
     * @param color Color to set as an 0xRRGGBB value. The high byte (alpha) is ignored.
     */
    public void setTabIndicatorColor(@ColorInt int color) {
        mIndicatorColor = color;
        mTabPaint.setColor(mIndicatorColor);
        invalidate();
    }

    /**
     * Set the color of the tab indicator bar from a color resource.
     *
     * @param resId Resource ID of a color resource to load
     */
    public void setTabIndicatorColorResource(@ColorRes int resId) {
        setTabIndicatorColor(ContextCompat.getColor(getContext(), resId));
    }

    /**
     * @return The current tab indicator color as an 0xRRGGBB value.
     */
    @ColorInt
    public int getTabIndicatorColor() {
        return mIndicatorColor;
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        if (bottom < mMinPaddingBottom) {
            bottom = mMinPaddingBottom;
        }
        super.setPadding(left, top, right, bottom);
    }

    @Override
    public void setTextSpacing(int spacingPixels) {
        if (spacingPixels < mMinTextSpacing) {
            spacingPixels = mMinTextSpacing;
        }
        super.setTextSpacing(spacingPixels);
    }

    @Override
    @SuppressWarnings("deprecation")
    public void setBackgroundDrawable(Drawable d) {
        super.setBackgroundDrawable(d);
        if (!mDrawFullUnderlineSet) {
            mDrawFullUnderline = d == null;
        }
    }

    @Override
    public void setBackgroundColor(@ColorInt int color) {
        super.setBackgroundColor(color);
        if (!mDrawFullUnderlineSet) {
            mDrawFullUnderline = (color & 0xFF000000) == 0;
        }
    }

    @Override
    public void setBackgroundResource(@DrawableRes int resId) {
        super.setBackgroundResource(resId);
        if (!mDrawFullUnderlineSet) {
            mDrawFullUnderline = resId == 0;
        }
    }

    /**
     * Set whether this tab strip should draw a full-width underline in the
     * current tab indicator color.
     *
     * @param drawFull true to draw a full-width underline, false otherwise
     */
    public void setDrawFullUnderline(boolean drawFull) {
        mDrawFullUnderline = drawFull;
        mDrawFullUnderlineSet = true;
        invalidate();
    }

    /**
     * Return whether or not this tab strip will draw a full-width underline.
     * This defaults to true if no background is set.
     *
     * @return true if this tab strip will draw a full-width underline in the
     * current tab indicator color.
     */
    public boolean getDrawFullUnderline() {
        return mDrawFullUnderline;
    }

    @Override
    int getMinHeight() {
        return Math.max(super.getMinHeight(), mMinStripHeight);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        if (action != MotionEvent.ACTION_DOWN && mIgnoreTap) {
            return false;
        }

        // Any tap within touch slop to either side of the current item
        // will scroll to prev/next.
        final float x = ev.getX();
        final float y = ev.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mInitialMotionX = x;
                mInitialMotionY = y;
                mIgnoreTap = false;
                break;

            case MotionEvent.ACTION_MOVE:
                if (Math.abs(x - mInitialMotionX) > mTouchSlop
                        || Math.abs(y - mInitialMotionY) > mTouchSlop) {
                    mIgnoreTap = true;
                }
                break;

            case MotionEvent.ACTION_UP:
                if (x < mCurrText.getLeft() - mTabPadding) {
                    mPager.setCurrentItem(mPager.getCurrentItem() - 1);
                } else if (x > mCurrText.getRight() + mTabPadding) {
                    mPager.setCurrentItem(mPager.getCurrentItem() + 1);
                }
                break;
        }

        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        final int height = getHeight();
        final int bottom = height;
        final int left = mCurrText.getLeft() - mTabPadding;
        final int right = mCurrText.getRight() + mTabPadding;
        final int top = bottom - mIndicatorHeight;

        mTabPaint.setColor(mTabAlpha << 24 | (mIndicatorColor & 0xFFFFFF));
        canvas.drawRect(left, top, right, bottom, mTabPaint);

        if (mDrawFullUnderline) {
            mTabPaint.setColor(0xFF << 24 | (mIndicatorColor & 0xFFFFFF));
            canvas.drawRect(getPaddingLeft(), height - mFullUnderlineHeight,
                    getWidth() - getPaddingRight(), height, mTabPaint);
        }
    }

    @Override
    void updateTextPositions(int position, float positionOffset, boolean force) {
        super.updateTextPositions(position, positionOffset, force);
        mTabAlpha = (int) (Math.abs(positionOffset - 0.5f) * 2 * 0xFF);

        invalidate();
    }
}