代码
package com.xinxin.applicationtest.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import com.xinxin.applicationtest.R;
/**
* Created by wxx on 2016/11/22 0022.
* 作用 : 仿支付宝芝麻信用分 评分视图
*/
public class CreditView extends View {
//数据个数
private int dataCount = 5;
//每个角的弧度
private float radian = (float) (Math.PI*2/dataCount);
//中间雷达图半径
private float radius;
//各个维度的分值
private float[] data = {160,150,120,130,190};
//最大分值
private float maxValue = 190;
//中心坐标
private int centerX;
private int centerY;
//标题
private String[] titles = {"人际关系","够不够NB","够不够屌","后台硬不硬","有没有钱"};
//图标
private int[] icons = {R.drawable.ic_android_black_24dp,R.drawable.ic_autorenew_black_24dp,
R.drawable.ic_wrap_text_black_24dp,R.drawable.ic_format_shapes_black_24dp,R.drawable.ic_directions_car_black_24dp};
//中间分数大小,dip 值
private int scoreSize = 33;
//标题文字大小,dip 值
private int titleSize = 22;
//雷达区边界线的画笔
private Paint mainPaint;
//雷达区填充区域的画笔
private Paint valuePaint;
//中间总分的画笔
private Paint scorePaint;
//标题的画笔
private Paint titlePaint;
//标题的边距
private int radarMargin = 20;
public CreditView(Context context) {
super(context);
initPaint();
}
public CreditView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public CreditView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint(){
mainPaint = new Paint();
mainPaint.setAntiAlias(true);
mainPaint.setColor(Color.WHITE);
mainPaint.setStyle(Paint.Style.STROKE);
mainPaint.setTextSize(0.1f);
valuePaint = new Paint();
valuePaint.setAntiAlias(true);
valuePaint.setColor(Color.BLUE);
valuePaint.setAlpha(50);
scorePaint = new Paint();
scorePaint.setColor(Color.WHITE);
scorePaint.setTextSize(scoreSize);
titlePaint = new Paint();
titlePaint.setColor(Color.WHITE);
titlePaint.setTextSize(titleSize);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
radius = Math.min(w,h)/2*0.5f;
centerX = w/2;
centerY = h/2;
postInvalidate();
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawPolygon(canvas);
drawLine(canvas);
drawRegion(canvas);
drawScore(canvas);
drawTitle(canvas);
drawIcon(canvas);
}
/**
* 画雷达区的边界线
* @param canvas
*/
private void drawPolygon(Canvas canvas){
Path path = new Path();
for (int i = 0; i < dataCount; i++) {
if (i == 0) {
path.moveTo(getPoint(i).x, getPoint(i).y);
} else {
path.lineTo(getPoint(i).x,getPoint(i).y);
}
}
path.close();
canvas.drawPath(path,mainPaint);
}
/**
* 画雷达区中间的线
* @param canvas
*/
private void drawLine(Canvas canvas) {
Path path = new Path();
for (int i = 0; i < dataCount; i++) {
path.reset();
path.moveTo(centerX,centerY);
path.lineTo(getPoint(i).x,getPoint(i).y);
canvas.drawPath(path,mainPaint);
}
}
/**
* 画覆盖区域
* @param canvas
*/
private void drawRegion(Canvas canvas) {
Path path = new Path();
for (int i = 0; i < dataCount; i++) {
//计算百分比
float percent = data[i] / maxValue;
int x = getPoint(i, 0, percent).x;
int y = getPoint(i, 0, percent).y;
if (i == 0) {
path.moveTo(x,y);
} else {
path.lineTo(x,y);
}
}
//绘制填充区域的边界
path.close();
//绘制填充区域
valuePaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(path, valuePaint);
}
/**
* 绘制中间的总分
* @param canvas
*/
private void drawScore(Canvas canvas) {
int score =0;
for (int i = 0; i < dataCount; i++) {
score += data[i];
}
//测量文本的宽高
Rect bounds = new Rect();
scorePaint.getTextBounds(String.valueOf(score),0,String.valueOf(score).length(),bounds);
int width = bounds.width();
int height = bounds.height();
canvas.drawText(String.valueOf(score),centerX - width/2,centerY + height/2,scorePaint);
}
/**
* 画五个标题
* @param canvas
*/
private void drawTitle(Canvas canvas) {
for (int i = 0; i < dataCount; i++) {
int x = getPoint(i, radarMargin, 1).x;
int y = getPoint(i, radarMargin, 1).y;
//测量文本的宽高
Rect bounds = new Rect();
titlePaint.getTextBounds(titles[i],0,titles[i].length(),bounds);
int width = bounds.width();
int height = bounds.height();
if(i == 1) {
y += height;
}else if(i == 2) {
x -= width;
y += height;
}else if(i == 3) {
x -= width;
}else if(i == 4) {
x -= width/2;
}
canvas.drawText(titles[i],x,y,titlePaint);
}
}
/**
* 画五个图标
* @param canvas
*/
private void drawIcon(Canvas canvas) {
for (int i = 0; i < dataCount; i++) {
int x = getPoint(i, radarMargin, 1).x;
int y = getPoint(i, radarMargin, 1).y;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), icons[i]);
//测量文本的宽高
Rect bounds = new Rect();
titlePaint.getTextBounds(titles[i],0,titles[i].length(),bounds);
int width = bounds.width();
int height = bounds.height();
if(i == 0) {
x += width/2 - bitmap.getWidth()/2;
y -= height + bitmap.getHeight();
}else if(i == 1) {
x += width/2 - bitmap.getWidth()/2;
y -= bitmap.getHeight();
}else if(i == 2) {
x -= width/2 + bitmap.getWidth()/2;
y -= bitmap.getHeight();
}else if(i == 3) {
x -= width/2 + bitmap.getWidth()/2;
y -= height + bitmap.getHeight();
}else if(i ==4) {
x -= bitmap.getWidth()/2;
y -= height + bitmap.getHeight();
}
canvas.drawBitmap(bitmap,x,y,titlePaint);
}
}
private Point getPoint(int position) {
return getPoint(position, 0, 1);
}
/**
* 获取指定点的坐标
* @param position 数据的下标
* @param radarMargin 雷达图与纬度标题的边距
* @param percent 覆盖区的百分比
* @return 坐标
*/
private Point getPoint(int position, int radarMargin, float percent) {
int x = 0;
int y = 0;
if (position == 0) {
x = (int) (centerX + (radius + radarMargin) * Math.sin(radian) * percent);
y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);
} else if (position == 1) {
x = (int) (centerX + (radius + radarMargin) * Math.sin(radian / 2) * percent);
y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);
} else if (position == 2) {
x = (int) (centerX - (radius + radarMargin) * Math.sin(radian / 2) * percent);
y = (int) (centerY + (radius + radarMargin) * Math.cos(radian / 2) * percent);
} else if (position == 3) {
x = (int) (centerX - (radius + radarMargin) * Math.sin(radian) * percent);
y = (int) (centerY - (radius + radarMargin) * Math.cos(radian) * percent);
} else if (position == 4) {
x = centerX;
y = (int) (centerY - (radius + radarMargin) * percent);
}
return new Point(x, y);
}
public void setData(float[] data) {
this.data = data;
postInvalidate();
}
}
使用
view.setData({160,150,120,130,190});
还有一个芝麻信用分仪表盘图的 点击查看 https://blog.csdn.net/wxx_csdn/article/details/90714466