自定义UI——带文字进度条的绘制

直接上效果:

分五部分:绘制文字、绘制已完成进度,间隙,未完成进度,下面的小三角

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画文字
        drawText(canvas);
        progress = textWidth * index + textWidth / 2;
        //画左边的线
        drawLeftLine(canvas);

        drawMidLine(canvas);

        drawRightLine(canvas);

        drawTriangle(canvas);
    }

    /**
     * 绘制文字
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        if (textList.size() > 0) {
            textWidth = mWidth / textList.size();
            mPaint.setColor(textColor);
            mPaint.setTextSize(textSize);
            for (int i = 0; i < textList.size(); i++) {
                String text = textList.get(i);
                float size = text.length() * textSize;
                //为保证间隙在中间
                canvas.drawText(textList.get(i),
                        paddingLeft + textWidth * i + textWidth / 2 - size / 2, textSize, mPaint);
            }
        }
    }

    /**
     * 绘制三角
     * @param canvas
     */
    private void drawTriangle(Canvas canvas) {
        float startX = progress;
        float startY = textSize + TEXT_LINE_SPAEC + progressHeight;
        float leftX = progress - angleSize;
        float leftY = textSize + TEXT_LINE_SPAEC + progressHeight + angleSize;
        float rightX = progress + angleSize;
        float rightY = textSize + TEXT_LINE_SPAEC + progressHeight + angleSize;
        mPaint.setColor(angleColor);
        //实例化路径
        Path path = new Path();
        path.moveTo(startX, startY);// 此点为多边形的起点
        path.lineTo(leftX, leftY);
        path.lineTo(rightX, rightY);
        path.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(path, mPaint);
    }

    /**
     * 未完成的进度条
     * @param canvas
     */
    private void drawRightLine(Canvas canvas) {
        float left = progress + spaceWidth / 2;
        float top = textSize + TEXT_LINE_SPAEC;
        float right = mWidth;
        float bottom = textSize + TEXT_LINE_SPAEC + progressHeight;
        mPaint.setColor(rightColor);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(left, top, right, bottom, mPaint);
    }

    /**
     * 中间间隙
     * @param canvas
     */
    private void drawMidLine(Canvas canvas) {
        float left = progress - spaceWidth / 2;
        float right = progress + spaceWidth / 2;
        float top = textSize + TEXT_LINE_SPAEC;
        float bottom = textSize + TEXT_LINE_SPAEC + progressHeight;
        Log.e("angle:", "----------" + left);
        mPaint.setColor(spaceColor);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(left, top, right, bottom, mPaint);
    }

    /**
     * 完成的进度条
     * @param canvas
     */
    private void drawLeftLine(Canvas canvas) {
        float left = paddingLeft;
        float right = progress - spaceWidth / 2;
        float top = textSize + TEXT_LINE_SPAEC;
        float bottom = textSize + TEXT_LINE_SPAEC + progressHeight;
        mPaint.setColor(leftColor);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(left, top, right, bottom, mPaint);
    }

attrs文件:

 <declare-styleable name="ProgressView">
        <attr name="progressHeight" format="dimension" />
        <attr name="textSize" format="dimension" />
        <attr name="textColor" format="color" />
        <attr name="spaceColor" format="color" />
        <attr name="spaceWidth" format="dimension" />
        <attr name="angleHeight" format="dimension" />
        <attr name="finishColor" format="color" />
        <attr name="noFinishColor" format="color" />
        <attr name="angleColor" format="color" />
    </declare-styleable>

在7.0以上View运行机制发生改变在onMeasure()方法中获取的view宽度为0,导致绘制全部重叠,解决方案如下

 /**
     * 解决7.0以上获取宽为0的情况
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    mWidth = getMeasuredWidth();
                    invalidate();
                }
            }
        });
    }

具体使用可以移步demo

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值