基于android平台的模拟血压计实现(surfaceView的熟练使用)

这个是我根据上一篇文章的温度计改的血压计,因为客户对温度计还有血压计的需求是一样的,所以,我就选择了偷懒,直接用温度计的代码改了一概,就成了血压计的了

  1 package com.example.test;
  2
  3
  4
  5 import android.content.Context;
  6 import android.graphics.Bitmap;
  7 import android.graphics.Canvas;
  8 import android.graphics.Color;
  9 import android.graphics.Paint;
 10 import android.graphics.RectF;
 11 import android.util.AttributeSet;
 12 import android.util.TypedValue;
 13 import android.view.SurfaceHolder;
 14 import android.view.SurfaceView;
 15
 16
 17
 18
 19 import java.text.DecimalFormat;
 20
 21 /**
 22  * Created by yinxiaofei on 2016/1/13.
 23  */
 24
 25 public class Sphygmomanometer extends SurfaceView implements SurfaceHolder.Callback ,Runnable{
 26
 27     private SurfaceHolder mHolder;
 28     private Canvas mCanvas;
 29
 30     //定义刻度的范围
 31     int temperatureRange=5;
 32     //定义一个盘快的范围
 33     private RectF mRange=new RectF();
 34     //定义温度计的宽度和中心宽度
 35     int mWith;
 36     int mHeight;
 37     int centerWith;
 38     int centerHeight;
 39     //定义总的宽度
 40
 41     //定义温度计刻度总长度
 42     int temperatureAllLong;
 43
 44     //定义一下水银的宽度
 45     int MercuryWith;
 46     //十的倍数的线长度
 47     int MaxLineLong;
 48     //五的倍数的线的长度
 49     int MidLineLong;
 50     //其他刻度线的长度
 51     int MinLineLong;
 52     //刻度间隔
 53     int scaleLong;
 54     //定义温度计距离画布的上宽度
 55     int abHeight;
 56
 57     //绘制线条的画笔
 58     private Paint LinePaint;
 59     //绘制文本的画笔
 60     private Paint TextPaint;
 61
 62     //设置温度上升的速度
 63     private volatile float mSpeed=0;
 64
 65     //设置背景图
 66     private Bitmap mBitmap;
 67
 68     /**
 69      * 定义初始温度,当前显示正在变化也就是显示的温度,还有目标温度
 70      * 其中,初始温度不变,
 71      * 当前温度是有程序根据不同的速度和目标温度计算出来的,
 72      * 目标温度则是由仪器传送过来的数据
 73      */
 74     private float BeginTenperature= (float) 0;
 75     private int EndTenperrature=300;
 76     private volatile float CurrentTemperature= (float) 60;
 77     float TargetTemperature=120;
 78
 79     /**
 80      * 定义每一秒绘制的次数
 81      */
 82     int everySecondTime=50;
 83
 84     //设置文字的大小
 85     private float mTextSize= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SHIFT,25,getResources().getDisplayMetrics());
 86     private float mSymbolTextSize= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SHIFT,35,getResources().getDisplayMetrics());
 87     private float mShowSymbolTextSize= TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SHIFT,45,getResources().getDisplayMetrics());
 88     /**
 89      * 用户绘制的线程
 90      */
 91     private Thread mThread;
 92     /**
 93      * 根据目标温度改变要显示的当前温度的线程
 94      */
 95     private Thread mChangeTemperatureThread;
 96
 97     /**
 98      * 设置一个标志位,用于线程的开启还是关闭的标志
 99      * @param context
100      */
101     private Boolean isRunning;
102     private DecimalFormat fomat;//格式化float
103
104     public Sphygmomanometer(Context context) {
105         this(context, null);
106     }
107
108     public Sphygmomanometer(Context context, AttributeSet attrs) {
109         super(context,attrs);
110         mHolder=getHolder();
111         mHolder.addCallback(this);
112
113     }
114     @Override
115     protected void onMeasure(int with,int height){
116         super.onMeasure(with, height);
117         this.mWith=getMeasuredWidth()/2;
118         this.mHeight=getMeasuredHeight();
119         //这里先把中心设置在屏幕的中心
120         this.centerWith=mWith/2;
121         this.centerHeight=mHeight/2;
122         //设置水银的宽度,暂时设置为总宽度的十五分之一
123         MercuryWith=mWith/15;
124         MinLineLong=MercuryWith;
125         MidLineLong=MinLineLong*8/5;
126         MaxLineLong=MidLineLong*3/2;
127         //temperatureAllLong表示温度刻度总长度
128         temperatureAllLong=mHeight*7/10;
129         //设置刻度间隔,包含了刻度线的长度
130         scaleLong=temperatureAllLong/temperatureRange/10;//表示一个温度十个刻度
131
132
133         abHeight=mHeight/10;
134     }
135     @Override
136     public void surfaceCreated(SurfaceHolder surfaceHolder) {
137         //初始化画笔
138         LinePaint=new Paint();
139         //去锯齿
140         LinePaint.setAntiAlias(true);
141         LinePaint.setColor(Color.BLACK);
142         LinePaint.setStyle(Paint.Style.STROKE);
143         LinePaint.setStrokeWidth(1);
144         //初始化画笔
145         TextPaint=new Paint();
146         TextPaint.setColor(Color.BLACK);
147         TextPaint.setTextSize(mTextSize);
148         TextPaint.setShader(null);
149         //初始化温度计的范围
150         mRange=new RectF(0,0,mWith,mHeight);
151         isRunning=true;
152         mThread =new Thread(this);
153         mThread.start();
154
155     }
156
157     @Override
158     public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
159
160     }
161
162     @Override
163     public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
164
165         isRunning=false;
166
167     }
168
169     @Override
170     public void run() {
171         //不断进行绘制
172         while(isRunning){
173             long start=System.currentTimeMillis();
174             draw();
175             long end=System.currentTimeMillis();
176             if(end-start<everySecondTime){
177                 //这里控制一下,一秒绘制二十次。也就是五十秒绘制一次
178                 try {
179                     Thread.sleep(everySecondTime-(end-start));
180                 } catch (InterruptedException e) {
181                     e.printStackTrace();
182                 }
183             }
184         }
185     }
186
187     private void draw() {
188
189         try {
190             mCanvas=mHolder.lockCanvas();
191             //这里要判断是不是为空,之因为在用户点击了home以后,可能已经执行到这里
192             if(mCanvas!=null)
193             {
194                 //这里是开始绘制自己要的东西
195                 //先绘制背景,
196                 drawBg();
197                 //绘制水银的高度还有,显示体温
198                 drawShowHeightAndShow();
199             }
200         } catch (Exception e) {
201            // e.printStackTrace();这里的异常不处理,
202         } finally {
203             if(mCanvas!=null){
204                 mHolder.unlockCanvasAndPost(mCanvas);
205             }
206         }
207
208     }
209
210     private void drawShowHeightAndShow() {
211
212         //这里控制水银的上升速度
213         //这里要除以20,是因为血压计的刻度值,到温度计的刻度值,是二十倍的换算,主要是偷懒
214         float difference=Math.abs(TargetTemperature-CurrentTemperature)/60;
215         /**
216          * //这里定义一个boolean来控制是使用加法还是减法,其中true表示当前温度小于
217          * 目标温度,要使用加法,false表示当前温度大于目标温度,要使用减法。
218          */
219         boolean addORsub=CurrentTemperature>=TargetTemperature?false:true;
220         if(difference==0||difference<=0.005){
221             mSpeed=0;
222             CurrentTemperature=TargetTemperature;
223         }else{
224             if (difference>2){
225                 mSpeed= (float) 0.03;
226             }else{
227                 if(difference>1){
228                     mSpeed= (float) 0.025;
229                 }else{
230                     if(difference>0.5){
231                         mSpeed= (float) 0.015;
232                     }else{
233                         if(difference>0.3){
234                             mSpeed= (float) 0.012;
235                         }else{
236                             if(difference>0.2){
237                                 mSpeed= (float) 0.009;
238                             }else{
239                                 mSpeed= (float) 0.008;
240                             }
241
242                         }
243                     }
244                 }
245             }
246         }
247         if(addORsub){
248             CurrentTemperature+=mSpeed*100;
249         }else{
250             CurrentTemperature-=mSpeed*100;
251         }
252
253         //
254
255         Paint RectPaint=new Paint();
256         RectPaint.setStyle(Paint.Style.FILL);
257 //        RectPaint.setColor(getResources().getColor(R.color.theme_color));
258 //        这里主要是对温度的显示,画矩形的过程中,唯一改变的就是Top这一个值了
259         //这里(CurrentTemperature-BeginTenperature)/20表示的是刻度值的换算,从温度计过度到血压计的刻度值
260         if(Math.abs(CurrentTemperature-TargetTemperature)>0.8)
261         mCanvas.drawRect(centerWith-MercuryWith/2,
262                 (scaleLong)*10*(temperatureRange)+abHeight*2-
263                         (CurrentTemperature-BeginTenperature)/60*10*scaleLong,
264                 centerWith+MercuryWith/2,
265                 (scaleLong)*10*(temperatureRange)+abHeight*2,
266                 RectPaint);
267         else{
268             mCanvas.drawRect(centerWith-MercuryWith/2,
269                     (scaleLong)*10*(temperatureRange)+abHeight*2-
270                             (TargetTemperature-BeginTenperature)/60*10*scaleLong,
271                     centerWith+MercuryWith/2,
272                     (scaleLong)*10*(temperatureRange)+abHeight*2,
273                     RectPaint);
274         }
275
276         //这里开始画显示的数字
277         Paint ShowNumberTextPaint=new Paint();
278         ShowNumberTextPaint.setColor(Color.BLACK);
279         ShowNumberTextPaint.setTextSize(mShowSymbolTextSize);
280         ShowNumberTextPaint.setShader(null);
281         fomat = new DecimalFormat("##0.0");
282         float display = Float.parseFloat(fomat.format(trueTemperature));
283         mCanvas.drawText(display + " kpa",
284                 mWith * 3 / 2 - ShowNumberTextPaint.getTextSize() * 2,
285                 temperatureAllLong / 2 - ShowNumberTextPaint.getTextSize(),
286                 ShowNumberTextPaint
287         );
288
289
290         mCanvas.drawText(display + " kpa",
291                 mWith*3/2- ShowNumberTextPaint.getTextSize() * 2,
292                 temperatureAllLong/2+ShowNumberTextPaint.getTextSize(),
293                 ShowNumberTextPaint
294         );
295
296     }
297
298     private void drawBg() {
299         mCanvas.drawColor(Color.WHITE);
300 //        mCanvas.drawLine(0, 0, mWith, mHeight, LinePaint);
301         //画右边的刻度
302         //定义每一个长刻度的高度
303         float everyTemparaturHeight=(scaleLong)*10;
304         for(int i=0;i<temperatureRange;i++){
305             mCanvas.drawLine(centerWith + MercuryWith / 2,
306                     everyTemparaturHeight * i + abHeight * 2,//这里加上两倍的上距离
307                     centerWith + MercuryWith / 2 + MidLineLong,
308                     everyTemparaturHeight * i + abHeight * 2, LinePaint);
309             for(int j=1;j<=9;j++){
310                 if(j==5){
311                     mCanvas.drawLine(centerWith+MercuryWith/2,
312                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,
313                             centerWith+MercuryWith/2+MaxLineLong,
314                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,LinePaint);
315                     mCanvas.drawText(EndTenperrature-30 - i * 60 + "", centerWith + MercuryWith / 2 + MaxLineLong + MinLineLong / 3,
316                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2 + TextPaint.getTextSize() / 2 , TextPaint);
317                 }else{
318                     mCanvas.drawLine(centerWith+MercuryWith/2,
319                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,
320                             centerWith+MercuryWith/2+MinLineLong,
321                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,LinePaint);
322                 }
323
324             }
325
326         }
327         //画左边的刻度
328         for(int i=0;i<temperatureRange;i++){
329             mCanvas.drawLine(centerWith-MercuryWith/2,
330                     everyTemparaturHeight*i+abHeight*2,
331                     centerWith-MercuryWith/2-MaxLineLong,
332                     everyTemparaturHeight*i+abHeight*2,LinePaint);
333             if(EndTenperrature-i*60>99)
334             mCanvas.drawText(EndTenperrature-i*60+"", centerWith - (MercuryWith/2+MaxLineLong+MinLineLong/3)-TextPaint.getTextSize()*3/2,
335                     everyTemparaturHeight * i + TextPaint.getTextSize() / 2+abHeight*2, TextPaint);
336             else if(EndTenperrature-i*60>9)
337                 mCanvas.drawText(EndTenperrature-i*60+"", centerWith - (MercuryWith/2+MaxLineLong+MinLineLong/3)-TextPaint.getTextSize(),
338                         everyTemparaturHeight * i + TextPaint.getTextSize() / 2+abHeight*2, TextPaint);
339             else if(EndTenperrature-i*60>=0)
340                 mCanvas.drawText(EndTenperrature-i*60+"", centerWith - (MercuryWith/2+MaxLineLong+MinLineLong/3)-TextPaint.getTextSize()/100,
341                         everyTemparaturHeight * i + TextPaint.getTextSize() / 2+abHeight*2, TextPaint);
342
343             for(int j=1;j<=9;j++){
344                 if(j==5){
345                     mCanvas.drawLine(centerWith-MercuryWith/2,
346                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,
347                             centerWith-MercuryWith/2-MidLineLong,
348                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,LinePaint);
349                 }else{
350                     mCanvas.drawLine(centerWith-MercuryWith/2,
351                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,
352                             centerWith-MercuryWith/2-MinLineLong,
353                             everyTemparaturHeight*i+j*(scaleLong)+abHeight*2,LinePaint);
354                 }
355
356             }
357             //画最后一个刻度
358             if(i==temperatureRange-1){
359                 mCanvas.drawLine(centerWith-MercuryWith/2,
360                         everyTemparaturHeight*(i+1)+abHeight*2,
361                         centerWith-MercuryWith/2-MaxLineLong,
362                         everyTemparaturHeight*(i+1)+abHeight*2,LinePaint);
363                 mCanvas.drawText(EndTenperrature-(i+1)*60+"", centerWith - (MercuryWith/2+MaxLineLong+MinLineLong/3)-TextPaint.getTextSize(),
364                         everyTemparaturHeight * (i+1) + TextPaint.getTextSize() / 2+abHeight*2, TextPaint);
365             }
366         }
367         //画红色的园
368         Paint CirclePaint=new Paint();
369         CirclePaint.setStyle(Paint.Style.FILL);
370  //       CirclePaint.setColor(getResources().getColor(R.color.theme_color));
371         mCanvas.drawCircle(centerWith,
372                 everyTemparaturHeight*(temperatureRange)+abHeight*2+MercuryWith,
373                 MercuryWith*3/2,CirclePaint);
374         //画摄氏度的符号
375         Paint symbolTextPaint=new Paint();
376         symbolTextPaint.setColor(Color.BLACK);
377         symbolTextPaint.setTextSize(mSymbolTextSize);
378         symbolTextPaint.setShader(null);
379         mCanvas.drawText("BP",
380                 centerWith - MaxLineLong / 2 - MercuryWith / 2 - symbolTextPaint.getTextSize() / 2,
381                 abHeight * 2 - symbolTextPaint.getTextSize(),
382                 symbolTextPaint
383         );
384         mCanvas.drawText("BP",
385                 centerWith + MaxLineLong / 2 + MercuryWith / 2 - symbolTextPaint.getTextSize() / 2,
386                 abHeight * 2 - symbolTextPaint.getTextSize(),
387                 symbolTextPaint
388         );
389
390         //绘制显示数字的符号和虚线
391         Paint ShowsymbolTextPaint=new Paint();
392         ShowsymbolTextPaint.setColor(Color.BLACK);
393         ShowsymbolTextPaint.setTextSize(mShowSymbolTextSize);
394         ShowsymbolTextPaint.setShader(null);
395
396         mCanvas.drawText("- - - - - - - -",
397                 mWith * 3 / 2 - ShowsymbolTextPaint.getTextSize() * 2,
398                 temperatureAllLong/2,
399                 ShowsymbolTextPaint
400         );
401
402     }
403
404     private float trueTemperature = 0;
405
406     public void setTargetTemperature(float targetTemperature) {
407         trueTemperature = targetTemperature;
408         if(targetTemperature<0){
409             targetTemperature = 0;
410         }
411         if(targetTemperature>EndTenperrature){
412             targetTemperature = EndTenperrature;
413         }
414         TargetTemperature = targetTemperature;
415     }
416 }

至于xml的布局文件,请参考上一篇文章,其实也和简单

时间: 2024-10-08 03:16:07

基于android平台的模拟血压计实现(surfaceView的熟练使用)的相关文章

基于Android平台的i-jetty网站智能农业监控系统

基于android平台i-jetty网站的智能农业监控系统 摘要:传统的监控系统,一般是基于PC的有线通信传输,其有很多不足之处,如功耗较高.布线成本高.难度大,适应性差,可扩展性不强,增加新的通信线路需要再次布线施工,而且维护起来也比较麻烦,一旦线路出问题,需要繁琐的检查.而嵌入式Web监控系统是基于物联网技术,其无线通信技术具有成本低廉.适应性强.扩展性强.信息安全.使用维护简单等优点. 智能农业中,种植大棚是通过大棚内安装温湿度以及光照传感器,来对农作物的环境参数进行实时采集,由Web监控

基于Android平台的会议室管理系统具体设计说明书

会议室管理系统具体设计说明书 第一部分  引言 1.编写目的 本说明对会议室管理系统项目的各模块.页面.脚本分别进行了实现层面上的要求和说明. 软件开发小组的产品实现成员应该阅读和參考本说明进行代码的编写.測试. 1.2 背景 说明: A.软件系统的名称:会议室管理系统 B. 任务提出者:内蒙古大学计算机学院 开发人员:魏晓蕾 本项目将实现基于Android平台的会议室管理系统的原型部分,而且在该原型的基础上进行功能的扩展和需求的界定,终于完毕的版本号将在全国范围内推广使用. 提供会议室管理功能

基于Android 平台简易即时通讯的研究与设计[转]

摘要:论文简单介绍Android 平台的特性,主要阐述了基于Android 平台简易即时通讯(IM)的作用和功能以及实现方法.(复杂的通讯如引入视频音频等可以考虑AnyChat SDK~)关键词:Android 平台:即时通讯 (本文中图表点击附件即可见) 1 Android 平台简介Android 是Google 公司于2007年11月5日推出的手机操作系统,经过2年多的发展,Android平台在智能移动领域占有不小的份额,由Google为首的40 多家移动通信领域的领军企业组成开放手机联盟(

cocos2dx-2.X前后台切换分析,基于android平台

摘自网上的android生命周期图: cocos2dx-2.X前后台切换分析,基于android平台: 1.从后台进入前台 项目的activity一般继承自Cocos2dxActivity,看过activity生命周期的 都知道onCreate,onResume等方法,这些函数是activity生命周期中 最重要的函数,具体什么时候调用,可以查看相关资料. //刚进入游戏和游戏从后台回到前台会调用 @Override protected void onResume() { super.onRes

基于Android平台简易即时通讯的研究与设计

1 Android平台简介 Android是Google公司于2007年11月5日推出的手机操作系统,经过2年多的发展,Android平台在智能移动领域占有不小的份额,由Google为首的40多家移动通信领域的领军企业组成开放手机联盟(OHA).Google与运营商.设备制造商.开发商和其他第三方结成深层次的合作伙伴关系,希望通过建立标准化.开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统.正因如此,Android正在被越来越多的开发者和使用者所接受.近日,Google发言人Ant

基于Android平台开发的手电筒Light

基于Android平台开发的手电筒Light 1.     需求分析: 在现代社会中,手机的功能越来越完善,手电筒就是这些功能中必不可少的一种.当行走在漆黑的道路上,当你在黑暗狭小的地方寻找物品,当你在家中停电之时,如果你的手机拥有了手电筒的功能,那将为你带来莫大的方便.当然,它的用处不仅仅只是这样,有了这样一个方便携带的手电筒,在许多时候都是大有益处,因此,开发出了手电筒这一应用程序. 2.     开发环境: 1. JDK Ver: jdk-7u4-windows-x64.exe 2. My

基于Android平台的快递轨迹查询应用开发全程视频教程

课程讲师:欧楠课时数量:10(17节)课时用到技术:MenuDrawer.DbUtils.HttpUtils.讯飞语音识别涉及项目:基于Android平台的快递轨迹查询应用开发项目咨询QQ:1609173918 http://yunpan.cn/cVgILJtNYMcDB 访问密码 f885 目前Android平台移动应用开发正如火如荼的发展,智能手机和平板电脑的出货量正快速上升,人们正越来越习惯于在移动平台进行娱乐和各种操作.目前电子商务的发展使人们在每次网购之后都需要了解购买的商品的物流信息

基于Android平台的汽车租赁平台项目的数据库设计心得

我们团队的项目是基于Android平台的汽车租赁平台,其分为手机客户端与web后台管理系统,用以满足租车公司的业务需求,故数据库设计对于本项目显得尤为重要,我们团队数据库设计最开始用的是最原始的方式:Word手动输入,但随后随着数据库课程以及实验的学习,我们最后使用的PowerDesigner设计的数据库并生成了SQL文件,导入数据库完成的数据库最终设计与搭建,我们团队于第8周完成了数据库的搭建. 数据库设计中,数据库要严格与项目需求相联系,同时保证数据库数据完整.正确.安全以及数据处理的高效与

基于ANDROID平台,U3D对蓝牙手柄键值的获取

对于ANDROID平台,物理蓝牙手柄已被封装,上层应用不可见,也就是说对于上层应用,不区分蓝牙手柄还是其它手柄: 完成蓝牙手柄和ANDROID手机的蓝牙连接后,即可以UNITY3D中获取其键值: 在U3D中已有对手柄键值的获取接口,主要分两类: 1.摇杆: translationy = Input.GetAxis("Vertical") * 10.0f; translationx = Input.GetAxis("Horizontal") * 10.0f; Inpu