项目中需要同步硬件设备的数据,显示大概百分比和实时数据。自定义的控件。
简介
- 用户目前数量。
- 设置单位。
- 根据颜色来判断目前所占总数的大概百分比。
特点
-
项目中使用
可以在代码或xml中设置 当前数目和背景的颜色,当前数目和单位的字体,颜色,大小。
使用简单,可以直接在xml中或者动态代码中设置对应的属性,代码中设置的属性会覆盖xml中的属性。
功能的设计
- 按照要求宽和高相同onMeasure的代码
//测量控件的大小,以为是一个圆,所以用最小的数字作为他们的直径的长度。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
setMeasuredDimension(size, size);
}
- 绘制onDraw(),一条直线,然后去旋转
- 画直线
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mLineLength, mPaint);
起始点为(width/2,0)就是控件的中心点的正上方,坐标的-90°位置。
- 旋转
canvas.rotate(mDrgees, getWidth() / 2, getHeight() / 2);
以控件的中心点为原点,以设定的角度去旋转,在for中循环执行。
-
颜色
占有百分比和背景颜色,在for循环前设定。如下代码
//设置未被选中的直线的颜色。
mPaint.setColor(mUnSelectColor);
for (int i = 0; i < mSumLine - mSelectLine; i++) {
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mLineLength, mPaint);
canvas.rotate(mDrgees, getWidth() / 2, getHeight() / 2);
}
//设置数量字体的颜色
mPaint.setColor(mNumColor);
if (!TextUtils.isEmpty(mNumShow)) {
mPaint.setTextSize(mNumTextSize);
mPaint.getTextBounds(mNumShow, 0, mNumShow.length(), mNumShowRect);
}
-
字体
设定字体的颜色,和范围。
//设置数量字体的颜色
mPaint.setColor(mNumColor);
if (!TextUtils.isEmpty(mNumShow)) {
mPaint.setTextSize(mNumTextSize);
mPaint.getTextBounds(mNumShow, 0, mNumShow.length(), mNumShowRect);
}
if(!TextUtils.isEmpty(mNumShow)){
canvas.drawText(mNumShow, (getWidth() / 2 - mNumShowRect.width() / 2), (getHeight() / 2 + mNumShowRect.height() / 2)
, mPaint);
}
以上就是主要的代码实现。主要就是ondraw()中代码的实现。
属性和样式
属性 | 对应变量 | 类型 | 默认值 |
---|---|---|---|
选中直线颜色 | select_color | color | Color.BLUE |
未选中直线颜色 | select_color | color | Color.GRAY |
数量字体颜色 | num_color | color | Color.BLACK |
单位字体颜色 | unit_color | color | Color.BLACK |
数量文字 | num_text | String | -- |
单位文字 | unit_text | String | -- |
数量文字大小 | num_text_size | dimension | 30px |
数量文字大小 | unit_text_size | dimension | 18px |
总直线数目 | all_line_num | integer | 36 |
直线长度 | line_height | dimension | 10px |
直线宽度 | line_width | dimension | 2px |
源码
- 控件代码
public class PercentageCircle extends View {
//初始化画笔
private Paint mPaint;
//设置没有被选中的颜色。
private int mSelectColor;
//设置选中后的颜色。
private int mUnSelectColor;
//设置数字的颜色
private int mNumColor;
//设置单位的颜色
private int mUnitColor;
//设置单位字体的大小。
private float mUnitTextSize;
//设置数目字体的大小。
private float mNumTextSize;
//总的数目
private int mSumLine;
//旋转的角度
private float mDrgees;
//dp转换为px。。line的长度
private float mLineLength;
//line的宽度。
private float mLineWidth;
//初始化被选中的数目
private int mSelectLine = 0;
//设置控件的单位
private String mUnit;
//设置控件的单位
private String mNumShow;
//设置字体的范围
private Rect mUnitRect;
//设置字体的范围
private Rect mNumShowRect;
public PercentageCircle(Context context) {
this(context, null);
}
public PercentageCircle(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PercentageCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//属性集合
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PercentageCircle);
//设置没被选中的默认的颜色为灰色。
mUnSelectColor = array.getColor(R.styleable.PercentageCircle_unselect_color, Color.GRAY);
//设置默认被选中的颜色为蓝色。
mSelectColor = array.getColor(R.styleable.PercentageCircle_select_color, Color.BLUE);
//设置字体和单位的默认的颜色为灰色。
mNumColor = array.getColor(R.styleable.PercentageCircle_num_color, Color.BLACK);
mUnitColor = array.getColor(R.styleable.PercentageCircle_unit_color, Color.BLACK);
//设置字体的大小和默认值
mUnitTextSize = array.getDimensionPixelOffset(R.styleable.PercentageCircle_unit_text_size, (int) dp2px(18));
mNumTextSize = array.getDimensionPixelOffset(R.styleable.PercentageCircle_num_text_size, (int) dp2px(30));
//设置总的数目
mSumLine = array.getInt(R.styleable.PercentageCircle_all_line_num, 36);
//单位的文本
mUnit = array.getString(R.styleable.PercentageCircle_unit_text);
mNumShow = array.getString(R.styleable.PercentageCircle_num_text);
//设置直线的宽度
mLineWidth = array.getDimensionPixelOffset(R.styleable.PercentageCircle_line_width, (int) dp2px(2));
//长度
mLineLength = array.getDimensionPixelOffset(R.styleable.PercentageCircle_line_length, (int) dp2px(10));
array.recycle();
//实例化画笔
mPaint = new Paint();
//抗锯齿
mPaint.setAntiAlias(true);
//设置宽度
mPaint.setStrokeWidth(mLineWidth);
//设置数目字体的范围,用来得到 字体的宽和高。
mNumShowRect = new Rect();
//设置单位字体的范围。
mUnitRect = new Rect();
}
//测量控件的大小,以为是一个圆,所以用最小的数字作为他们的直径的长度。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
setMeasuredDimension(size, size);
}
//绘制控件
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置每个间隔的旋转的角度.等于360/总数目的个数。
mDrgees = 360 / mSumLine;
Log.i("111", mDrgees + "hha");
canvas.save();
//设置被选中的直线的颜色
mPaint.setColor(mSelectColor);
for (int i = 0; i < mSelectLine; i++) {
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mLineLength, mPaint);
canvas.rotate(mDrgees, getWidth() / 2, getHeight() / 2);
}
//设置未被选中的直线的颜色。
mPaint.setColor(mUnSelectColor);
for (int i = 0; i < mSumLine - mSelectLine; i++) {
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mLineLength, mPaint);
canvas.rotate(mDrgees, getWidth() / 2, getHeight() / 2);
}
//设置数量字体的颜色
mPaint.setColor(mNumColor);
if (!TextUtils.isEmpty(mNumShow)) {
mPaint.setTextSize(mNumTextSize);
mPaint.getTextBounds(mNumShow, 0, mNumShow.length(), mNumShowRect);
}
if(!TextUtils.isEmpty(mNumShow)){
canvas.drawText(mNumShow, (getWidth() / 2 - mNumShowRect.width() / 2), (getHeight() / 2 + mNumShowRect.height() / 2)
, mPaint);
}
// canvas.drawText(mNumShow, (getWidth() / 2 - mNumShowRect.width() / 2), (getHeight() / 2 + mNumShowRect.height() / 2)
// , mPaint);
Log.i("111",mNumShow +"---"+ (getWidth() / 2 - mNumShowRect.width() / 2) + "===" + (getHeight() / 2 + mNumShowRect.height() / 2));
//设置单位字体的颜色。
mPaint.setColor(mUnitColor);
if (!TextUtils.isEmpty(mUnit)) {
mPaint.setTextSize(mUnitTextSize);
mPaint.getTextBounds(mUnit, 0, mUnit.length(), mUnitRect);
}
if(!TextUtils.isEmpty(mUnit)){
canvas.drawText(mUnit, getWidth() / 2 - mUnitRect.width() / 2, getHeight() / 2 + mNumShowRect.height() / 2
+ mUnitRect.height() / 2 + dp2px(20), mPaint);
}
canvas.restore();
}
//设置被选中的数目。
public void setSumSelect(int num) {
if (num > mSumLine) {
num = mSumLine;
}
if (num < 0) {
num = 0;
}
this.mSelectLine = num;
invalidate();
}
//设置单位文字
public void setUnit(String unit) {
if (!TextUtils.isEmpty(unit)) {
this.mUnit = unit;
}
invalidate();
}
//设置单位颜色
public void setUnitColor(int color) {
if (!TextUtils.isEmpty(mUnit)) {
this.mUnitColor = color;
}
invalidate();
}
//设置单位字体大小
public void setUnitTextSize(int size) {
if (!TextUtils.isEmpty(mUnit)) {
this.mUnitTextSize = size;
}
invalidate();
}
//设置数量的文字
public void setNumText(String numText) {
if (!TextUtils.isEmpty(numText)) {
this.mNumShow = numText;
}
invalidate();
}
//设置没有被选中的颜色
public void setUnSelectColor(int color) {
this.mUnSelectColor = color;
}
//设置被选中的颜色
public void setSelectColor(int color) {
this.mSelectColor = color;
}
//设置数量颜色
public void setmNumColor(int color) {
if (!TextUtils.isEmpty(String.valueOf(color))) {
this.mNumColor = color;
}
invalidate();
}
//设置数量字体大小
public void setNumTextSize(int size) {
if (!TextUtils.isEmpty(String.valueOf(size))) {
this.mNumTextSize = size;
}
invalidate();
}
//设置数目
public void setNumShow(String show) {
if (!TextUtils.isEmpty(show)) {
this.mNumShow = show;
}
invalidate();
}
//设置直线的宽度。
public void setLineWidth(int width) {
this.mLineWidth = width;
}
//设置直线的高度。
public void setLineLength(int length) {
this.mLineLength = length;
}
//dp转化为px
private float dp2px(float dpVal) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, getResources().getDisplayMetrics());
}
}
- 属性
<declare-styleable name="PercentageCircle">
<!--被选中的文字的颜色-->
<attr name="select_color" format="color"/>
<!--没有被选中的文字的颜色-->
<attr name="unselect_color" format="color"/>
<!--数量单位的文字的颜色-->
<attr name="unit_color" format="color"/>
<!--数量文字的颜色-->
<attr name="num_color" format="color"/>
<!--数量单位的文字-->
<attr name="unit_text" format="string"/>
<!--数量的字体size大小-->
<attr name="num_text" format="string"/>
<!--数量单位的文字-->
<attr name="unit_text_size" format="dimension"/>
<!--数量的字体size大小-->
<attr name="num_text_size" format="dimension"/>
<!--总数目的直线的条数-->
<attr name="all_line_num" format="integer"/>
<!--间隔的角度的大小-->
<!--<attr name="interval_degree" format="integer"/>-->
<!--直线的宽度的大小-->
<attr name="line_width" format="dimension"/>
<!--直线的长度-->
<attr name="line_length" format="dimension"/>
</declare-styleable>
- 代码
//可以动态的设置自定义view的属性。也可以在xml中设置属性。
//设置被选中的数量。
percentageCircle.setSumSelect(20);
/**
* 1:可以直接在代码中动态设置。
* 2:动态设置的会把 xml中设置的 数量和文字覆盖掉。
*/
//设置显示的数量。
percentageCircle.setNumShow(60+"");
//设置单位文字
percentageCircle.setUnit("口数");
percentageCircle.setUnSelectColor(Color.BLACK);
percentageCircle.setSelectColor(Color.RED);
percentageCircle.setUnitColor(Color.GREEN);
percentageCircle.setmNumColor(Color.MAGENTA);
源码
Github的源码地址-->PercentageCircle
使用
在model的build.gradle中添加
'compile 'com.cyy:PercentageCircle:1.0.2'