com.qs.qswlw.view.Mypager.UltraViewPagerIndicator.java Source code

Java tutorial

Introduction

Here is the source code for com.qs.qswlw.view.Mypager.UltraViewPagerIndicator.java

Source

/*
 *
 *  MIT License
 *
 *  Copyright (c) 2017 Alibaba Group
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in all
 *  copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *  SOFTWARE.
 *
 */

package com.qs.qswlw.view.Mypager;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;

/**
 * Created by mikeafc on 15/11/25.
 */
public class UltraViewPagerIndicator extends View
        implements ViewPager.OnPageChangeListener, IUltraIndicatorBuilder {
    interface UltraViewPagerIndicatorListener {
        void build();
    }

    private UltraViewPagerView viewPager;
    private ViewPager.OnPageChangeListener pageChangeListener;
    private int scrollState;

    //attr for custom
    private int radius;
    private int indicatorPadding;
    private boolean animateIndicator;
    private int gravity;
    private UltraViewPager.Orientation orientation = UltraViewPager.Orientation.HORIZONTAL;

    private int marginLeft;
    private int marginTop;
    private int marginRight;
    private int marginBottom;
    //for circle
    private int focusColor;
    private int normalColor;
    //for custom icon
    private Bitmap focusBitmap;
    private Bitmap normalBitmap;

    //paint
    private Paint paintStroke;
    private Paint paintFill;

    float pageOffset;
    float defaultRadius;

    //default
    private static final int DEFAULT_RADIUS = 3;

    private UltraViewPagerIndicatorListener indicatorBuildListener;

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

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

    public UltraViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paintStroke = new Paint(Paint.ANTI_ALIAS_FLAG);
        paintStroke.setStyle(Paint.Style.STROKE);
        paintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
        paintFill.setStyle(Paint.Style.FILL);
        defaultRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_RADIUS,
                getResources().getDisplayMetrics());
    }

    public void setViewPager(UltraViewPagerView viewPager) {
        this.viewPager = viewPager;
        this.viewPager.setOnPageChangeListener(this);
    }

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

        if (viewPager == null || viewPager.getAdapter() == null)
            return;

        final int count = ((UltraViewPagerAdapter) viewPager.getAdapter()).getRealCount();
        if (count == 0)
            return;

        int longSize;
        int shortSize;

        int longPaddingBefore;
        int longPaddingAfter;
        int shortPaddingBefore;
        int shortPaddingAfter;
        if (orientation == UltraViewPager.Orientation.HORIZONTAL) {
            longSize = viewPager.getWidth();
            shortSize = viewPager.getHeight();
            longPaddingBefore = (int) (getItemWidth() + getPaddingLeft() + marginLeft);
            longPaddingAfter = getPaddingRight() + marginRight;
            shortPaddingBefore = (int) (getItemWidth() + getPaddingTop() + marginTop);
            shortPaddingAfter = (int) paintStroke.getStrokeWidth() + getPaddingBottom() + marginBottom;
        } else {
            longSize = viewPager.getHeight();
            shortSize = viewPager.getWidth();
            longPaddingBefore = (int) (getItemWidth() + getPaddingTop() + marginTop);
            longPaddingAfter = (int) paintStroke.getStrokeWidth() + getPaddingBottom() + marginBottom;
            shortPaddingBefore = (int) (getItemWidth() + getPaddingLeft() + marginLeft);
            shortPaddingAfter = getPaddingRight() + marginRight;
        }

        final float itemWidth = getItemWidth();
        final int widthRatio = isDrawResIndicator() ? 1 : 2; //bitmap resource X1 : circle  X2
        if (indicatorPadding == 0) {
            indicatorPadding = (int) itemWidth;
        }

        float shortOffset = shortPaddingBefore;
        float longOffset = longPaddingBefore;

        final float indicatorLength = count * itemWidth * widthRatio + (count - 1) * indicatorPadding;

        final int horizontalGravityMask = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
        final int verticalGravityMask = gravity & Gravity.VERTICAL_GRAVITY_MASK;
        switch (horizontalGravityMask) {
        case Gravity.CENTER_HORIZONTAL:
            longOffset = (longSize - longPaddingBefore - longPaddingAfter - indicatorLength) / 2.0f;
            break;
        case Gravity.RIGHT:
            if (orientation == UltraViewPager.Orientation.HORIZONTAL) {
                longOffset = longSize - longPaddingAfter - indicatorLength;
            }
            if (orientation == UltraViewPager.Orientation.VERTICAL) {
                shortOffset = shortSize - shortPaddingAfter - itemWidth;
            }
            break;
        case Gravity.LEFT:
        default:
            break;
        }

        switch (verticalGravityMask) {
        case Gravity.CENTER_VERTICAL:
            shortOffset = (shortSize - shortPaddingAfter - shortPaddingBefore - itemWidth) / 2;
            break;
        case Gravity.BOTTOM:
            if (orientation == UltraViewPager.Orientation.HORIZONTAL) {
                shortOffset = shortSize - shortPaddingAfter - getItemHeight();
            }
            if (orientation == UltraViewPager.Orientation.VERTICAL) {
                longOffset = longSize - longPaddingAfter - indicatorLength;
            }
            break;
        case Gravity.TOP:
        default:
            break;
        }

        if (horizontalGravityMask == Gravity.CENTER_HORIZONTAL && verticalGravityMask == Gravity.CENTER_VERTICAL) {
            shortOffset = (shortSize - shortPaddingAfter - shortPaddingBefore - itemWidth) / 2;
        }

        float dX;
        float dY;

        float pageFillRadius = radius;
        if (paintStroke.getStrokeWidth() > 0) {
            pageFillRadius -= paintStroke.getStrokeWidth() / 2.0f; //TODO may not/2
        }

        //Draw stroked circles
        for (int iLoop = 0; iLoop < count; iLoop++) {
            float drawLong = longOffset + (iLoop * (itemWidth * widthRatio + indicatorPadding));
            if (orientation == UltraViewPager.Orientation.HORIZONTAL) {
                dX = drawLong;
                dY = shortOffset;
            } else {
                dX = shortOffset;
                dY = drawLong;
            }

            if (isDrawResIndicator()) {
                if (iLoop == viewPager.getCurrentItem())
                    continue;
                canvas.drawBitmap(normalBitmap, dX, dY, paintFill);
            } else {
                // Only paint fill if not completely transparent
                if (paintFill.getAlpha() > 0) {
                    paintFill.setColor(normalColor);
                    canvas.drawCircle(dX, dY, pageFillRadius, paintFill);
                }

                // Only paint stroke if a stroke width was non-zero
                if (pageFillRadius != radius) {
                    canvas.drawCircle(dX, dY, radius, paintStroke);
                }
            }
        }

        //Draw the filled circle according to the current scroll
        float cx = (viewPager.getCurrentItem()) * (itemWidth * widthRatio + indicatorPadding);
        if (animateIndicator)
            cx += pageOffset * itemWidth;
        if (orientation == UltraViewPager.Orientation.HORIZONTAL) {
            dX = longOffset + cx;
            dY = shortOffset;
        } else {
            dX = shortOffset;
            dY = longOffset + cx;
        }

        if (isDrawResIndicator()) {
            canvas.drawBitmap(focusBitmap, dX, dY, paintStroke);
        } else {
            paintFill.setColor(focusColor);
            canvas.drawCircle(dX, dY, radius, paintFill);
        }
    }

    private boolean isDrawResIndicator() {
        return focusBitmap != null && normalBitmap != null;
    }

    private float getItemWidth() {
        if (isDrawResIndicator()) {
            return Math.max(focusBitmap.getWidth(), normalBitmap.getWidth());
        }
        return radius == 0 ? defaultRadius : radius;
    }

    private float getItemHeight() {
        if (isDrawResIndicator()) {
            return Math.max(focusBitmap.getHeight(), normalBitmap.getHeight());
        }
        return radius == 0 ? defaultRadius : radius;
    }

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

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

    @Override
    public void onPageSelected(int position) {
        if (scrollState == ViewPager.SCROLL_STATE_IDLE) {
            invalidate();
        }

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

    @Override
    public void onPageScrollStateChanged(int state) {
        scrollState = state;

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

    @Override
    public IUltraIndicatorBuilder setOrientation(UltraViewPager.Orientation orien) {
        this.orientation = orien;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setRadius(int radius) {
        this.radius = radius;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setIndicatorPadding(int indicatorPadding) {
        this.indicatorPadding = indicatorPadding;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setFocusColor(int focusColor) {
        this.focusColor = focusColor;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setNormalColor(int normalColor) {
        this.normalColor = normalColor;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setStrokeColor(int strokeColor) {
        paintStroke.setColor(strokeColor);
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setStrokeWidth(int strokeWidth) {
        paintStroke.setStrokeWidth(strokeWidth);
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setGravity(int gravity) {
        this.gravity = gravity;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setFocusResId(int focusResId) {
        try {
            focusBitmap = BitmapFactory.decodeResource(getResources(), focusResId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setNormalResId(int normalResId) {
        try {
            normalBitmap = BitmapFactory.decodeResource(getResources(), normalResId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setFocusIcon(Bitmap bitmap) {
        focusBitmap = bitmap;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setNormalIcon(Bitmap bitmap) {
        normalBitmap = bitmap;
        return this;
    }

    @Override
    public IUltraIndicatorBuilder setMargin(int left, int top, int right, int bottom) {
        marginLeft = left;
        marginTop = top;
        marginRight = right;
        marginBottom = bottom;
        return this;
    }

    @Override
    public void build() {
        if (indicatorBuildListener != null) {
            indicatorBuildListener.build();
        }
    }

    public void setPageChangeListener(ViewPager.OnPageChangeListener pageChangeListener) {
        this.pageChangeListener = pageChangeListener;
    }

    public void setIndicatorBuildListener(UltraViewPagerIndicatorListener listener) {
        this.indicatorBuildListener = listener;
    }
}