记录TV开发过程中使用的自定义控件(进度类型)
高血压检测 View
效果图
代码
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* author : TiaoPi
* date : 2018/12/3 15:24
* desc : 高血压检测 View
*/
public class BloodPressureView extends View {
private int width = 500;
private int leftWidth = 50;
private int height = 400;
private int bottomHeight = 120;
private Paint paint;
private int textColor = Color.parseColor("#333333");
private int[] colors = {
Color.parseColor("#44AEFF"),Color.parseColor("#00E084"),
Color.parseColor("#FEDB64"),Color.parseColor("#FF6261")
};
private float[] gbp = {60,90,130,140,220};//高压范围
private float[] lbp = {30,60,80,90,120};//低压范围
private float gbpNum = 150;
private float lbpNum = 88;
public BloodPressureView(Context context) {
super(context);
paint = new Paint();
}
public BloodPressureView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
public BloodPressureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(width + leftWidth,height + bottomHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawChat(canvas);
drawBloodPressure(canvas);
}
/**
* 绘制高压低压的位置
*/
private void drawBloodPressure(Canvas canvas){
//绘制高压的点
paint.setColor(Color.parseColor("#50000000"));
float gx = (width * (height - getGPoi(gbpNum))/height) / 2 + leftWidth;
float gy = getGPoi(gbpNum);
canvas.drawCircle(gx,gy,8,paint);
//绘制低压的点
float lx = getLPoi(lbpNum);
float ly = height - (getLPoi(lbpNum)/width * height) / 2;
canvas.drawCircle(lx + leftWidth,ly,8,paint);
//绘制一个对话框
paint.setColor(Color.parseColor("#FFFFFF"));
Path path = new Path();
path.moveTo(gx,gy - 10);// 此点为多边形的起点
path.lineTo(gx + 4,gy - 20);
path.lineTo(gx + 15,gy - 20);
path.close();
canvas.drawPath(path, paint);
RectF rectF = new RectF();
rectF.set(gx - 20,gy - 50,gx + 80,gy - 20);
canvas.drawRoundRect(rectF,5,5,paint);
lx = lx + leftWidth;
path.reset();
path.moveTo(lx,ly - 10);// 此点为多边形的起点
path.lineTo(lx + 4,ly - 20);
path.lineTo(lx + 15,ly - 20);
path.close();
canvas.drawPath(path, paint);
RectF rectF2 = new RectF();
rectF2.set(lx - 20,ly - 50,lx + 80,ly - 20);
canvas.drawRoundRect(rectF2,5,5,paint);
//绘制文字
paint.setColor(textColor);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(20);
canvas.drawText("高压:" + (int)gbpNum,gx + 30,gy - 27,paint);
canvas.drawText("低压:" + (int)lbpNum,lx + 30,ly - 27,paint);
}
/**
* 绘制表格
* @param canvas
*/
private void drawChat(Canvas canvas){
initPaint();
//绘制四个矩形线
paint.setColor(colors[3]);
RectF rectF3 = new RectF();
rectF3.set(leftWidth,0,width + leftWidth,height);
canvas.drawRect(rectF3,paint);
paint.setColor(colors[2]);
RectF rectF2 = new RectF();
rectF2.set(leftWidth,height/6 * 1.8f,leftWidth + width/6 * 4.2f,height);
canvas.drawRect(rectF2,paint);
paint.setColor(colors[1]);
RectF rectF1 = new RectF();
rectF1.set(leftWidth,height/10 * 5.5f,leftWidth + width/10 * 4.5f,height);
canvas.drawRect(rectF1,paint);
paint.setColor(colors[0]);
RectF rectF0 = new RectF();
rectF0.set(leftWidth,height/4 * 3,leftWidth + width/4 ,height);
canvas.drawRect(rectF0,paint);
//绘制白色线条
paint.setColor(Color.parseColor("#FFFFFF"));
paint.setStrokeWidth(1.0f);
canvas.drawLine(leftWidth,height,leftWidth + width,0,paint);
canvas.drawLine(leftWidth,height/6 * 1.8f,
leftWidth + width/6 * 4.2f,height/6 * 1.8f,paint);
canvas.drawLine(leftWidth + width/6 * 4.2f,height/6 * 1.8f,
leftWidth + width/6 * 4.2f,height,paint);
canvas.drawLine(leftWidth,height/10 * 5.5f,
leftWidth + width/10 * 4.5f,height/10 * 5.5f,paint);
canvas.drawLine(leftWidth + width/10 * 4.5f,height/10 * 5.5f,
leftWidth + width/10 * 4.5f,height,paint);
canvas.drawLine(leftWidth,height/4 * 3,
leftWidth + width/4,height/4 * 3,paint);
canvas.drawLine(leftWidth + width/4,height/4 * 3,
leftWidth + width/4,height,paint);
//绘制文字
initPaint();
paint.setColor(textColor);
paint.setTextSize(34);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("收",leftWidth/2,height/3,paint);
canvas.drawText("缩",leftWidth/2,height/3 + 34,paint);
canvas.drawText("压",leftWidth/2,height/3 + 68,paint);
canvas.drawText("舒张压",leftWidth + width/3,height + 42,paint);
paint.setTextSize(28);
canvas.drawText("高",leftWidth/2,height/3 + 128,paint);
canvas.drawText("压",leftWidth/2,height/3 + 156,paint);
canvas.drawText("低压",leftWidth + width/3 + 128,height + 39,paint);
//绘制底部的提示
paint.setColor(colors[0]);
RectF rectFs0 = new RectF();
rectFs0.set(leftWidth,height + 85,leftWidth + 15,height +100);
canvas.drawRect(rectFs0,paint);
paint.setColor(colors[1]);
RectF rectFs1 = new RectF();
rectFs1.set(leftWidth + 120,height + 85,leftWidth + 135,height +100);
canvas.drawRect(rectFs1,paint);
paint.setColor(colors[2]);
RectF rectFs2 = new RectF();
rectFs2.set(leftWidth + 235,height + 85,leftWidth + 250,height +100);
canvas.drawRect(rectFs2,paint);
paint.setColor(colors[3]);
RectF rectFs3 = new RectF();
rectFs3.set(leftWidth + 350,height + 85,leftWidth + 365,height +100);
canvas.drawRect(rectFs3,paint);
initPaint();
paint.setColor(textColor);
paint.setTextSize(20);
paint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("血压偏低",leftWidth + 20,height +100,paint);
canvas.drawText("血压正常",leftWidth + 140,height +100,paint);
canvas.drawText("正常偏高",leftWidth + 255,height +100,paint);
canvas.drawText("高血压诊断标",leftWidth + 370,height +100,paint);
}
/**
* 设置画笔
*/
private void initPaint(){
paint.reset();
paint.setStrokeWidth(2.0f);
paint.setColor(Color.parseColor("#DDDDDD"));
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
/**
* 计算高压对应的点的位置
*/
private float getGPoi(float gv){
int index = 0;
for (int i = 0; i < gbp.length - 1; i++) {
if (gv >= gbp[i] && gv < gbp[i + 1]){
index = i;
}
}
float gHeight = 0; //高血压的位置高度
switch (index){
case 0:
gHeight = height/4 * 3 + (height - height/4 * 3) * (gbp[1] -gv)/(gbp[1] - gbp[0]);
break;
case 1:
gHeight = height/10 * 5.5f + (height - height/10 * 5.5f - height/4) * (gbp[2] -gv)/(gbp[2] - gbp[1]);
break;
case 2:
gHeight = height/6 * 1.8f + (height/10 * 5.5f - height/6 * 1.8f) * (gbp[3] -gv)/(gbp[3] - gbp[2]);
break;
case 3:
gHeight = height/6 * 1.8f * (gbp[4] -gv)/(gbp[4] - gbp[3]);
break;
}
return gHeight;
}
/**
* 查找低压的点
* @param lv
* @return
*/
private float getLPoi(float lv){
int index = 0;
for (int i = 0; i < lbp.length - 1; i++) {
if (lv >= lbp[i] && lv < lbp[i + 1]){
index = i;
}
}
float lWidth = 0; //高血压的位置高度
switch (index){
case 0:
lWidth = width/4 * (lv - lbp[0])/(lbp[1] - lbp[0]);
break;
case 1:
lWidth =width/4 + (width/10 * 4.5f - width/4) * (lv - lbp[1])/(lbp[2] - lbp[1]);
break;
case 2:
lWidth = width/10 * 4.5f + (width/6 * 4.2f - width/10 * 4.5f) * (lv - lbp[2])/(lbp[3] - lbp[2]);
break;
case 3:
lWidth = width/6 * 4.2f + (width - width/6 * 4.2f) * (lv - lbp[3])/(lbp[4] - lbp[3]);
break;
}
return lWidth;
}
}
血糖检测
效果图
代码
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* author : TiaoPi
* date : 2018/12/4 16:24
* desc : 血糖检测view
*/
public class BloodSugarView extends View {
private Paint paint;
private float bloodSugar = 5f;
private int leftWidth = 26;
private int width = 1586 - leftWidth * 2;
private int height = 273;
public BloodSugarView(Context context) {
super(context);
paint = new Paint();
}
public BloodSugarView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
public BloodSugarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
}
public void setData(float bloodSugar){
this.bloodSugar = bloodSugar;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(1586,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
LinearGradient linearGradient = new LinearGradient(
leftWidth,0,leftWidth + width,0,
new int[]{
Color.parseColor("#00A8FF"),
Color.parseColor("#00E587"),
Color.parseColor("#FCD449"),
Color.parseColor("#FF5757"),
},new float[]{
0,0.52f,0.6f,0.8f
}, Shader.TileMode.MIRROR);
paint.setShader(linearGradient);
RectF rectF = new RectF(leftWidth,80,width + leftWidth,140);
canvas.drawRect(rectF,paint);
paint.reset();
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(),R.mipmap.blood_sugar_tip_bg);
RectF rectF2 = new RectF(leftWidth,220,width + leftWidth,271);
canvas.drawBitmap(bitmap2,null,rectF2,paint);
float bloodSugarWidth = (bloodSugar - 1) * (width / 14);
initPaint();
canvas.drawText(bloodSugar + "mmol/l",bloodSugarWidth + leftWidth,52,paint);
if (bloodSugar <= 4){
paint.setColor(Color.parseColor("#00A8FF"));
}else if (bloodSugar > 4 && bloodSugar <= 6 ){
paint.setColor(Color.parseColor("#00E587"));
}else if (bloodSugar > 6 && bloodSugar <= 7){
paint.setColor(Color.parseColor("#FCD449"));
}else if (bloodSugar > 7){
paint.setColor(Color.parseColor("#FF5757"));
}
//绘制刻度值
Path path = new Path();
path.moveTo(bloodSugarWidth + leftWidth,75);
path.lineTo(bloodSugarWidth - 8 + leftWidth,62);
path.lineTo(bloodSugarWidth + 8 + leftWidth,62);
path.close();
canvas.drawPath(path, paint);
drawRuler(canvas);
}
/**
* 绘制刻度尺
* @param canvas
*/
private void drawRuler(Canvas canvas){
float rulerWidth = width/14;
initPaint();
paint.setStrokeWidth(1f);
for (int i = 1; i < 16; i++) {
paint.setColor(Color.parseColor("#333333"));
canvas.drawText((float)i + "",leftWidth + rulerWidth * (i- 1),175,paint);
}
float rulerSmallWidth = width/28;
paint.setColor(Color.parseColor("#FFFFFF"));
for (int i = 0; i < 29; i++) {
if (i == 0) {
canvas.drawLine(leftWidth + 5 + rulerSmallWidth * i+ 5,
115,leftWidth + 5 + rulerSmallWidth * i+ 5,138,paint);
}else if (i == 30){
canvas.drawLine(leftWidth + 5 + rulerSmallWidth * i+ 5,
115,leftWidth + 5 + rulerSmallWidth * i+ 5,138,paint);
}else {
if (i % 2 == 0){
canvas.drawLine(leftWidth + 5 + rulerSmallWidth * i,
115,leftWidth + 5 + rulerSmallWidth * i,138,paint);
}else {
canvas.drawLine(leftWidth + 5 + rulerSmallWidth * i,
122,leftWidth + 5 + rulerSmallWidth * i,138,paint);
}
}
}
}
/**
* 设置画笔
*/
private void initPaint(){
paint.reset();
paint.setStrokeWidth(2.0f);
paint.setColor(Color.parseColor("#333333"));
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
}
}
范围彩色的View
效果图
代码
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* author : TiaoPi
* date : 2018/12/3 9:35
* desc : 范围彩色的View
*/
public class RangeColorView extends View {
private int width = 200;
private int height = 80;
private float progress = 23; //刻度值
private String unit = ""; //单位
private float progressRange[] = {10,18.5f,28,32,42}; // 刻度范围
private String progressRangeText[] = {"偏低","正常","超重","肥胖"}; // 刻度范围
private int textColor = Color.parseColor("#333333");
private int rangeColor[] = {
Color.parseColor("#44AEFF"),
Color.parseColor("#00E587"),
Color.parseColor("#FF9540"),
Color.parseColor("#FF5857")
};
private Paint paint;
public RangeColorView(Context context) {
super(context);
paint = new Paint();
}
public RangeColorView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
public RangeColorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
}
/**
* 设置数据
* @param progress
* @param unit
* @param progressRange
* @param progressRangeText
* @param rangeColor
*/
public void setData(float progress,String unit,float progressRange[],
String progressRangeText[],int rangeColor[]){
this.progress = progress;
this.unit = unit;
this.progressRangeText = progressRangeText;
this.rangeColor = rangeColor;
this.progressRange = progressRange;
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drowProgressText(canvas);
drowRangeColor(canvas);
drowRangeText(canvas);
}
/**
* 绘制文字
*/
private void drowProgressText(Canvas canvas){
float progressWidth = getProgressWidth(progress);
//绘制刻度文字
initTextPaint();
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(20);
paint.setColor(textColor);
canvas.drawText(progress + unit,progressWidth,20,paint);
//绘制三角形刻度
Path path = new Path();
path.moveTo(progressWidth,32);// 此点为多边形的起点
path.lineTo(progressWidth - 5,24);
path.lineTo(progressWidth + 5,24);
path.close();
paint.setColor(rangeColor[getColorIndex(progress)]);
canvas.drawPath(path, paint);
}
/**
* 绘制刻度
*/
private void drowRangeColor(Canvas canvas){
initRangePaint();
float rangeHeight = 12;
float yHeight = 35 + rangeHeight/2;
//线绘制第一个左边圆角
paint.setColor(rangeColor[0]);
canvas.drawCircle(rangeHeight/2, yHeight, rangeHeight/2, paint);// 小圆
float startWidth = rangeHeight/2;
//绘制矩形
for (int i = 1; i < progressRange.length; i++) {
paint.setColor(rangeColor[i - 1]);
if (i == progressRange.length - 1){
//最后一个需要绘制最右边的圆形
canvas.drawCircle(getProgressWidth(progressRange[i]) - rangeHeight/2, yHeight, rangeHeight/2, paint);// 小圆
canvas.drawRect(startWidth, yHeight - rangeHeight/2,
getProgressWidth(progressRange[i]) - rangeHeight/2, yHeight + rangeHeight/2, paint);// 长方形
startWidth = getProgressWidth(progressRange[i]);
}else {
canvas.drawRect(startWidth, yHeight - rangeHeight/2,
getProgressWidth(progressRange[i]), yHeight + rangeHeight/2, paint);// 长方形
startWidth = getProgressWidth(progressRange[i]);
}
}
}
/**
* 绘制最底下的文字是多少
*/
private void drowRangeText(Canvas canvas){
initTextPaint();
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(12);
paint.setColor(textColor);
for (int i = 0; i < progressRange.length - 1 ; i++) {
float xWidth
= (getProgressWidth(progressRange[i + 1]) - getProgressWidth(progressRange[i]))/2
+ getProgressWidth(progressRange[i]);
canvas.drawText(progressRangeText[i],xWidth,65,paint);
}
}
/**
* 设置文字画笔的颜色
*/
private void initTextPaint(){
paint.reset();
paint.setColor(textColor);
paint.setStrokeWidth(0.0f);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(20);
paint.setAntiAlias(true);
}
/**
* 设置文字画笔的颜色
*/
private void initRangePaint(){
paint.reset();
paint.setStrokeWidth(0.0f);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
/**
* 获取点的宽度位置
* @param progress
* @return
*/
private float getProgressWidth(float progress){
return (progress - progressRange[0])/(progressRange[progressRange.length - 1]
- progressRange[0]) * width;
}
/**
* 获取刻度值的对应的颜色
* @param progress
* @return
*/
private int getColorIndex(float progress){
int colorIndex = 0;
for (int i = 0; i < progressRange.length; i++) {
if (i == progressRange.length - 1){
break;
}
if (progress >= progressRange[i] && progress < progressRange[i + 1]){
colorIndex = i;
}
}
return colorIndex;
}
}
视力值 显示图
效果图
代码
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
/**
* author : TiaoPi
* date : 2018/12/3 14:01
* desc : 视力值 显示图
*/
public class EyesightView extends View {
//视力范围4-5.3
private int width = 420;
private int height = 110;
private Paint paint;
private float leftSight = 5.3f;
private float rightSight = 4.8f;
private int blueColor = Color.parseColor("#677FFD");
private int greeColor = Color.parseColor("#6ADE86");
private int yellowColor = Color.parseColor("#F5DA60");
int[] colors = {yellowColor,greeColor,yellowColor};
float[] floats = {0.75f,0.8f,0.9f};
public EyesightView(Context context) {
super(context);
paint = new Paint();
}
public EyesightView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
public EyesightView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
}
public void setData(float leftSight,float rightSight){
this.leftSight = leftSight;
this.rightSight = rightSight;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(width + 18,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制背景
drawBackRuler(canvas);
drawData(canvas);
}
/**
* 绘制背景
* @param canvas
*/
private void drawBackRuler(Canvas canvas){
initPaint();
//绘制背景
LinearGradient linearGradient = new LinearGradient(
0,0,width,40,colors,floats,
Shader.TileMode.MIRROR);
paint.setShader(linearGradient);
RectF rectF = new RectF(0,30,width,70);
canvas.drawRect(rectF,paint);
//绘制刻度
float itemWidth = width / 13;
paint.reset();
paint.setColor(Color.parseColor("#FFFFFF"));
for (int i = 0; i < 14; i++) {
canvas.drawLine(itemWidth*i,40,itemWidth*i,50,paint);
if (i == 0) {
paint.setTextAlign(Paint.Align.LEFT);
canvas.drawText(4 + 0.1 *i + "",itemWidth*i,65,paint);
}else if (i == 13) {
paint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(4 + 0.1 *i + "",itemWidth*i,65,paint);
}else {
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(4 + 0.1 *i + "",itemWidth*i,65,paint);
}
}
}
/**
* 绘制刻度值
*/
private void drawData(Canvas canvas){
//绘制上面的
paint.reset();
paint.setTextAlign(Paint.Align.CENTER);
Path path = new Path();
path.moveTo(getSightWidth(leftSight),26);// 此点为多边形的起点
path.lineTo(getSightWidth(leftSight) - 8,13);
path.lineTo(getSightWidth(leftSight) + 8,13);
path.close();
paint.setColor(blueColor);
canvas.drawPath(path, paint);
paint.setColor(Color.parseColor("#000000"));
canvas.drawText("左眼",getSightWidth(leftSight),10,paint);
Path path2 = new Path();
path2.moveTo(getSightWidth(rightSight),75);// 此点为多边形的起点
path2.lineTo(getSightWidth(rightSight) - 8,90);
path2.lineTo(getSightWidth(rightSight) + 8,90);
path2.close();
paint.setColor(greeColor);
canvas.drawPath(path2, paint);
paint.setColor(Color.parseColor("#000000"));
canvas.drawText("右眼",getSightWidth(rightSight),105,paint);
}
/**
* 设置画笔
*/
private void initPaint(){
paint.reset();
paint.setStrokeWidth(1.0f);
paint.setColor(yellowColor);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
}
/**
* 获取视力宽度
* @param sight
* @return
*/
private float getSightWidth(float sight){
return (sight - 4) / (5.3f - 4) * width;
}
}