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

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

作者: 初见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