失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android自定义View——心电图 曲线图 波形图

Android自定义View——心电图 曲线图 波形图

时间:2018-12-26 21:14:04

相关推荐

Android自定义View——心电图 曲线图 波形图

公司要求做个心电图,昨天就写了下,原谅我懒得弄视频了,看图:

点击开始开始绘制,绘制屏满后,曲线向左移,点击停止则停止绘制。

首先自定义View,WaveShowView,重写其onLayout,onDraw方法,注释写的很清楚了:

public class WaveShowView extends View {private float mWidth = 0,mHeight = 0;//自身大小private int mBackGroundColor = Color.BLACK;private Paint mLinePaint;//画笔private Paint mWavePaint;//心电图的折现private Path mPath;//心电图的路径private ArrayList refreshList = new ArrayList();//后加的数据点private int row;//背景网格的行数和列数//心电private float MAX_VALUE = 20;private float WAVE_LINE_STROKE_WIDTH = 2;private int mWaveLineColor = Color.parseColor("#EE4000");//波形颜色private float nowX,nowY;//目前的xy坐标//网格private final int GRID_SMALL_WIDTH = 10;//每一个网格的宽度和高度,包括线private final int GRID_BIG_WIDTH = 50;//每一个大网格的宽度和高度,包括线private int xSmallNum,ySmallNum,xBigNum,yBigNum;//小网格的横格,竖格,大网格的横格,竖格数量private final int GRID_LINE_WIDTH=2;//网格的线的宽度private int mWaveSmallLineColor = Color.parseColor("#092100");//小网格颜色private int mWaveBigLineColor = Color.parseColor("#1b4200");//小网格颜色public WaveShowView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public WaveShowView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {mWidth = w;mHeight = h;super.onSizeChanged(w, h, oldw, oldh);}private void init() {mLinePaint = new Paint();mLinePaint.setStyle(Paint.Style.STROKE);mLinePaint.setStrokeWidth(GRID_LINE_WIDTH);mLinePaint.setAntiAlias(true);//抗锯齿效果mWavePaint = new Paint();mWavePaint.setStyle(Paint.Style.STROKE);mWavePaint.setColor(mWaveLineColor);mWavePaint.setStrokeWidth(WAVE_LINE_STROKE_WIDTH);mWavePaint.setAntiAlias(true);//抗锯齿效果mPath = new Path();}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);mWidth = getMeasuredWidth();//获取view的宽mHeight = getMeasuredHeight();//获取view的高row= (int) (mWidth/(GRID_SMALL_WIDTH));//获取行数//小网格xSmallNum = (int) (mHeight/GRID_SMALL_WIDTH);//横线个数=总高度/小网格高度ySmallNum = (int) (mWidth/GRID_SMALL_WIDTH);//竖线个数=总宽度/小网格宽度//大网格xBigNum = (int) (mHeight/GRID_BIG_WIDTH);//横线个数yBigNum = (int) (mWidth/GRID_BIG_WIDTH);//竖线个数}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制网格drawGrid(canvas);//绘制波形drawWaveLine(canvas);}/*** 画折线* @param canvas*/private void drawWaveLine(Canvas canvas) {if(null == refreshList || refreshList.size()<=0){return;}mPath.reset();mPath.moveTo(0f,mHeight/2);for (int i = 0;i<refreshList.size();i++){nowX = i* GRID_SMALL_WIDTH;float dataValue = (float) refreshList.get(i);if(dataValue>0){if(dataValue>MAX_VALUE * 0.8){dataValue = MAX_VALUE * 0.8f;}}else {if(dataValue< -MAX_VALUE * 0.8){dataValue = -MAX_VALUE * 0.8f;}}nowY = mHeight/2 + dataValue *(mHeight/(MAX_VALUE*2));mPath.lineTo(nowX,nowY);}canvas.drawPath(mPath, mWavePaint);if(refreshList.size()>row){refreshList.remove(0);}}//画网格private void drawGrid(Canvas canvas){canvas.drawColor(mBackGroundColor);//画小网格mLinePaint.setColor(mWaveSmallLineColor);//画横线for(int i = 0;i < xSmallNum + 1;i++){canvas.drawLine(0,i*GRID_SMALL_WIDTH,mWidth, i*GRID_SMALL_WIDTH, mLinePaint);}//画竖线for(int i = 0;i < ySmallNum+1;i++){canvas.drawLine(i*GRID_SMALL_WIDTH,0,i*GRID_SMALL_WIDTH,mHeight, mLinePaint);}//画大网格mLinePaint.setColor(mWaveBigLineColor);//画横线for(int i = 0;i < xBigNum + 1;i++){canvas.drawLine(0,i*GRID_BIG_WIDTH,mWidth, i*GRID_BIG_WIDTH, mLinePaint);}//画竖线for(int i = 0;i < yBigNum+1;i++){canvas.drawLine(i*GRID_BIG_WIDTH,0,i*GRID_BIG_WIDTH,mHeight, mLinePaint);}}public void showLine(float line) {refreshList.add(line);postInvalidate();}//重置折现的坐标集合public void resetCanavas() {refreshList.clear();}}

然后写个使用的类,WaveUtil类,非常简单:

Timer是一种定时器,而TimerTask是一个抽象类,表示被Timer计划的任务,实现了Runnable接口。

public class WaveUtil {private Timer timer;private TimerTask timerTask;/*** 模拟源源不断的数据源*/public void showWaveData(final WaveShowView waveShowView){timer = new Timer();timerTask = new TimerTask() {@Overridepublic void run() {waveShowView.showLine(new Random().nextFloat()*(40f)-20f);//取得是-20到20间的浮点数}};//500表示调用schedule方法后等待500ms后调用run方法,50表示以后调用run方法的时间间隔timer.schedule(timerTask,500,50);}/*** 停止绘制波形*/public void stop(){if(timer != null){timer.cancel();timer.purge();timer = null;}if(null != timerTask) {timerTask.cancel();timerTask = null;}}}

最后在activity页面调用,也非常简单,为了避免内存泄漏,退出activity时必须停止绘制:

//开始绘制波形public void start(View view) {WaveShowView waveShowView = findViewById(R.id.waveview);waveUtil.showWaveData(waveShowView);}//停止绘制波形public void stop(View view) {waveUtil.stop();}

其实不用上传git地址的,因为非常简单,还是传一下吧,有更好想法的童鞋欢迎留言:

/androidGL/WaveProject.git

如果觉得《Android自定义View——心电图 曲线图 波形图》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。