Android——ECG心电图的绘制实现(二)

在上篇Android——ECG心电图的绘制实现博客中,实现了心电图的数据展示绘制。

在之后又新增了 心电图的自动滑动展示 实时绘制 功能。效果如下:

自动滑动展示

实时绘制(这里用到了一个timer不断添加数据)

一、自动滑动展示 实现

实现思路:

通过开启定时器实现下标scrollIndex不断增加,以此来计算展示数据的开始下标scrollStartIndex与结束下标scrollEndIndex,来获得一段数据data[]中的展示数据,该段数据刚好填满view的宽度(按比例填满),然后不断的更细视图,实现视觉上的滑动效果(View实际上没有滑动)。如图所示:

代码实现:

首先在initData()初始化数据的时候,调用startScrollTimer()方法,开启一个timer,去不断的更新下标:

    private fun startScrollTimer() {
        timer = Timer()
        timerTask = object : TimerTask() {
            override fun run() {
                if (scrollIndex < data!!.size) {
                    scrollIndex++
                } else {
                    scrollIndex = 0
                }
            }
        }
        timer!!.schedule(timerTask, 0, 50)
    }

然后在ondraw中,进行具体的绘制:

// 绘制心电滚动视图
    private fun drawHeartScroll(canvas: Canvas) {
        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 scrollStartIndex = 0
        var scrollEndIndex = 0

        scrollEndIndex = scrollIndex

        scrollStartIndex = scrollEndIndex - intervalNumHeart
        if (scrollStartIndex < 0) {
            scrollStartIndex = 0
        }

        var nowX: Float
        var nowY: Float
        for (i in scrollStartIndex until scrollEndIndex) {
            nowX = (i - scrollStartIndex) * 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)
            LogUtils.d("drawHeartScroll $nowX $nowY")
        }

        canvas.drawPath(path!!, paint!!)
        postInvalidate()
    }

其中,前半部分是对数据下标的整理,后半部分是对整理的data数据进行实时展示。

二、实时绘制刷新refresh 实现

实现思路

这个就比上一个复杂多了。通过showLine(float float) 方法,让外界能输入数据并动态展示在心电图上,也就是说需要实现一个动态递增的Arraylist,然后在具体的绘制中,实现如下所示的数据结构:

第1次添加   1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,                      
第2次添加   1 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,                      
第3次添加   1 , 2 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,                      
第4次添加   1 , 2 , 3 , 4 , 0 , 0 , 0 , 0 , 0 , 0 ,                      
第5次添加   1 , 2 , 3 , 4 , 5 , 0 , 0 , 0 , 0 , 0 ,                      
第6次添加   1 , 2 , 3 , 4 , 5 , 6 , 0 , 0 , 0 , 0 ,                      
第7次添加   1 , 2 , 3 , 4 , 5 , 6 , 7 , 0 , 0 , 0 ,                      
第8次添加   1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 0 , 0 ,                      
第9次添加   1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,                      
第10次添加   1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,                      
第11次添加   11 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,                      
第12次添加   11 , 12 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,                      
第13次添加   11 , 12 , 13 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ,                      
第14次添加   11 , 12 , 13 , 14 , 5 , 6 , 7 , 8 , 9 , 10 ,                      
第15次添加   11 , 12 , 13 , 14 , 15 , 6 , 7 , 8 , 9 , 10 ,                      
第16次添加   11 , 12 , 13 , 14 , 15 , 16 , 7 , 8 , 9 , 10 ,                      
第17次添加   11 , 12 , 13 , 14 , 15 , 16 , 17 , 8 , 9 , 10 ,                      
第18次添加   11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 9 , 10 ,                      
第19次添加   11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 10 ,                      
第20次添加   11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ,                      
第21次添加   21 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ,                      
第22次添加   21 , 22 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ,                      
第23次添加   21 , 22 , 23 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ,                      
第24次添加   21 , 22 , 23 , 24 , 15 , 16 , 17 , 18 , 19 , 20 ,                      
第25次添加   21 , 22 , 23 , 24 , 25 , 16 , 17 , 18 , 19 , 20 ,                      
第26次添加   21 , 22 , 23 , 24 , 25 , 26 , 17 , 18 , 19 , 20 ,                      
第27次添加   21 , 22 , 23 , 24 , 25 , 26 , 27 , 18 , 19 , 20 ,    ....(后面省略)

可以看到要位置一个总长度固定的数据,但是随着数据的增加新的数据是从左往右进行刷新的(对应刷新心电图数据的刷新方式),实现了该结构之后,再去做数据展示就可以实现心电图的刷新绘制了。

为此我专门写了一个测试类去测试:

public class TestClass {
    private static List<Float> refreshList = new ArrayList<>();
    private static float[] data; //一排显示的数据  一排10个
    private static int intervalNumHeart = 10;

    private static int showIndex;

    public static void main(String[] args) {
        data = new float[intervalNumHeart];

        for (int i = 1; i < 100; i++) {
            refreshList.add((float) i);
            drawHeartRefresh();
        }

    }

    private static void drawHeartRefresh() {
        int nowIndex = refreshList.size(); //当前长度
        if (nowIndex < intervalNumHeart) {
            showIndex = nowIndex - 1;
        } else {
            showIndex = (nowIndex - 1) % intervalNumHeart;
        }
        for (int i = 0; i < intervalNumHeart; i++) {
            if (i > refreshList.size() - 1) {
                break;
            }
            if (nowIndex <= intervalNumHeart) {
                data[i] = refreshList.get(i);
            } else {
                int times = (nowIndex - 1) / intervalNumHeart;
                int temp = times * intervalNumHeart + i;
                if (temp < nowIndex) {
                    data[i] =
                            refreshList.get(temp);
                }
            }
        }
        logdata();
    }

    private static void logdata() {
        String str = "";
        for (float temp : data) {
            int tempInt = (int) temp;
            str += tempInt + " , ";

        }
        Log( "第" +(refreshList.size()) + "次添加   " + str + "                     " );
    }

    private static void Log(String txt) {
        System.out.println(txt);
    }

}

代码实现

一样分为两个部分,前半部分实现该结构,后半部分进行具体的绘制:

private fun drawHeartRefresh(canvas: Canvas) {
        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)

        val nowIndex = if (refreshList == null) 0 else refreshList!!.size //当前长度

        if (nowIndex == 0) {
            return
        }

        if (nowIndex < intervalNumHeart) {
            showIndex = nowIndex - 1
        } else {
            showIndex = (nowIndex - 1) % intervalNumHeart
        }


        for (i in 0 until intervalNumHeart) {
            if (i > refreshList!!.size - 1) {
                break
            }
            if (nowIndex <= intervalNumHeart) {

                data!![i] = refreshList!![i]
            } else {
                val times = (nowIndex - 1) / intervalNumHeart

                val temp = times * intervalNumHeart + i

                if (temp < nowIndex) {
                    data?.set(i, refreshList!![temp])
                }
            }
        }

        logdata()

        //绘制出data
        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

            if (i - 1 == showIndex) {
                path!!.moveTo(nowX, nowY)

            } else {
                path!!.lineTo(nowX, nowY)
            }

        }

        canvas.drawPath(path!!, paint!!)
    }

 

 

近期在把所有写过的自定义view(实用性较强的)整理成一个开源框架,Github地址:

https://github.com/jiangzhengnan/UI#ngui

gradle依赖:

compile 'ng.ngui.ngbase:nguilib:0.0.1'

  • 11
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值