废话不多说先看效果图
原谅模拟器显示的不好看,为了录GIF图,只能用模拟器
思路分析
一个背景,一个进度,一个进度值显示,进度条与文字显示的高度是1:2,其中用到了drawRoundRect用来画带圆角的矩形,空心与实心都是Paint的属性设置的,drawText用来画文字
注意点:
1.进度条进度满进度与未满进度,计算onewidth = mwidth / mMaxProgress(单位进度占的宽度=总宽度/满进度);
2.文字显示,先计算文字的宽度,三个状态(起始位置 <= 文字宽度 / 当前位置 +文字宽度>=宽度/之间的),分别进行计算
实现
onDraw来画图了
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = onewidth * mCurrentProgress;
//画背景
RectF rectF = new RectF(0, 0, mwidth, bheight);
canvas.drawRoundRect(rectF, num8, num8, backgroudPaint);
//画进度条
RectF rectFm;
if (mCurrentProgress == mMaxProgress) {
rectFm = new RectF(num2, num2, mwidth - num2, bheight - num2);
} else {
rectFm = new RectF(num2, num2, x + num2, bheight - num2);
}
canvas.drawRoundRect(rectFm, num8, num8, mPaint);
//画文字
//获取文字的宽度及其高度
Rect rect = new Rect();
String speed = mCurrentProgress + "%";
txtPaint.getTextBounds(speed, 0, speed.length(), rect);
textheight = rect.height();
textwidth = rect.width();
if (mCurrentProgress == mMaxProgress) {
canvas.drawText(speed, mwidth - textwidth, txtheight, txtPaint);
} else {
//起始位置 <= 文字宽度
if (x <= textwidth) {
canvas.drawText(speed, textwidth / 2, txtheight, txtPaint);
//当前位置 +文字宽度>=宽度
} else if (x + textwidth >= mwidth) {
canvas.drawText(speed, mwidth - textwidth - 2 * num8, txtheight, txtPaint);
} else {
canvas.drawText(speed, x - textwidth / 2, txtheight, txtPaint);
}
}
}设置进度
public void setProgress(int progress) {
if (progress <= 100 && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
}实际项目中,可有很多的扩展,但是有时候实际项目不需要把很多不需要的方法,设置属性的方法等给写出来,根据项目的需求去写相关方法、属性设置
完整代码
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.numberview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by wujun on 2017/9/20.
*
* @author madreain
* @desc
*/
public class NumberView1 extends View {
Paint backgroudPaint;
Paint mPaint;
Paint txtPaint;
//宽高
int mwidth, mheight;
int bheight, txtheight;
private int mMaxProgress = 100;
private int mCurrentProgress = 0;
private float onewidth;
//文字显示的宽高
int textheight;
int textwidth;
float num8;
float num2;
// 30 10 20
public NumberView1(Context context) {
super(context);
init();
}
public NumberView1(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public NumberView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
backgroudPaint = new Paint();
backgroudPaint.setAntiAlias(true);
backgroudPaint.setStyle(Paint.Style.STROKE);
backgroudPaint.setStrokeCap(Paint.Cap.ROUND);
backgroudPaint.setColor(Color.rgb(51, 197, 167));
txtPaint = new Paint();
txtPaint.setAntiAlias(true);
txtPaint.setStyle(Paint.Style.FILL);
txtPaint.setColor(Color.rgb(51, 197, 167));
txtPaint.setTextSize(sp2px(12));
txtPaint.setStrokeWidth(2);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(Color.rgb(51, 197, 167));
num8 = dp2px(8);
num2 = dp2px(2);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mwidth = w;
mheight = h;
bheight = mheight / 3;
txtheight = bheight * 2;
onewidth = mwidth / mMaxProgress;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float x = onewidth * mCurrentProgress;
//画背景
RectF rectF = new RectF(0, 0, mwidth, bheight);
canvas.drawRoundRect(rectF, num8, num8, backgroudPaint);
//画进度条
RectF rectFm;
if (mCurrentProgress == mMaxProgress) {
rectFm = new RectF(num2, num2, mwidth - num2, bheight - num2);
} else {
rectFm = new RectF(num2, num2, x + num2, bheight - num2);
}
canvas.drawRoundRect(rectFm, num8, num8, mPaint);
//画文字
//获取文字的宽度及其高度
Rect rect = new Rect();
String speed = mCurrentProgress + "%";
txtPaint.getTextBounds(speed, 0, speed.length(), rect);
textheight = rect.height();
textwidth = rect.width();
if (mCurrentProgress == mMaxProgress) {
canvas.drawText(speed, mwidth - textwidth, txtheight, txtPaint);
} else {
//起始位置 <= 文字宽度
if (x <= textwidth) {
canvas.drawText(speed, textwidth / 2, txtheight, txtPaint);
//当前位置 +文字宽度>=宽度
} else if (x + textwidth >= mwidth) {
canvas.drawText(speed, mwidth - textwidth - 2 * num8, txtheight, txtPaint);
} else {
canvas.drawText(speed, x - textwidth / 2, txtheight, txtPaint);
}
}
}
public float dp2px(float dp) {
final float scale = getResources().getDisplayMetrics().density;
return dp * scale + 0.5f;
}
public float sp2px(float sp) {
final float scale = getResources().getDisplayMetrics().scaledDensity;
return sp * scale;
}
public void setProgress(int progress) {
if (progress <= 100 && progress >= 0) {
this.mCurrentProgress = progress;
invalidate();
}
}
}自定义view多写多练