最近項目中有這個需求,將總資產的組成以圖形的形態展現出來,所以就寫了個自定義View來實現這個需求。
其實試下這個思路還是挺簡單的,因爲只需要在onDraw方法中使用畫筆畫出一個又一個的扇形,就能實現這樣的效果。
以下是我的思路,首先介紹下canvas.drawArc()方法。
RectF rectF = new RectF(100, 100, 500, 500);
//繪製扇形
canvas.drawArc(rectF, startAngle, endAngle, true, paint);
參數說明:
rectF:繪製扇形的區域
startAngle:扇形的開始繪製的角度(是角度值不是弧度值)
endAngle:扇形繪製結束的角度值
true:是否從圓心開始畫扇形
paint:畫筆
所以實現起來的思路就是:
通過給定的數據值,也就是一個包含數字的數組,然後算出每個數字的比重,乘上360度,算出每個數字所佔的扇形的角度值,然後通過給不同數字的畫上顏色不同的扇形,當處理完所有的數據後,就可以看到由不同顏色扇形所組成的一個圓,這當然不是我們所想要的,所以在最後,以相同的圓心畫一個白色的圓,當然這個圓的半徑要比剛剛那個彩色的圓的半徑要小,最後剩下的就是我們想要的結果,最後在扇形的中間寫上我們需要的文字即可。
這個是畫上幾個扇形後的效果。
在中間畫一個白色的圓之後就變成這樣的了
其實這個時候就已經初見成效了。最後加上文字就好了。
最後提供自定義的控件。
SelfStatistics.java
package com.cretin.testprogress.views;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Created by cretin on 16/6/23.
*/
public class SelfStatistics extends View {
private Paint paint;
//對外提供注入數據的變量
private float[] datas;
//自定義view內部存儲數據信息
private List<Infos> listDatas = new ArrayList<>();
//默認統計圖的顏色配置 如果數據大於4 則顏色輪詢
private String colorRes[] = new String[]{"#fdb128", "#4a90e2", "#89c732", "#f46950"};
private int mPanelWidth;
public SelfStatistics(Context context) {
super(context);
init();
}
private void init() {
paint = new Paint();
}
public SelfStatistics(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SelfStatistics(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SelfStatistics(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public float[] getDatas() {
return datas;
}
public void startDraw() {
invalidate();
}
public void setDatas(float[] datas) {
this.datas = datas;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (datas != null && datas.length > 0) {
calculateDatas();
//獲取圓心的x座標
int center = mPanelWidth / 2;
//圓環的半徑
int radius = center - 10;
//消除鋸齒
paint.setAntiAlias(true);
//給外圈設置樣式
paint.setStyle(Paint.Style.FILL_AND_STROKE);
//設置StrokeWidth
paint.setStrokeWidth(20);
//給外圈設置顏色
paint.setColor(Color.WHITE);
//畫最外層的圈
canvas.drawCircle(center, center, radius, paint);
//設置進度的顏色
for (Infos infos : listDatas) {
//定義一個RectF類
paint.setColor(Color.parseColor(infos.getColor()));
RectF rectF = new RectF(center - radius, center - radius, center + radius, center + radius);
//繪製扇形
canvas.drawArc(rectF, infos.getStartAngle(), infos.getEndAngle(), true, paint);
}
//畫最外層的圈
paint.setColor(Color.WHITE);
canvas.drawCircle(center, center, radius - 50, paint);
drawTexts(canvas, center);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = Math.min(widthSize, heightSize);
if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
}
setMeasuredDimension(width, width);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mPanelWidth = Math.min(w,h);
}
private void drawTexts(Canvas canvas, int center) {
float total = 0;
for (int i = 0; i < datas.length; i++) {
total += datas[i];
}
String totalStr = total + "元";
paint.setStrokeWidth(2);
//設置進度扇形的樣式
paint.setStyle(Paint.Style.FILL);
//設置文字的大小
paint.setTextSize(35);
int widthStr1 = (int) paint.measureText("總資產");
int widthStr2 = (int) paint.measureText(totalStr);
paint.setColor(Color.parseColor("#333333"));
float baseX = center - widthStr1 / 2;
float baseY = center + 20 / 4;
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;
float offY = fontTotalHeight / 2 - fontMetrics.bottom - 30;
float newY = baseY + offY;
canvas.drawText("總資產", baseX, newY, paint);
paint.setColor(Color.parseColor("#fc561f"));
float baseX1 = center - widthStr2 / 2;
float baseY1 = center + 20 / 4;
Paint.FontMetrics fontMetrics1 = paint.getFontMetrics();
float fontTotalHeight1 = fontMetrics1.bottom - fontMetrics1.top;
float offY1 = fontTotalHeight1 / 2 - fontMetrics1.bottom + 30;
float newY1 = baseY1 + offY1;
canvas.drawText(totalStr, baseX1, newY1, paint);
}
//爲繪畫做基本的計算
private void calculateDatas() {
float total = 0;
float tempAngle = 270;
//計算出總數
for (int i = 0; i < datas.length; i++) {
total += datas[i];
}
//創建不同的Infos對象
Infos infos;
for (int i = 0; i < datas.length; i++) {
infos = new Infos();
float currData = datas[i];
float startAngle = tempAngle;
float endAngle = (float) (currData * 100 / total * 3.6);
infos.setStartAngle(startAngle);
infos.setEndAngle(endAngle);
infos.setColor(colorRes[i % colorRes.length]);
tempAngle = endAngle + tempAngle;
listDatas.add(infos);
}
}
class Infos {
private float startAngle;
private float endAngle;
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public float getStartAngle() {
return startAngle;
}
public void setStartAngle(float startAngle) {
this.startAngle = startAngle;
}
public float getEndAngle() {
return endAngle;
}
public void setEndAngle(float endAngle) {
this.endAngle = endAngle;
}
}
}
最後提供使用的方法:
佈局文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.cretin.testprogress.MainActivity">
<com.cretin.testprogress.views.SelfStatistics
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
主函數的調用:
package com.cretin.testprogress;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.cretin.testprogress.views.SelfStatistics;
public class MainActivity extends AppCompatActivity {
private SelfStatistics selfStatistics;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selfStatistics = (SelfStatistics) findViewById(R.id.progress);
float datas[] = new float[]{4000,3000,7000,8000};
selfStatistics.setDatas(datas);
selfStatistics.startDraw();
}
}
最後我寫了一個demo,歡迎下載,重在分享,不要積分哦,哈哈
下載地址爲:http://download.csdn.net/detail/u010998327/9557747