Android怎么自定义View

目录标题

  • 效果预览
  • 实现
    • attrs文件
    • 创建自定义View
    • 重点讲解
      • 获取属性
      • 计算文字位置
        • 计算baseLine
        • 计算文字开横坐标

效果预览

实现

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; 

本文地址:https://blog.csdn.net/zhu18538731252/article/details/107760320

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐