自定义View-01-自定义计步器

效果预览

在这里插入图片描述

实现

attrs文件

// 创建attrs.xml(values的目录下面)文件 用来自定义View的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="textColor" format="color"/>
    <attr name="textSize" format="dimension"/>
    <attr name="minNumber" format="integer"/>
    <attr name="maxNumber" format="integer"/>
    <attr name="currentNumber" format="integer"/>
    <attr name="bgColor" format="color"/>
    <attr name="foreColor" format="color"/>
    <attr name="strokeWidth" format="dimension"/>


    <declare-styleable name="StepView">
        <attr name="textColor"/>
        <attr name="textSize"/>
        <attr name="minNumber"/>
        <attr name="maxNumber"/>
        <attr name="bgColor"/>
        <attr name="foreColor"/>
        <attr name="strokeWidth"/>
        <attr name="currentNumber"/>
    </declare-styleable>
</resources>

创建自定义View

// 1/创建StepView 继承 View
// 2/初始化相关属性与Paint
public StepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // width

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StepView);
        textColor = typedArray.getColor(R.styleable.StepView_textColor, textColor);
        textSize = typedArray.getDimensionPixelSize(
                R.styleable.StepView_textSize,
                dip2px(context, textSize));
        minNumber = typedArray.getInt(R.styleable.StepView_minNumber, minNumber);
        maxNumber = typedArray.getInt(R.styleable.StepView_maxNumber, maxNumber);
        currentStep = typedArray.getInt(R.styleable.StepView_currentNumber, currentStep);
        if (currentStep < minNumber) currentStep = minNumber;
        if (currentStep > maxNumber) currentStep = maxNumber;
        bgColor = typedArray.getColor(R.styleable.StepView_bgColor, bgColor);
        foreColor = typedArray.getColor(R.styleable.StepView_foreColor, foreColor);
        strokeWidth = typedArray.getDimensionPixelSize(
                R.styleable.StepView_strokeWidth,
                dip2px(context, strokeWidth));


        initPaint();
        typedArray.recycle();

    }
private void initPaint() {
        textPaint = new Paint();
        textPaint.setAntiAlias(true); // 抗锯齿
        textPaint.setTextSize(textSize);
        textPaint.setColor(textColor);

        bgPaint = new Paint();
        bgPaint.setAntiAlias(true);
        bgPaint.setColor(bgColor);
        bgPaint.setStrokeWidth(strokeWidth);
        bgPaint.setStyle(Paint.Style.STROKE);    // 绘制边框,不填充
        bgPaint.setStrokeCap(Paint.Cap.ROUND);   // 设置画的线头尾是圆的

        forePaint = new Paint();
        forePaint.setAntiAlias(true);
        forePaint.setColor(foreColor);
        forePaint.setStrokeWidth(strokeWidth);
        forePaint.setStyle(Paint.Style.STROKE);    // 绘制边框,不填充
        forePaint.setStrokeCap(Paint.Cap.ROUND);   // 设置画的线头尾是圆的
    }

// 3/重写onDraw方法
Rect textBounds = new Rect();
    int width = 0;
    int height = 0;
    RectF rectF;

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

        if (width == 0 || height == 0) {
            width = getMeasuredWidth();
            height = getMeasuredHeight();

            if (width > height) {
                width = height;
            } else {
                height = width;
            }
            rectF = new RectF(strokeWidth/2f, strokeWidth/2f, width - strokeWidth/2f, height - strokeWidth/2f);
        }

        String currentStepString = String.valueOf(currentStep);

        textPaint.getTextBounds(currentStepString, 0, currentStepString.length(), textBounds);
        int startPosition = width/2 - textBounds.width()/2;
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float dy = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
        float baseLine = height/2f + dy;
        canvas.drawText(currentStepString, startPosition, baseLine, textPaint);

        canvas.drawArc(rectF, 135, 270, false, bgPaint);
        float rate = currentStep * 1f / maxNumber;
        if (rate < 0) rate = 0;
        if (rate > 1) rate = 1;
        canvas.drawArc(rectF, 135, 270 * rate, false, forePaint);
    }

重点讲解

获取属性

// 通过此方式获取自定义的属性值
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StepView);
textColor = typedArray.getColor(R.styleable.StepView_textColor, textColor);
typedArray.recycle();

计算文字位置

计算baseLine
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float dy = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
float baseLine = height/2f + dy;
计算文字开横坐标
Rect textBounds = new Rect();
textPaint.getTextBounds(currentStepString, 0, currentStepString.length(), textBounds);
int startPosition = width/2 - textBounds.width()/2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值