美文网首页高级UIAndroid自定义View
Android自定义Tab 滑动指示条

Android自定义Tab 滑动指示条

作者: 小白彡 | 来源:发表于2020-05-11 20:53 被阅读0次

    最近在项目中有用到Tab,Tab下面有个指示条,一般来说可以使用用官方的TabLayout做,但官方提供的Tab指示器太不灵活,没法做到更换任意图形,,,于是自己尝试弄一下了,
    先看一下效果:


    20200511203638.gif

    再看一下如何使用:

    //第一排
            scrollIndicator = findViewById(R.id.scrollIndicatorone);
            llParent = findViewById(R.id.ll_parentone);
    
            //第二排
            scrollIndicatorTwo = findViewById(R.id.scrollIndicatortwo);
            llParentTwo = findViewById(R.id.ll_parenttwo);
    
            //第一排
            scrollIndicator
                    .setWith(20)
                    .setHigh(4)
                    .setColor(ContextCompat.getColor(this, R.color.colorAccent))
                    .setViewGroup(llParent)
                    .setPosition(0);
    
            //第二排
            scrollIndicatorTwo
                    //宽
                    .setWith(40)
                    //高
                    .setHigh(4)
                    //圆角
                    .setRound(10)
                    //颜色
                    .setColor(ContextCompat.getColor(this, R.color.colorAccent))
                    //文字父容器
                    .setViewGroup(llParentTwo)
                    //初始显示
                    .setPosition(0);
    

    scrollIndicator就是自定义的指示器,使用的时候可以设置宽度,高度,圆角,颜色等,基本满足我这项目的需求,当然,光是这样的话和官方的区别也不大, 但这个最灵活的就是scrollIndicator继承自View,可以在onDraw中任意改变形状,可以变三角形,变水滴, 变五角形,任何形状都是可以绘制的, 而且scrollIndicator和显示的文字是分离的,没有一点耦合,可以随意增删,关联只需调用

                    //文字父容器
                    .setViewGroup(llParentTwo)
    

    将文字的父容器传进去即可,再加上属性动画,感觉也还可以。。。。
    下面帖一下全部代码:

    public class ScrollIndicator extends View {
        private Paint paint;
        private int with;
        private int high;
        private int round;
        private RectF rectF;
        private ViewGroup viewGroup;
        private int startWith;
        private int color;
        private int defaulteWith;
        private int defaulteHigh;
        //父容器是否加载完
        private boolean isLoad;
    
        public ScrollIndicator(Context context) {
            super(context);
            init();
        }
    
        public ScrollIndicator(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public ScrollIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init(){
            paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            paint.setStrokeWidth(1);
            paint.setAntiAlias(true);
            paint.setDither(true);
            rectF = new RectF();
    
            defaulteWith = SizeUtils.dp2px(20);
            defaulteHigh = SizeUtils.dp2px(4);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            paint.setColor(color);
            rectF.set(startWith, 0,startWith + with, high);
            canvas.drawRoundRect(rectF, round, round, paint);
        }
    
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int withModel = MeasureSpec.getMode(widthMeasureSpec);
            int highModel = MeasureSpec.getMode(widthMeasureSpec);
    
            int specWith = MeasureSpec.getSize(widthMeasureSpec);
            int specHigh = MeasureSpec.getSize(heightMeasureSpec);
    
            int currentWith;
            int currentHigh;
            switch (withModel){
                case MeasureSpec.AT_MOST:
                    currentWith = defaulteWith;
                    break;
                case MeasureSpec.EXACTLY:
                default:
                    currentWith = specWith;
                    break;
            }
    
            switch (highModel){
                case MeasureSpec.AT_MOST:
                    currentHigh = defaulteHigh;
                    break;
                case MeasureSpec.EXACTLY:
                default:
                    currentHigh = specHigh;
                    break;
            }
    
            setMeasuredDimension(currentWith, currentHigh);
        }
    
        public ScrollIndicator setWith(int with){
            this.with = SizeUtils.dp2px(with);
            return this;
        }
    
        public ScrollIndicator setHigh(int high){
            this.high = SizeUtils.dp2px(high);
            return  this;
        }
    
        public ScrollIndicator setColor(int color){
            this.color = color;
            return this;
        }
    
        public ScrollIndicator setRound(int round){
            this.round = SizeUtils.dp2px(round);
            return this;
        }
    
        public ScrollIndicator setViewGroup(ViewGroup viewGroup){
            this.viewGroup = viewGroup;
            return this;
    
        }
    
        public void setPosition(final int position){
            if(isLoad){
                int listCenter = (viewGroup.getChildAt(position).getRight() + viewGroup.getChildAt(position).getLeft())/2;
                int endWith = listCenter - with/2;
                startAnim(startWith,endWith);
                startWith = listCenter - with/2;
            }else{
                viewGroup.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        int listCenter = (viewGroup.getChildAt(position).getRight() + viewGroup.getChildAt(position).getLeft())/2;
                        int endWith = listCenter - with/2;
                        startAnim(startWith,endWith);
                        startWith = listCenter - with/2;
    
                        isLoad = true;
                    }
                },100);
            }
        }
    
    
        public void startAnim(int startWith, int endwith){
            ValueAnimator valueAnimator = ValueAnimator.ofInt(startWith, endwith);
            valueAnimator.setDuration(100);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    ScrollIndicator.this.startWith = (int) animation.getAnimatedValue();
                    postInvalidate();
                }
            });
            valueAnimator.start();
        }
    }
    

    完。

    相关文章

      网友评论

        本文标题:Android自定义Tab 滑动指示条

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