Android自定义View(环形进度条)

1 前言

自定义view是android的一个难点,逃避了那么久, 现在觉得不会的东西还是得要从基础补起来,自定义进度条网上也一大堆,这篇文章只是一个入门的学习笔记,高手请略过...

2 view的工作流程

这里只说自定义环形进度条,比较入门级,所以只做简单介绍,显得简洁,看着舒服,后续会讲详细的流程方法,所以先来看看view的大体工作流程。
a) measure 确实view的测量宽/高 (测三围,看五官)
b) layout 确定view的四个顶点的位置 (站在舞台位置)
c} ondraw 将view绘制到屏幕上 (打扮好出场)

3 工作图

Android自定义View(环形进度条)_第1张图片

4 流程步骤

  • 自定义view的相关属性
 // 圆环的颜色
    private int ringColor = 0xFF00FF00;
    // 圆环进度的颜色
    private int ringProgressColor = 0xFFFF0000;
    //圆环的宽度
    private int ringWidth = 10;
    // 字体大小
    private int textSize = 20;
    // 字体颜色
    private int textColor = 0xFF0000FF;
    // 当前进度
    private int currentProgress = 60;
    // 最大进度
    private int maxProgress = 100;
    // 得到控件的宽度
    private int width;
    // 画笔对象
    private Paint paint;
  • 在values下新建attr.xml

    
        
        
        
        
        
        
        
    
  • 通过TypedArray获取自定义view的相关属性
 public RingProgressView(Context context) {
        this(context, null);
    }

    public RingProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RingProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        // 得到自定义资源数组
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingProgressView);
        ringColor = typedArray.getColor(R.styleable.RingProgressView_ringColor, ringColor);
        ringProgressColor = typedArray.getColor(R.styleable.RingProgressView_ringProgressColor, ringProgressColor);
        ringWidth = (int) typedArray.getDimension(R.styleable.RingProgressView_ringWidth, dip2px(10));
        textSize = (int) typedArray.getDimension(R.styleable.RingProgressView_textSize, dip2px(20));
        textColor = typedArray.getColor(R.styleable.RingProgressView_textColor, textColor);
        currentProgress = typedArray.getInt(R.styleable.RingProgressView_currentProgress, currentProgress);
        maxProgress = typedArray.getColor(R.styleable.RingProgressView_maxProgress, maxProgress);
        typedArray.recycle();

        paint = new Paint();
        // 抗锯齿
        paint.setAntiAlias(true);
    }
  • 画同心圆
 // 1. 计算圆心坐标及半径
  float centerX = width / 2;
  float centerY = width / 2;
  float radius = width / 2 - ringWidth / 2;

  // 2. 画圆环
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(ringWidth);
  paint.setColor(ringColor);
  canvas.drawCircle(centerX, centerY, radius, paint);
  • 画圆弧进度
        // 3. 画圆弧
        RectF rectF = new RectF(ringWidth / 2, ringWidth / 2, width - ringWidth / 2, width - ringWidth / 2);
        paint.setColor(ringProgressColor);
        canvas.drawArc(rectF, 0, currentProgress * 360 / maxProgress, false, paint);
  • 画百分比文本框
        // 3. 画文本
        String text = currentProgress * 100 / maxProgress + "%";
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        // 要重新设置宽度为0
        paint.setStrokeWidth(0);
        // 得到指定文本边界的指定大小
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
//        float textWidth = paint.measureText(text);
//        float textHigh = textSize;
        canvas.drawText(text, width / 2 - bounds.width() / 2, width / 2 + bounds.height() / 2, paint);

学习心得

  • 自定义属性

1.通过新建attrs.xml,增加declare-styleable标签来定义相关的属性
2.通过TypedArray获取自定义的资源数组

  • getDimension、getDimensionPixelOffset、getDimensionPixelSize区别

getDimension和getDimensionPixelOffset的功能都是获取某个dimen的值,但是如果单位是dp或sp,则需要将其乘以density。如果是px,则不乘。并且getDimension返回float,getDimensionPixelOffset返回int.
而getDimensionPixelSize则不管写的是dp,sp,px, 都会乘以denstiy.

  • Paint类measureText与getTextBounds的区别

在使用Canvas绘制文字时,需要得到字符串的长度,Paint类内给了两个方法,measureText(),getTextBounds(),但是实际的宽度meauserText()要比getTextBounds()大一点,但是相差不会太大

  • Paint画圆的半径之谜

为什么圆的半径是radius = width / 2 - ringWidth / 2而不是width / 2 或者width / 2 - ringWidth?
其实我们画的是圆环,有宽度的,Paint画刷其实是从圆环的中心点绘制的,所以半径是 width / 2 - ringWidth / 2,如果你不信,看下图:

Android自定义View(环形进度条)_第2张图片
width / 2 - ringWidth

Android自定义View(环形进度条)_第3张图片
width / 2

自定义环形进度条到此结束,感谢你的浏览
完整版代码: 戳这里

你可能感兴趣的:(Android自定义View(环形进度条))