Android——ECG心电图的绘制实现
Posted 化作孤岛的瓜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android——ECG心电图的绘制实现相关的知识,希望对你有一定的参考价值。
最近在项目中需要使用到的心电Ecg显示效果,本来打算使用sdk方的视图组件的,但是奈何他们的组件问题太多了。比如网格不对齐(强迫症表示这个无法忍),组件不支持静态显示数据等等问题。所以打算自己写一个用来做主页面的心电数据展示。
首先要实现以下几个功能点:
1.网格的大小,颜色可控。
2.心电线条的颜色粗细可控。
3.无论传入的数据源长度是多少,都要均匀的显示在表格上(按一定的比例尺缩放或者扩展)
之后可能会实现动态显示数据的部分,会在本篇博客更新。
技术实现要点:
传入的数据源是String字符串,类似于:"0.101253886148333549,0.001253886148333549,0.003036087844520807,0.002440808573737741"
这样的数据,所以这里要对传入的数据进行处理,根据数据的个数确定屏幕上一共要均匀连线多少个点。
代码实现:
class EcgShowView : View
private var mWidth: Float = 0.toFloat()
private var mHeight: Float = 0.toFloat()
private var paint: Paint? = null
private var path: Path? = null
private var dataStrList: Array<String>? = null
private var intervalNumHeart: Int = 0
private var intervalRowHeart: Float = 0.toFloat()
private var intervalColumnHeart: Float = 0.toFloat()
private var data: FloatArray? = null
private var mHeartLinestrokeWidth: Float = 0.toFloat()
private var row: Int = 0
private var intervalRow: Float = 0.toFloat()
private var column: Int = 0
private var intervalColumn: Float = 0.toFloat()
private var mGridLinestrokeWidth: Float = 0.toFloat()
private var mGridstrokeWidthAndHeight: Float = 0.toFloat()
//心电
private val MAX_VALUE = 20f //峰值
private val HEART_LINE_STROKE_WIDTH = 5f
//网格
private val GRID_LINE_STROKE_WIDTH = 3f
private val GRID_WIDTH_AND_HEIGHT = 10f
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
init()
private fun init()
paint = Paint()
path = Path()
//setLayerType(View.LAYER_TYPE_SOFTWARE, null);
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int)
super.onLayout(changed, left, top, right, bottom)
mWidth = measuredWidth.toFloat()
mHeight = measuredHeight.toFloat()
mGridLinestrokeWidth = dip2px(GRID_LINE_STROKE_WIDTH).toFloat()
mGridstrokeWidthAndHeight = dip2px(GRID_WIDTH_AND_HEIGHT).toFloat()
column = (mWidth / mGridstrokeWidthAndHeight).toInt();
intervalColumn = mWidth / column
row = (mHeight / mGridstrokeWidthAndHeight).toInt()
intervalRow = mHeight / row
mHeartLinestrokeWidth = dip2px(HEART_LINE_STROKE_WIDTH).toFloat()
initData()
override fun onDraw(canvas: Canvas)
super.onDraw(canvas)
//绘制网格
paint!!.style = Paint.Style.STROKE
paint!!.color = Color.parseColor("#D8D8D8")
paint!!.strokeWidth = mGridLinestrokeWidth
paint!!.isAntiAlias = true
for (i in 0..column)
val iTempC = i * intervalColumn
path!!.moveTo(iTempC, 0f)
path!!.lineTo(iTempC, mHeight)
for (i in 0..row)
path!!.moveTo(0f, i * intervalRow)
path!!.lineTo(mWidth, i * intervalRow)
canvas.drawPath(path!!, paint!!)
//绘制心电图
if (data == null || data!!.size == 0)
return
paint!!.reset()
path!!.reset()
paint!!.style = Paint.Style.STROKE
paint!!.color = Color.parseColor("#31CE32")
paint!!.strokeWidth = mGridLinestrokeWidth
paint!!.isAntiAlias = true
path!!.moveTo(0f, mHeight / 2)
var nowX: Float
var nowY: Float
for (i in data!!.indices)
nowX = i * intervalRowHeart
var dataValue = data!![i]
if (dataValue > 0)
if (dataValue > MAX_VALUE * 0.8f)
dataValue = MAX_VALUE * 0.8f
else
if (dataValue < -MAX_VALUE * 0.8f)
dataValue = -(MAX_VALUE * 0.8f)
nowY = mHeight / 2 - dataValue * intervalColumnHeart
path!!.lineTo(nowX, nowY)
canvas.drawPath(path!!, paint!!)
fun setData(dataStr: String)
dataStrList = dataStr.split(",".toRegex()).dropLastWhile it.isEmpty() .toTypedArray()
initData()
private fun initData()
try
var dataLength = dataStrList!!.size
if (dataLength > mWidth)
dataLength = mWidth.toInt()
data = FloatArray(dataLength)
for (i in 0 until dataLength)
data!![i] = java.lang.Float.parseFloat(dataStrList!![i])
intervalNumHeart = data!!.size
intervalRowHeart = mWidth / intervalNumHeart
intervalColumnHeart = mHeight / (MAX_VALUE * 2)
catch (e: Exception)
e.printStackTrace()
private fun px2dip(px: Int): Int
val scale = context.resources.displayMetrics.density
return (px / scale + 0.5f).toInt()
private fun dip2px(dipValue: Float): Int
val scale = context.resources.displayMetrics.density
return (dipValue * scale + 0.5f).toInt()
Github项目地址:
https://github.com/jiangzhengnan/UI
最近会把实现的UI效果都集中到一个库里面,求start~
以上是关于Android——ECG心电图的绘制实现的主要内容,如果未能解决你的问题,请参考以下文章