Android Open Source - android-viewpager-indicator Line Tab Indicator






From Project

Back to project page android-viewpager-indicator.

License

The source code is released under:

MIT License

If you think the Android project android-viewpager-indicator listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package me.caiying.indicator;
/*  ww  w.  jav  a 2 s.  com*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class LineTabIndicator  extends HorizontalScrollView {

    public interface OnTabSelectedListener {

        void onTabSelected(int position);
    }

    public OnPageChangeListener mOnPageChangeListener;
    private OnTabSelectedListener mTabSelectedListener;

    private LinearLayout mTabsContainer;
    private ViewPager mPager;

    private int tabCount;
    private int currentPosition = 0;
    private float currentPositionOffset = 0f;

    private Paint linePaint;
    private Paint diviPaint;

    private int indicatorColor = 0xFF52B800;
    private int underlineColor = 0x1A000000;
    private int dividerColor = 0x1A000000;
    private int textSelectedColor = 0xFF52B800;
    private int textUnselectColor = 0xFF808080;

    private boolean enableExpand = true;
    private boolean enableDivider = false;
    private boolean indicatorOnTop = false;
    private boolean viewPagerScrollWithAnimation = true;

    private int tabTextSize = 16;
    private int scrollOffset = 52;
    private float indicatorHeight = 1.5f;
    private float underlineHeight = 1.0f;
    private int dividerPadding = 12;
    private int tabPadding = 24;
    private int dividerWidth = 1;
    private int lastScrollX = 0;

    public LineTabIndicator(Context context) {
        this(context, null);
    }

    public LineTabIndicator(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LineTabIndicator(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        setFillViewport(true);
        setWillNotDraw(false);

        DisplayMetrics dm = getResources().getDisplayMetrics();

        mTabsContainer = new LinearLayout(context);
        mTabsContainer.setOrientation(LinearLayout.HORIZONTAL);
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        params.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, dm);
        mTabsContainer.setLayoutParams(params);
        addView(mTabsContainer);

        scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
        dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
        tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
        dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
        indicatorHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
        underlineHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);

        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setStyle(Style.FILL);

        diviPaint = new Paint();
        diviPaint.setAntiAlias(true);
        diviPaint.setStrokeWidth(dividerWidth);
    }

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

        if (isInEditMode() || tabCount == 0) {
            return;
        }

        final int height = getHeight();

        linePaint.setColor(underlineColor);
        if(indicatorOnTop) {
            canvas.drawRect(0, 0, mTabsContainer.getWidth(), underlineHeight, linePaint);
        } else {
            canvas.drawRect(0, height - underlineHeight, mTabsContainer.getWidth(), height, linePaint);
        }

        linePaint.setColor(indicatorColor);

        View currentTab = mTabsContainer.getChildAt(currentPosition);
        float lineLeft = currentTab.getLeft();
        float lineRight = currentTab.getRight();

        if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
            View nextTab = mTabsContainer.getChildAt(currentPosition + 1);
            final float nextTabLeft = nextTab.getLeft();
            final float nextTabRight = nextTab.getRight();

            lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
            lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
        }

        if(indicatorOnTop) {
            canvas.drawRect(lineLeft, 0, lineRight, indicatorHeight, linePaint);
        } else {
            canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, linePaint);
        }

        if(enableDivider) {
            diviPaint.setColor(dividerColor);
            for (int i = 0; i < tabCount - 1; i++) {
                View tab = mTabsContainer.getChildAt(i);
                canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, diviPaint);
            }
        }
    }

    public void setViewPager(ViewPager pager) {
        this.mPager = pager;

        if (pager.getAdapter() == null) {
            throw new IllegalStateException("ViewPager does not have adapter instance.");
        }

        pager.setOnPageChangeListener(new PageListener());

        notifyDataSetChanged();
    }

    public void setOnPageChangeListener(OnPageChangeListener listener) {
        this.mOnPageChangeListener = listener;
    }

    public void setOnTabReselectedListener(OnTabSelectedListener listener) {
        mTabSelectedListener = listener;
    }

    public void notifyDataSetChanged() {

        mTabsContainer.removeAllViews();

        tabCount = mPager.getAdapter().getCount();

        for (int i = 0; i < tabCount; i++) {
            addTab(i, mPager.getAdapter().getPageTitle(i).toString());
        }

        updateTabStyles();
    }

    private class TabView extends RelativeLayout {
        private TextView mTabText;

        public TabView(Context context) {
            super(context);
            init();
        }

        public TabView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public TabView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }

        private void init() {
            mTabText = new TextView(getContext());
            mTabText.setTextAppearance(getContext(), android.R.attr.textAppearanceMedium);
            mTabText.setTextSize(tabTextSize / getResources().getConfiguration().fontScale);
            mTabText.setSingleLine(true);
            mTabText.setGravity(Gravity.CENTER);
            LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            this.addView(mTabText, params);

        }

        public TextView getTextView() {
            return mTabText;
        }
    }

    private void addTab(final int position, String title) {
        TabView tab = new TabView(getContext());
        tab.getTextView().setText(title);
        tab.setFocusable(true);
        tab.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                final int oldSelected = mPager.getCurrentItem();
                if (oldSelected != position && mTabSelectedListener != null) {
                    mTabSelectedListener.onTabSelected(position);
                }

                mPager.setCurrentItem(position, viewPagerScrollWithAnimation);
            }
        });

        if(!enableExpand) {
            tab.setPadding(tabPadding, 0, tabPadding, 0);
        }
        mTabsContainer.addView(tab, position, enableExpand ?
                new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
                    new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
    }

    public void setTabText(int position, String text) {
        if (position < 0 || position > (mTabsContainer.getChildCount() - 1))
            throw new RuntimeException("tabs does not have this position.");

        View tab = mTabsContainer.getChildAt(position);
        if (tab instanceof TextView) {
            ((TextView) tab).setText(text);
        }
    }

    public boolean isIndicatorOnTop() {
        return indicatorOnTop;
    }

    public void setIndicatorOnTop(boolean indicatorOnTop) {
        this.indicatorOnTop = indicatorOnTop;
    }

    public boolean isEnableExpand() {
        return enableExpand;
    }

    public void setEnableExpand(boolean enableExpand) {
        this.enableExpand = enableExpand;
    }

    public boolean isEnableDivider() {
        return enableDivider;
    }

    public void setEnableDivider(boolean enableDivider) {
        this.enableDivider = enableDivider;
    }

    public void setViewPagerScrollWithAnimation(boolean enable) {
        this.viewPagerScrollWithAnimation = enable;
    }

    public boolean getViewPagerScrollWithAnimation() {
       return this.viewPagerScrollWithAnimation;
    }

    public void setCurrentItem(int item) {
        mPager.setCurrentItem(item, viewPagerScrollWithAnimation);
    }

    private void tabSelect(int index) {
        final int tabCount = mTabsContainer.getChildCount();
        for (int i = 0; i < tabCount; i++) {
            final View child = mTabsContainer.getChildAt(i);
            final boolean isSelected = (i == index);
            child.setSelected(isSelected);
            if(isSelected) {
                ((TabView) child).getTextView().setTextColor(textSelectedColor);
            } else {
                ((TabView) child).getTextView().setTextColor(textUnselectColor);
            }
        }
    }

    private void updateTabStyles() {
        for (int i = 0; i < tabCount; i++) {
            View v = mTabsContainer.getChildAt(i);
            v.setBackgroundColor(Color.TRANSPARENT);
        }
        tabSelect(mPager.getCurrentItem());
    }

    private void scrollToChild(int position, int offset) {
        if (tabCount == 0) {
            return;
        }

        int newScrollX = mTabsContainer.getChildAt(position).getLeft() + offset;

        if (position > 0 || offset > 0) {
            newScrollX -= scrollOffset;
        }

        if (newScrollX != lastScrollX) {
            lastScrollX = newScrollX;
            scrollTo(newScrollX, 0);
        }
    }

    private class PageListener implements OnPageChangeListener {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            currentPosition = position;
            currentPositionOffset = positionOffset;

            scrollToChild(position, (int) (positionOffset * mTabsContainer.getChildAt(position).getWidth()));

            invalidate();

            if (mOnPageChangeListener != null) {
                mOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                scrollToChild(mPager.getCurrentItem(), 0);
            }

            if (mOnPageChangeListener != null) {
                mOnPageChangeListener.onPageScrollStateChanged(state);
            }
        }

        @Override
        public void onPageSelected(int position) {
            tabSelect(position);

            if (mOnPageChangeListener != null) {
                mOnPageChangeListener.onPageSelected(position);
            }
        }
    }
}




Java Source Code List

me.caiying.indicator.FadeTabIndicator.java
me.caiying.indicator.LineTabIndicator.java
me.caiying.indicator.demo.ApiDemos.java
me.caiying.indicator.demo.FadeTabActivity.java
me.caiying.indicator.demo.LineTabActivity.java
me.caiying.indicator.demo.SampleFragmentPagerAdapter.java
me.caiying.indicator.demo.SampleFragment.java