自定义控件画统计图 完成对sd卡内存使用情况
不足之处是在现实180的的时候圆弧没有完全占整个圆环的一半
主类
package com.example.draw;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class TestTUhua extends View {
public TestTUhua(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.initialize();
}
public TestTUhua(Context context, AttributeSet attrs) {
super(context, attrs);
this.initialize();
}
public TestTUhua(Context context) {
super(context);
this.initialize();
}
final String TAG = "TestTUhua";
/** 底部圆环的颜色 */
int remainColor = Color.parseColor("#B5B5B5");
/** 第一个圆环底部颜色 */
int aColor = Color.parseColor("#54DB51");
/** 第二个圆环底部颜色 */
int bColor = Color.parseColor("#FE6D50");
/** 第三个圆环半径超出的部分 */
float outWidth = 10;
/** 文字字体颜色 */
int centerTextColor = Color.parseColor("#61C31D");
/** 描述信息的字体大小 */
float tagTextSize = 30;
/** 描述文字字体颜色 */
int tagTextColor = Color.BLACK;
float horLineWidth = 10;
/** 中心点对象 */
CenterPoint centerPoint = new CenterPoint();
/** 圆的半径 */
float radius;
/** 画圆弧画笔的宽度 */
float paintWidth;
/** 画圆弧画笔对象 */
Paint genPaint;
/** 画中间画笔对象 */
Paint centerTextPaint;
/** 画描述信息画笔对象 */
Paint flagPaint;
final float totalAngle = 360;
float startAngle = 90; //画圆的开始位置,在圆的正下下方
float aAngle = 0; // 第一个弧的旋转角度
float bAngle = 0; // 第二个弧的旋转角度
float remainAngle;
int aPrecent;//a 部分的百分比
int bPrecent;//b 部分的百分比
int remainPrecent;// 剩余部分的百分比
private String totalSizeStr;
double totalSize = 0;
double aSize = 0;
double bSize = 0;
private float centerTextSize;
void initialize(){
genPaint = new Paint();
genPaint.setStyle(Paint.Style.STROKE);
genPaint.setStrokeWidth(paintWidth);
genPaint.setAntiAlias(true);
// 中心文本
centerTextPaint = new Paint();
centerTextPaint.setColor(centerTextColor);
centerTextPaint.setStyle(Paint.Style.STROKE);
centerTextPaint.setStrokeWidth(0);
centerTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
// 指示器画笔
flagPaint = new Paint();
flagPaint.setColor(tagTextColor);
flagPaint.setStyle(Paint.Style.STROKE);
flagPaint.setStrokeWidth(1);
flagPaint.setAntiAlias(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getWidth();
int heigh = getHeight();
centerPoint.centerX = width / 2;
centerPoint.centerY = heigh / 3;
radius = width / 4;
paintWidth = radius / 2;
/** 圆中间字体的大小 */
centerTextSize = (radius - paintWidth /2) / 2;
initialize();
}
void calculateAngle(Double totalSize , Double aSize , Double bSize){
aPrecent = Math.round((float)(aSize * 100 / totalSize));
bPrecent = Math.round((float)(bSize * 100 / totalSize));
remainPrecent = 100 - (aPrecent + bPrecent) < 0 ? 0 : 100 - (aPrecent + bPrecent);
//防止aPrecent + bPrecent 大于100;
bPrecent = 100 - (aPrecent + bPrecent) < 0 ? bPrecent + 100 - (aPrecent + bPrecent) : bPrecent;
aAngle = Math.round((aPrecent / 100f) * totalAngle);
bAngle = Math.round((bPrecent / 100f) * totalAngle);
remainAngle = totalAngle - (aAngle + bAngle) < 0 ? 0 : totalAngle - (aAngle + bAngle);
bAngle = totalAngle - (aAngle + bAngle) < 0 ? bAngle + totalAngle - (aAngle + bAngle) : bAngle;
Log.e(TAG, "aAngle : " + aAngle);
Log.e(TAG, "bAngle : " + bAngle);
this.totalSizeStr = byte2String(totalSize);
}
String byte2String(Double size){
Double temp = size / 1024;
if(temp < 1){
return Math.round(size) + "byte";
}
size = temp;
temp = size / 1024;
if(temp < 1){
return Math.round(size) + "KB";
}
size = temp;
temp = size / 1024;
if(temp < 1){
return Math.round(size) + "MB";
}
size = temp;
temp = size / 1024;
if(temp < 1){
return Math.round(size) + "GB";
}
size = size / 1024;
return Math.round(size) + "TB";
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
calculateAngle(totalSize, aSize, bSize);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
//画一个空白的画布
canvas.drawCircle(centerPoint.centerX, centerPoint.centerY, radius, paint);
//画圆环的半径
float genRadius = radius;
//第一个底部圆
genPaint.setColor(remainColor);
RectF oval1 = new RectF(centerPoint.centerX - genRadius, centerPoint.centerY
- genRadius, centerPoint.centerX + genRadius, centerPoint.centerY
+ genRadius);
canvas.drawArc(oval1,startAngle, totalAngle, false, genPaint);
if(remainPrecent != 0 && remainAngle != 0){
double tempAngle = aAngle + bAngle + remainAngle * 0.5;
drawTag(canvas, genRadius, tempAngle, getPrecent(remainPrecent));
}
//第二个圆弧
if(aPrecent != 0 && bAngle != 0){
//第二个圆弧
genPaint.setColor(aColor);
RectF oval2 = new RectF(centerPoint.centerX - genRadius, centerPoint.centerY
- genRadius, centerPoint.centerX + genRadius, centerPoint.centerY
+ genRadius);
canvas.drawArc(oval2, startAngle, aAngle + bAngle, false, genPaint);
double tempAngle = aAngle * 0.5 + bAngle;
drawTag(canvas, genRadius, tempAngle, getPrecent(aPrecent));
}
//第三个圆弧
if(bPrecent != 0 && bAngle != 0){
//第三个圆弧: 第三个圆需要突出来
genPaint.setColor(bColor);
genPaint.setStrokeWidth(paintWidth + outWidth + 1);//在这里为了防止内边阴影, 加了 1
float bRadius = genRadius + (outWidth * 0.5f) ;
RectF oval3 = new RectF(centerPoint.centerX - bRadius, centerPoint.centerY
- bRadius, centerPoint.centerX + bRadius, centerPoint.centerY
+ bRadius);
canvas.drawArc(oval3, startAngle, bAngle, false, genPaint);
double bTempAngle = bAngle * 0.5;
drawTag(canvas, bRadius, bTempAngle, getPrecent(bPrecent));
}
//中间位置的文本
centerTextPaint.setTextSize(centerTextSize);
float ww = centerTextPaint.measureText(totalSizeStr);
canvas.drawText(totalSizeStr , centerPoint.centerX - ww / 2,
centerPoint.centerY + centerTextSize / 3, centerTextPaint);
}
/**
* 用来返回描述信息
* @param precent
* @return
*/
String getPrecent(int precent){
return precent + "%";
}
/**
* 画区域的标记信息
* @param canvas 画布
* @param radius 圆环的半径
* @param tempAngle 圆弧中心点的角度
* @param txt 标记的描述信息
*/
private void drawTag(Canvas canvas, float radius, double tempAngle,
String txt) {
float relativePointX = (float) Math.sin(tempAngle / 180 * Math.PI) * radius;
float relativePointY = (float) Math.cos(tempAngle / 180 * Math.PI) * radius;
relativePointX = Math.abs(relativePointX);
relativePointY = Math.abs(relativePointY);
float tagPointX = 0;
float tagPointY = 0;
// 连线
float[] pts1 = new float[8];
// 文本
centerTextPaint.setTextSize(tagTextSize);
if(tempAngle <= 90){
Log.e(TAG, tempAngle +"");
tagPointX = centerPoint.centerX - relativePointX;
tagPointY = centerPoint.centerY + relativePointY;
pts1[0] = tagPointX - radius / 40;
pts1[1] = tagPointY + radius / 40;
pts1[2] = tagPointX - 50;
pts1[3] = tagPointY + 40;
pts1[4] = pts1[2];
pts1[5] = pts1[3];
pts1[6] = pts1[4] - horLineWidth;
pts1[7] = pts1[5];
canvas.drawLines(pts1, flagPaint);
float wt = centerTextPaint.measureText(txt);
canvas.drawText(txt, pts1[6] - wt - 5, pts1[7] + tagTextSize / 2, centerTextPaint);//在这里可以设置描述字体在线的位置
}else if(tempAngle <= 180){
Log.e(TAG, tempAngle +"");
tagPointX = centerPoint.centerX - relativePointX;
tagPointY = centerPoint.centerY - relativePointY;
pts1[0] = tagPointX - radius / 40;
pts1[1] = tagPointY - radius / 40;
pts1[2] = tagPointX - 50;
pts1[3] = tagPointY - 40;
pts1[4] = pts1[2];
pts1[5] = pts1[3];
pts1[6] = pts1[4] - horLineWidth;
pts1[7] = pts1[5];
canvas.drawLines(pts1, flagPaint);
float wt = centerTextPaint.measureText(txt);
canvas.drawText(txt, pts1[6] - wt - 5, pts1[7] + tagTextSize / 2, centerTextPaint);
}else if(tempAngle <= 270){
Log.e(TAG, tempAngle +"");
tagPointX = centerPoint.centerX + relativePointX;
tagPointY = centerPoint.centerY - relativePointY;
pts1[0] = tagPointX + radius / 40;
pts1[1] = tagPointY - radius / 40;
pts1[2] = tagPointX + 50;
pts1[3] = tagPointY - 40;
pts1[4] = pts1[2];
pts1[5] = pts1[3];
pts1[6] = pts1[4] + horLineWidth;
pts1[7] = pts1[5];
canvas.drawLines(pts1, flagPaint);
float wt = centerTextPaint.measureText(txt);
canvas.drawText(txt, pts1[6] + 5, pts1[7] + tagTextSize / 2, centerTextPaint);
}else if(tempAngle < 360){
Log.e(TAG, tempAngle +"");
tagPointX = centerPoint.centerX + relativePointX;
tagPointY = centerPoint.centerY + relativePointY;
pts1[0] = tagPointX + radius / 40;
pts1[1] = tagPointY + radius / 40;
pts1[2] = tagPointX + 50;
pts1[3] = tagPointY + 40;
pts1[4] = pts1[2];
pts1[5] = pts1[3];
pts1[6] = pts1[4] + horLineWidth;
pts1[7] = pts1[5];
canvas.drawLines(pts1, flagPaint);
float wt = centerTextPaint.measureText(txt);
canvas.drawText(txt, pts1[6] + 5, pts1[7] + tagTextSize / 2, centerTextPaint);
}
canvas.drawCircle(tagPointX, tagPointY, radius / 40, flagPaint);
}
class CenterPoint{
float centerX;
float centerY;
}
public void setData(double totalSize , double aSize , double bSize){
this.totalSize = totalSize;
this.aSize = aSize;
this.bSize = bSize;
invalidate();//重新绘制
}
}
xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<com.example.draw.TestTUhua
android:id="@+id/tt"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
activity文件
package com.example.draw;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TestTUhua tt = (TestTUhua) findViewById(R.id.tt);
tt.setData(1024*1024*1024*16d, 1024*1024*1024*5d, 1024*1024*1024*5d);
}
}