自定义身高,体重,血压,腰围选择器View

2023-10-18 06:20

本文主要是介绍自定义身高,体重,血压,腰围选择器View,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这里通过对于左右滑动的操作,来显示之前的或之后的数值共用了3种方法:

①VerticalDialView和HorizontalDialView 把所有刻度值画出来,不断的改变从哪个位置开始画第一个刻度值。显示在View大小之外的就隐藏了

②SphygmomanometerView 因为下面的圆形肚子不能显示刻度值,所以不能用①方法,在底部设置一个位置,当绘制刻度值到这个位置时,停止绘制。

③WeightView 根据当前指向的值,计算出左右两边可以显示的最小值和最大值。只绘制可以显示的刻度值。(当然是这个效率最高,会少绘制很多)


VerticalDialView(身高):




package com.ancx.view.view;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.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import com.ancx.view.R;
import com.ancx.view.util.UnitConversionUtils;/*** 竖直的刻度计*/
public class VerticalDialView extends View {private Context context;/*** 四个圆角的半径*/private int radius = 10;private int greyColor = Color.parseColor("#808080");private int cyanColor = Color.parseColor("#40BEBD");private int pinkColor = Color.parseColor("#FFBEB4");/*** 边框画笔*/private Paint borderPaint = new Paint();/*** 填充画笔*/private Paint fillPaint = new Paint();/*** 短刻度线画笔*/private Paint shortLinePaint = new Paint();/*** 长刻度线画笔*/private Paint longLinePaint = new Paint();/*** 指向当前值的粉色线画笔*/private Paint currentLinePaint = new Paint();/*** 指针图片的画笔*/private Paint currentPicPaint = new Paint();/*** 刻度值的画笔*/private Paint textPaint = new Paint();private int mHeight;private int mWidth;/*** 当前值*/private int currentValue;/*** 每个刻度之间的距离*/private float average = 15f;/*** 开始时指向的值*/private int startData = 175;/*** 根据startData计算的从哪开始画的位置*/private float startPosition;/*** 粉色线的位置*/private float currentPinkLine;public VerticalDialView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;currentValue = startData;}/*** 设置刻度间距,当设置值为负数时会自动赋值为默认值15** @param average*/public void setAverage(float average) {if (average <= 0) {this.average = 15f;//15} else {this.average = average;}}/*** 设置开始时要指向的值 0--230 之间** @param startData*/public void setStartData(int startData) {if (startData < 0) {this.startData = 0;} else if (startData > 230) {this.startData = 230;} else {this.startData = startData;}currentValue = this.startData;startPosition = -this.startData * average;}/*** 获取当前值** @return*/public int getCurrentValue() {return currentValue;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mHeight = getHeight();mWidth = getWidth() - UnitConversionUtils.dip2px(context, 10);currentPinkLine = mHeight / 2f;startPosition = currentPinkLine - (230 - this.startData) * average;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBackGround(canvas);drawData(canvas);}private void drawBackGround(Canvas canvas) {// 矩形(控件的所有区域)RectF border = new RectF(0, 0, mWidth, mHeight);// 画填充fillPaint.setAntiAlias(true);fillPaint.setColor(Color.parseColor("#FFFFFF"));fillPaint.setStyle(Paint.Style.FILL);canvas.drawRoundRect(border, radius, radius, fillPaint);// 画边框borderPaint.setAntiAlias(true);borderPaint.setColor(greyColor);borderPaint.setStyle(Paint.Style.STROKE);borderPaint.setStrokeWidth(3);canvas.drawRoundRect(border, radius, radius, borderPaint);// 画当前刻度值currentLinePaint.setAntiAlias(true);currentLinePaint.setColor(pinkColor);currentLinePaint.setStrokeWidth(3);canvas.drawLine(0, currentPinkLine, mWidth, currentPinkLine, currentLinePaint);// 画当前刻度的图片currentPicPaint.setAntiAlias(true);Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.zhizhen);canvas.drawBitmap(bitmap, getWidth() - bitmap.getWidth(), (mHeight - bitmap.getHeight()) / 2f, currentPicPaint);}private void drawData(Canvas canvas) {// 画短刻度线shortLinePaint.setAntiAlias(true);shortLinePaint.setColor(greyColor);shortLinePaint.setStrokeWidth(3);// 画长刻度线longLinePaint.setAntiAlias(true);longLinePaint.setColor(cyanColor);longLinePaint.setStrokeWidth(5);// 画刻度值textPaint.setAntiAlias(true);textPaint.setColor(greyColor);textPaint.setTextSize(UnitConversionUtils.sp2px(context, 12));Rect rect = new Rect();textPaint.getTextBounds("999cm", 0, 1, rect);for (int height = 230; height >= 0; height--) {if (height % 10 == 0) {// 长线canvas.drawLine(0, startPosition + average * (230 - height), 50, startPosition + average * (230 - height), longLinePaint);canvas.drawText(height + "cm", 50, startPosition + average * (230 - height) + rect.height() / 2f - 2, textPaint);} else {// 短线canvas.drawLine(0, startPosition + average * (230 - height), 20, startPosition + average * (230 - height), shortLinePaint);}}}private float startY, moveY, disY;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startY = event.getY();break;case MotionEvent.ACTION_MOVE:moveY = event.getY();disY = moveY - startY;startPosition += disY;if (startPosition > currentPinkLine) {startPosition = currentPinkLine;}if (startPosition < currentPinkLine - 230 * average) {startPosition = currentPinkLine - 230 * average;}float data = (currentPinkLine - startPosition) / average;currentValue = (230 - (int) (data + 0.5f));if (dataChangerListener != null) {dataChangerListener.listener();}invalidate();startY = moveY;break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:startPosition = currentPinkLine - (230 - currentValue) * average;invalidate();break;}return true;}/*** 设置监听属性*/public interface DataChangerListener {void listener();}private DataChangerListener dataChangerListener;/*** 设置指向值变化的监听,刻度变化后就会执行listener()方法** @param dataChangerListener*/public void setDataChangerListener(DataChangerListener dataChangerListener) {this.dataChangerListener = dataChangerListener;}
}

HorizontalDialView (腰围)




package com.ancx.view.view;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.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import com.ancx.view.R;
import com.ancx.view.util.UnitConversionUtils;/*** 水平的刻度尺*/
public class HorizontalDialView extends View {private Context context;/*** 边框的弧度半径*/private int radius = 10;/*** 短刻度线,边框,刻度数的颜色(灰色)*/private int greyColor = Color.parseColor("#CBCBCB");/*** 长刻度线的颜色(青色)*/private int cyanColor = Color.parseColor("#40BEBD");/*** 当前刻度的指示线的颜色(粉色)*/private int pinkColor = Color.parseColor("#FFBEB4");/*** 边框的画笔*/private Paint borderPaint = new Paint();/*** 填充画笔*/private Paint fillPaint = new Paint();/*** 短刻度线的画笔*/private Paint shortLinePaint = new Paint();/*** 长刻度线的画笔*/private Paint longLinePaint = new Paint();/*** 当前刻度的指示线的画笔*/private Paint currentLinePaint = new Paint();/*** 当前刻度的图片的画笔*/private Paint currentPicPaint = new Paint();/*** 刻度数文本的画笔*/private Paint textPaint = new Paint();/*** View的总高度*/private int mHeight;/*** View的总宽度*/private int mWidth;/*** 当前刻度值*/private float currentValue;/*** 两个刻度之间的高度*/private float average = 15f;/*** Y轴上开始画的数据,默认是100.0*/private int startData = 1000;/*** Y轴上开始画的位置,默认是currentPinkLine - startData * average*/private float startPosition;/*** 当前刻度指示针的位置,默认是中间*/private float currentPinkLine;public HorizontalDialView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;currentValue = this.startData / 10;}/*** 设置每个刻度之间的距离** @param average*/public void setAverage(float average) {if (average <= 0) {this.average = 15f;} else {this.average = average;}}/*** 开始的指示数据** @param startData*/public void setStartData(float startData) {if (startData < 0) {this.startData = 0;} else if (startData > 200) {this.startData = 2000;} else {this.startData = (int) (startData * 10);}currentValue = this.startData / 10f;startPosition = -this.startData * average;}public float getCurrentValue() {return currentValue;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mHeight = getHeight() - UnitConversionUtils.dip2px(context, 10);mWidth = getWidth();currentPinkLine = mWidth / 2f;startPosition = currentPinkLine - startData * average;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBackGround(canvas);drawDate(canvas);}/*** 画背景,包括边框和中间的当前刻度值的指针** @param canvas*/private void drawBackGround(Canvas canvas) {// 矩形(控件的所有区域)RectF border = new RectF(0, 0, mWidth, mHeight);// 画填充fillPaint.setAntiAlias(true);fillPaint.setColor(Color.parseColor("#FFFFFF"));fillPaint.setStyle(Paint.Style.FILL);canvas.drawRoundRect(border, radius, radius, fillPaint);// 画边框borderPaint.setAntiAlias(true);borderPaint.setColor(greyColor);borderPaint.setStyle(Paint.Style.STROKE);borderPaint.setStrokeWidth(3);canvas.drawRoundRect(border, radius, radius, borderPaint);// 画当前刻度值currentLinePaint.setAntiAlias(true);currentLinePaint.setColor(pinkColor);currentLinePaint.setStrokeWidth(3);canvas.drawLine(currentPinkLine, 0, currentPinkLine, mHeight, currentLinePaint);// 画当前刻度的图片currentPicPaint.setAntiAlias(true);Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.zhizhen_up);canvas.drawBitmap(bitmap, (mWidth - bitmap.getWidth()) / 2f, getHeight() - bitmap.getHeight(), currentPicPaint);}/*** 画数据** @param canvas*/private void drawDate(Canvas canvas) {// 画短刻度线shortLinePaint.setAntiAlias(true);shortLinePaint.setColor(greyColor);shortLinePaint.setStrokeWidth(3);// 画长刻度线longLinePaint.setAntiAlias(true);longLinePaint.setColor(cyanColor);longLinePaint.setStrokeWidth(5);// 画刻度值textPaint.setAntiAlias(true);textPaint.setColor(greyColor);textPaint.setTextSize(UnitConversionUtils.sp2px(context, 12));Rect rect = new Rect();textPaint.getTextBounds("999cm", 0, 1, rect);for (int width = 0; width <= 2000; width++) {if (width % 10 == 0) {// 长线canvas.drawLine(startPosition + average * width, 0, startPosition + average * width, 50, longLinePaint);canvas.drawText(width / 10 + "cm", startPosition + average * width - textPaint.measureText(width / 10 + "cm") / 2, 50 + rect.height() + 5, textPaint);} else {// 短线canvas.drawLine(startPosition + average * width, 0, startPosition + average * width, 20, shortLinePaint);}}}private float startX, moveX, disX;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startX = event.getX();break;case MotionEvent.ACTION_MOVE:moveX = event.getX();disX = moveX - startX;startPosition += disX;if (startPosition > currentPinkLine) {startPosition = currentPinkLine;}if (startPosition < currentPinkLine - 2000 * average) {startPosition = currentPinkLine - 2000 * average;}float data = (currentPinkLine - startPosition) / average + 0.5f;currentValue = (int) data / 10f;if (dataChangerListener != null) {dataChangerListener.listener();}invalidate();startX = moveX;break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:startPosition = currentPinkLine - currentValue * 10 * average;invalidate();break;}return true;}/*** 数值变化监听*/// 接口public interface DataChangerListener {void listener();}private DataChangerListener dataChangerListener;public void setDataChangerListener(DataChangerListener dataChangerListener) {this.dataChangerListener = dataChangerListener;}
}


SphygmomanometerView (血压刻度计)




package com.ancx.view.view;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.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import com.ancx.view.R;
import com.ancx.view.util.UnitConversionUtils;/*** 血压计*/
public class SphygmomanometerView extends View {private Context context;private int topArcHeight = 100;private int bottomArcHeight;private int spacing = 30;private int greyColor = Color.parseColor("#808080");private int cyanColor = Color.parseColor("#40BEBD");private int pinkColor = Color.parseColor("#FFBEB4");private Paint borderPaint = new Paint();private Paint fillPaint = new Paint();private Paint whitePaint = new Paint();private Paint shortLinePaint = new Paint();private Paint longLinePaint = new Paint();private Paint currentLinePaint = new Paint();private Paint currentPicPaint = new Paint();private Paint textPaint = new Paint();private int mHeight;private int mWidth;private int currentValue;private float average = 15f;private int startData = 80;private float startPosition;private float currentPinkLine;public SphygmomanometerView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;currentValue = startData;}public void setAverage(float average) {if (average <= 0) {this.average = 15f;} else {this.average = average;}}public void setStartData(int startData) {if (startData < 0) {this.startData = 0;} else if (startData > 230) {this.startData = 230;} else {this.startData = startData;}currentValue = this.startData;startPosition = -this.startData * average;}public int getCurrentValue() {return currentValue;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mHeight = getHeight();mWidth = getWidth();if (mHeight == 0 || mWidth == 0) {return;}bottomArcHeight = mWidth;currentPinkLine = (mHeight - topArcHeight / 2f - bottomArcHeight - 3) / 2f + 3 + topArcHeight / 2f;startPosition = currentPinkLine - (230 - this.startData) * average;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBackGround(canvas);drawData(canvas);}private void drawBackGround(Canvas canvas) {// 白线whitePaint.setAntiAlias(true);whitePaint.setColor(Color.parseColor("#FFFFFF"));whitePaint.setStrokeWidth(5);// 画填充fillPaint.setAntiAlias(true);fillPaint.setColor(Color.parseColor("#FFFFFF"));fillPaint.setStyle(Paint.Style.FILL);// 画边框borderPaint.setAntiAlias(true);borderPaint.setColor(greyColor);borderPaint.setStyle(Paint.Style.STROKE);borderPaint.setStrokeWidth(3);//画顶部弧形RectF topRectF = new RectF(spacing, 3, mWidth - spacing, topArcHeight);canvas.drawArc(topRectF, -180, 180, true, borderPaint);canvas.drawArc(topRectF, -180, 180, true, fillPaint);canvas.drawLine(spacing, topArcHeight / 2f + 3, mWidth - spacing, topArcHeight / 2f + 3, whitePaint);// 画两条边线canvas.drawLine(spacing, topArcHeight / 2f, spacing, mHeight - bottomArcHeight / 2f, borderPaint);canvas.drawLine(mWidth - spacing, topArcHeight / 2f, mWidth - spacing, mHeight - bottomArcHeight / 2f, borderPaint);//画底部弧形RectF bottomRectF = new RectF(3, mHeight - bottomArcHeight, mWidth - 3, mHeight - 3);canvas.drawArc(bottomRectF, -45, 270, true, borderPaint);canvas.drawArc(bottomRectF, -45, 270, true, fillPaint);// 矩形RectF border = new RectF(spacing, topArcHeight / 2f, mWidth - spacing, mHeight - bottomArcHeight / 2f - 3);canvas.drawRoundRect(border, 0, 0, fillPaint);// 画当前刻度值currentLinePaint.setAntiAlias(true);currentLinePaint.setColor(pinkColor);currentLinePaint.setStrokeWidth(3);canvas.drawLine(spacing, currentPinkLine, mWidth - 30, currentPinkLine, currentLinePaint);// 画当前刻度的图片currentPicPaint.setAntiAlias(true);Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.zhizhen);canvas.drawBitmap(bitmap, getWidth() - spacing - bitmap.getWidth() + 16, currentPinkLine - bitmap.getHeight() / 2f, currentPicPaint);}private void drawData(Canvas canvas) {// 画短刻度线shortLinePaint.setAntiAlias(true);shortLinePaint.setColor(greyColor);shortLinePaint.setStrokeWidth(3);// 画长刻度线longLinePaint.setAntiAlias(true);longLinePaint.setColor(cyanColor);longLinePaint.setStrokeWidth(5);// 画刻度值textPaint.setAntiAlias(true);textPaint.setColor(greyColor);textPaint.setTextSize(UnitConversionUtils.sp2px(context, 12));Rect rect = new Rect();textPaint.getTextBounds("999Kpa", 0, 1, rect);for (int height = 230; height >= 0; height--) {if (startPosition + average * (230 - height) <= mHeight - bottomArcHeight && startPosition + average * (230 - height) >= topArcHeight / 2f) {if (height % 10 == 0) {// 长线canvas.drawLine(spacing, startPosition + average * (230 - height), 50 + spacing, startPosition + average * (230 - height), longLinePaint);canvas.drawText(height + "Kpa", 50 + spacing, startPosition + average * (230 - height) + rect.height() / 2f - 2, textPaint);} else {// 短线canvas.drawLine(spacing, startPosition + average * (230 - height), 20 + spacing, startPosition + average * (230 - height), shortLinePaint);}}}}private float startY, moveY, disY;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startY = event.getY();break;case MotionEvent.ACTION_MOVE:moveY = event.getY();disY = moveY - startY;startPosition += disY;if (startPosition > currentPinkLine) {startPosition = currentPinkLine;}if (startPosition < currentPinkLine - 230 * average) {startPosition = currentPinkLine - 230 * average;}float data = (currentPinkLine - startPosition) / average;currentValue = (230 - (int) (data + 0.5f));if (dataChangerListener != null) {dataChangerListener.listener();}invalidate();startY = moveY;break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:startPosition = currentPinkLine - (230 - currentValue) * average;invalidate();break;}return true;}public interface DataChangerListener {void listener();}private DataChangerListener dataChangerListener;public void setDataChangerListener(DataChangerListener dataChangerListener) {this.dataChangerListener = dataChangerListener;}}


WeightView (体重刻度计)




package com.ancx.view.view;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.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import com.ancx.view.R;
import com.ancx.view.util.UnitConversionUtils;/*** 体重刻度尺*/
public class WeightDialView extends View {private Context context;private int greyColor = Color.parseColor("#808080");private int cyanColor = Color.parseColor("#40BEBD");private int pinkColor = Color.parseColor("#FFBEB4");private int backgroundColor = Color.parseColor("#EEEEEE");private Paint borderPaint = new Paint();private Paint fillPaint = new Paint();private Paint rectPaint = new Paint();private Paint tranPaint = new Paint();private Paint shortLinePaint = new Paint();private Paint longLinePaint = new Paint();private Paint currentLinePaint = new Paint();private Paint currentPicPaint = new Paint();private Paint textPaint = new Paint();private int mHeight;private int mWidth;private float currentValue;private float average = 4;private float distance = (float) (2 * (mHeight * 2 * Math.sin(2 * Math.PI / 180)));private int startData = 100;private float startPosition = (float) (-startData * 2 * (mHeight * 2 * Math.sin(2 * Math.PI / 180)));private float currentPinkLine;public WeightDialView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;currentValue = this.startData / 2f;}public void setAverage(float average) {if (average <= 0) {this.average = 4;} else {this.average = average;}}public void setStartData(float startData) {if (startData < 0) {this.startData = 0;} else if (startData > 200) {this.startData = 400;} else {this.startData = (int) (startData * 2);}currentValue = this.startData / 2f;}@Overridepublic void setBackgroundColor(int backgroundColor) {this.backgroundColor = backgroundColor;}public float getCurrentValue() {return currentValue;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mHeight = getHeight();mWidth = getWidth();distance = (float) (2 * (mHeight * 2 * Math.sin(2 * Math.PI / 180)));currentPinkLine = mWidth / 2f;
//        startPosition = (float) (-startData * 2 * (mHeight * 2 * Math.sin(2 * Math.PI / 180)));startPosition = currentPinkLine;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);drawBackGround(canvas);drawData(canvas);//        drawRect(canvas);}private void drawBackGround(Canvas canvas) {// 画填充fillPaint.setAntiAlias(true);fillPaint.setColor(Color.parseColor("#FFFFFF"));fillPaint.setStyle(Paint.Style.FILL);tranPaint.setAntiAlias(true);tranPaint.setColor(backgroundColor);tranPaint.setStyle(Paint.Style.FILL);// 画边框borderPaint.setAntiAlias(true);borderPaint.setColor(greyColor);borderPaint.setStyle(Paint.Style.STROKE);borderPaint.setStrokeWidth(3);// 画上面弧形RectF topRectF = new RectF(mWidth / 2f - 2 * mHeight, 3, mWidth / 2f + 2 * mHeight, 4 * mHeight + 3);canvas.drawArc(topRectF, 311, -82, true, fillPaint);canvas.drawArc(topRectF, 311, -82, true, borderPaint);// 画下面弧形RectF bottomRectF = new RectF(mWidth / 2f - 4 * mHeight / 3f, 2 * mHeight / 3f, mWidth / 2f + 4 * mHeight / 3f, 10 * mHeight / 3f);canvas.drawArc(bottomRectF, 311, -82, true, tranPaint);canvas.drawArc(bottomRectF, 311, -82, true, borderPaint);// 画当前刻度值currentLinePaint.setAntiAlias(true);currentLinePaint.setColor(pinkColor);currentLinePaint.setStrokeWidth(3);canvas.drawLine(currentPinkLine, 3, currentPinkLine, 2 * mHeight / 3f, currentLinePaint);// 画当前刻度的图片currentPicPaint.setAntiAlias(true);Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.zhizhen_up);canvas.drawBitmap(bitmap, (mWidth - bitmap.getWidth()) / 2f, 2 * mHeight / 3f - bitmap.getHeight() / 2f, currentPicPaint);}private void drawData(Canvas canvas) {// 画短刻度线shortLinePaint.setAntiAlias(true);shortLinePaint.setColor(greyColor);shortLinePaint.setStrokeWidth(3);// 画长刻度线longLinePaint.setAntiAlias(true);longLinePaint.setColor(cyanColor);longLinePaint.setStrokeWidth(5);// 画刻度值textPaint.setAntiAlias(true);textPaint.setColor(greyColor);textPaint.setTextSize(UnitConversionUtils.sp2px(context, 12));Rect rect = new Rect();textPaint.getTextBounds("999kg", 0, 1, rect);float sp = (float) (mWidth / 2f - mHeight * 2 * Math.sin(41 * Math.PI / 180));// 左边for (int i = startData - 1; i >= startData - (int) (41 / average); i--) {canvas.rotate(-average, mWidth / 2f, mHeight * 2);if (i >= 0) {if (i % 6 == 0) {// 长线canvas.drawLine(startPosition + 0 * i, 3, startPosition + 0 * i, 50, longLinePaint);//33为刻度的长canvas.drawText(i / 2 + "kg", startPosition + 0 * i - textPaint.measureText(i / 2 + "kg") / 2,50 + rect.height() + 5, textPaint);} else {canvas.drawLine(startPosition + 0 * i, 0, startPosition + 0 * i, 30, shortLinePaint);//20为短刻度的长}}}canvas.rotate(average * (int) (41 / average), mWidth / 2f, mHeight * 2);// 右边for (int i = startData; i <= (int) (41 / average) + startData && i <= 400; i++) {if (i % 6 == 0) {// 长线canvas.drawLine(startPosition + 0 * i, 3, startPosition + 0 * i, 50, longLinePaint);canvas.drawText(i / 2 + "kg", startPosition + 0 * i - textPaint.measureText(i / 2 + "kg") / 2,50 + rect.height() + 5, textPaint);} else {canvas.drawLine(startPosition + 0 * i, 0, startPosition + 0 * i, 30, shortLinePaint);}canvas.rotate(average, mWidth / 2f, mHeight * 2);}}private void drawRect(Canvas canvas) {rectPaint.setAntiAlias(true);rectPaint.setColor(backgroundColor);rectPaint.setStyle(Paint.Style.FILL);rectPaint.setAntiAlias(true);rectPaint.setColor(backgroundColor);rectPaint.setStyle(Paint.Style.FILL);}private float startX, moveX, disX;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:startX = event.getX();break;case MotionEvent.ACTION_MOVE:moveX = event.getX();disX = moveX - startX;if (Math.abs(disX) < distance) {break;}startData -= (int) (disX / distance);if (startData <= 0) {startData = 0;}if (startData >= 400) {startData = 400;}currentValue = startData / 2f;invalidate();if (dataChangerListener != null) {dataChangerListener.listener();}startX = moveX;break;}return true;}public interface DataChangerListener {void listener();}private DataChangerListener dataChangerListener;public void setDataChangerListener(DataChangerListener dataChangerListener) {this.dataChangerListener = dataChangerListener;}
}

资源图片:

zhizhen                   zhizhen_up    

这篇关于自定义身高,体重,血压,腰围选择器View的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/230742

相关文章

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

SpringBoot AspectJ切面配合自定义注解实现权限校验的示例详解

《SpringBootAspectJ切面配合自定义注解实现权限校验的示例详解》本文章介绍了如何通过创建自定义的权限校验注解,配合AspectJ切面拦截注解实现权限校验,本文结合实例代码给大家介绍的非... 目录1. 创建权限校验注解2. 创建ASPectJ切面拦截注解校验权限3. 用法示例A. 参考文章本文

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Python利用GeoPandas打造一个交互式中国地图选择器

《Python利用GeoPandas打造一个交互式中国地图选择器》在数据分析和可视化领域,地图是展示地理信息的强大工具,被将使用Python、wxPython和GeoPandas构建的交互式中国地图行... 目录技术栈概览代码结构分析1. __init__ 方法:初始化与状态管理2. init_ui 方法:

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束