美文网首页
底部指示器【借鉴他人+做了部分优化】

底部指示器【借鉴他人+做了部分优化】

作者: 初见soulmate | 来源:发表于2020-10-16 16:16 被阅读0次

import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

import com.hcb.fixorder.R;
import com.orhanobut.logger.Logger;

import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;

/**
 * viewpager 底部指示器
 *
 * @author 陈聪 2020-05-11 10:59
 */
public class CuteIndicator extends LinearLayout {
    /** 显示个数 */
    private int itemCount = 0;
    /** 选中宽度 */
    private float selectedWidth = 0f;
    /** 点大小 */
    private float dia = 0f;
    /** 间隔大小 */
    private float space = 0f;
    /** 阴影大小 */
    private float shadowRadius = 0f;
    /** 位置 */
    private RectF rectf = new RectF();
    /** 画笔 */
    private Paint paint;
    /** 上个点偏移量 */
    private float lastPositionOffset = 0f;
    /** 选中点偏移量 */
    private int firstVisiblePosition = 0;
    /** 点颜色 */
    private int indicatorColor = 0xffffffff;
    /** 选中点颜色 */
    private int indicatorSelectColor = 0xffffffff;
    /** 阴影颜色 */
    private int shadowColor = 0x88000000;
    /** 是否使用动画 */
    private boolean isAnimation = true;
    /** 是否使用阴影 */
    private boolean isShadow = true;

    public CuteIndicator(Context context) {
        super(context);
        init(null, 0);
    }

    public CuteIndicator(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public CuteIndicator(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        //默认值
        selectedWidth = dp2px(20f);
        dia = dp2px(10f);
        space = dp2px(5f);
        shadowRadius = dp2px(2f);

        setWillNotDraw(false);
        // Load attributes
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CuteIndicator, defStyle, 0);

        indicatorColor = a.getColor(R.styleable.CuteIndicator_IndicatorColor, indicatorColor);
        indicatorSelectColor = a.getColor(R.styleable.CuteIndicator_IndicatorSelectColor, indicatorSelectColor);
        shadowColor = a.getColor(R.styleable.CuteIndicator_IndicatorShadowColor, shadowColor);
        selectedWidth = a.getDimension(R.styleable.CuteIndicator_IndicatorSelectedWidthDimension, selectedWidth);
        dia = a.getDimension(R.styleable.CuteIndicator_IndicatorDiaDimension, dia);
        space = a.getDimension(R.styleable.CuteIndicator_IndicatorSpaceDimension, space);
        shadowRadius = a.getDimension(R.styleable.CuteIndicator_IndicatorShadowRadiusDimension, shadowRadius);
        isAnimation = a.getBoolean(R.styleable.CuteIndicator_IndicatorIsAnimation, isAnimation);
        isShadow = a.getBoolean(R.styleable.CuteIndicator_IndicatorIsShadow, isShadow);

        a.recycle();

        if (isShadow) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(indicatorColor);
        paint.setStyle(Paint.Style.FILL);
        if (isShadow) {
            paint.setShadowLayer(shadowRadius, shadowRadius / 2, shadowRadius / 2, shadowColor);
        }
    }


    public void setupWithViewPager(final ViewPager viewPager) {
        if (viewPager.getAdapter() == null) {
            Logger.e("viewPager adapter not be null");
            return;
        }

        setWH(viewPager);
        viewPager.getAdapter().registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                setWH(viewPager);
            }
        });

        viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);
                if (isAnimation) {
                    firstVisiblePosition = position;
                    lastPositionOffset = positionOffset;
                    invalidate();
                }
            }

            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                if (!isAnimation) {
                    firstVisiblePosition = position;
                    invalidate();
                }
            }

        });
    }

    private void setWH(ViewPager viewPager) {
        itemCount = viewPager.getAdapter().getCount();
        if (isShadow) {
            getLayoutParams().width = (int) ((itemCount - 1) * (space + dia) + selectedWidth + shadowRadius);
            getLayoutParams().height = (int) (dia + shadowRadius);
        } else {
            getLayoutParams().width = (int) ((itemCount - 1) * (space + dia) + selectedWidth);
            getLayoutParams().height = (int) dia;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isInEditMode() || itemCount == 0) {
            return;
        }

        for (int i = 0; i < itemCount; i++) {

            float left;
            float right;

            paint.setColor(indicatorColor);
            if (i < firstVisiblePosition) {
                left = i * (dia + space);
                right = left + dia;
            } else if (i == firstVisiblePosition) {
                left = i * (dia + space);
                right = left + dia + (selectedWidth - dia) * (1 - lastPositionOffset);
            } else if (i == firstVisiblePosition + 1) {
                left = (i - 1) * (space + dia) + dia + (selectedWidth - dia) * (1 - lastPositionOffset) + space;
                right = i * (space + dia) + selectedWidth;
            } else {
                left = (i - 1) * (dia + space) + (selectedWidth + space);
                right = (i - 1) * (dia + space) + (selectedWidth + space) + dia;
            }

            float top = 0f;
            float bottom = dia;

            rectf.left = left;
            rectf.top = top;
            rectf.right = right;
            rectf.bottom = bottom;

            if (i == firstVisiblePosition) {
                paint.setColor(indicatorSelectColor);
            }
            canvas.drawRoundRect(rectf, dia / 2, dia / 2, paint);
        }
    }


    private float dp2px(float dpValue) {
        return dpValue * getContext().getResources().getDisplayMetrics().density;
    }

}
    <declare-styleable name="CuteIndicator">
        <attr name="IndicatorColor" format="color"/>
        <attr name="IndicatorSelectColor" format="color"/>
        <attr name="IndicatorShadowColor" format="color"/>
        <attr name="IndicatorSelectedWidthDimension" format="dimension"/>
        <attr name="IndicatorDiaDimension" format="dimension"/>
        <attr name="IndicatorSpaceDimension" format="dimension"/>
        <attr name="IndicatorShadowRadiusDimension" format="dimension"/>
        <attr name="IndicatorIsAnimation" format="boolean"/>
        <attr name="IndicatorIsShadow" format="boolean"/>
    </declare-styleable>

相关文章

网友评论

      本文标题:底部指示器【借鉴他人+做了部分优化】

      本文链接:https://www.haomeiwen.com/subject/uzdnpktx.html