自定义控件-5分钟手写计步器

前言

自定义控件是每个 Android 应用开发者的必备技能,所以一起来试着手写自定义控件,挑战自定义 View 中最好玩的 onDraw.

我们仿照 QQ 计步器的样式来做,主要熟悉画笔(Paint)的使用技巧

自定义控件-5分钟手写计步器_第1张图片

在这里感谢红橙Darren老师的指导

绘制步骤

  • 自定义属性
  • 继承 View
  • 绘制背景圆弧
  • 绘制前景圆弧
  • 绘制文字
  • 设置方法

自定义属性

   // 自定义计步器控件属性
    
        // 背景圆弧颜色
        
        // 前景圆弧颜色
        
        // 圆弧宽度
        
        // 字体颜色
        
        // 字体大小
        
        // 最大步数
        
        // 当前步数
        
    

继承 View

重写三个构造方法,读取自定义属性,重写onDraw

   public FootStepCounterView(Context context) {
        this(context,null);
    }

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

    }

    public FootStepCounterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomFilterView);
        bgViewColor = typedArray.getColor(R.styleable.CustomFilterView_backgroundViewColor, Color.RED);
        fontViewColor = typedArray.getColor(R.styleable.CustomFilterView_fontViewColor,Color.YELLOW);
        stepViewColor = typedArray.getColor(R.styleable.CustomFilterView_stepViewTextColor,Color.YELLOW);
        stepViewTextSize = typedArray.getDimensionPixelSize(R.styleable.CustomFilterView_stepViewTextSize,100);
        stepViewTextColor = typedArray.getColor(R.styleable.CustomFilterView_stepViewTextColor, Color.YELLOW);
        stepViewArcWidth = typedArray.getDimensionPixelOffset(R.styleable.CustomFilterView_stepViewArcWidth,10);
        maxStep = typedArray.getInt(R.styleable.CustomFilterView_maxStepCount,DEFAULT_MAX_STEP);
        mCurrentFootstep = typedArray.getInt(R.styleable.CustomFilterView_currentStepCount, DEFAULT_MAX_STEP);
        typedArray.recycle();
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        stringBuffer = new StringBuffer();
    }

绘制背景圆弧

 private void drawBgArc(Canvas canvas) {
        // 设置画笔: 宽度
        mPaint.setStrokeWidth(stepViewArcWidth);
        // 始末端圆角
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        // 拐角处圆角
     //   mPaint.setStrokeJoin(Paint.Join.ROUND);
        // 实线
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(bgViewColor);
        // 设置可操作区域
     //   RectF rectF = new RectF(left,top,right,bottom);
        canvas.drawArc(rectF,135,270,false,mPaint);
    }
  • 重写onDraw
  @Override
    protected void onDraw(Canvas canvas){
        // 绘制背景圆弧
        drawBgArc(canvas);
        // 绘制上层圆弧
        drawFontArc(canvas);
        // 绘制文字
        drawText(canvas);
    }

绘制前景圆弧

 private void drawFontArc(Canvas canvas) {
        mPaint.setColor(fontViewColor);
        float percentage = (float) ((double)getCurrentFootstep()/(double) maxStep)*100;
        canvas.drawArc(rectF,135,(percentage*270)/100,false,mPaint);
    }

绘制文字

绘制文字时需要注意基线的位置,在这个控件中基线位于整个控件空心点偏下的位置.

private void drawText(Canvas canvas) {
        // 重置画笔
        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(stepViewTextSize);
        mPaint.setColor(stepViewColor);
        // 设置基线

        stringBuffer.append(getCurrentFootstep());
        stringBuffer.append("步");
        Rect rect = new Rect();
        mPaint.getTextBounds(stringBuffer.toString(),0, stringBuffer.toString().length(),rect);
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        int baselineX = ( stepViewWidth - rect.width())/2;
        int baselineY = (stepViewHeight / 2) + (int) (fontMetrics.bottom-fontMetrics.top)/4;
        canvas.drawText(stringBuffer.toString(),baselineX,baselineY,mPaint);
        stringBuffer.setLength(0);
    }

设置方法

计步器需要提供一个设置步数的方法,并在调用此方法时重绘控件来刷新数据

 // 获取当前步数
    public synchronized int getCurrentFootstep() {
        return mCurrentFootstep;
    }
    // 设置当前步数
    public synchronized void setCurrentFootstep(int mCurrentFootstep) {
        this.mCurrentFootstep = mCurrentFootstep;
        invalidate();
    }

你可能感兴趣的:(view,android)