首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >接收数据实时更新的波状曲线图

接收数据实时更新的波状曲线图

作者头像
用户3112896
发布2019-09-26 15:18:05
1.5K0
发布2019-09-26 15:18:05
举报
文章被收录于专栏:安卓圈安卓圈

前面做了一个心电图的demo 心电图,结果发现那个心电图是静态的,是应用一启动就已经画好了的,整个页面向左滑动而已

下面我改造了一下,写了一个实时接收数据的动态心电图,网上其他地方也有,但是没有讲到重点

我们先看看效果图

很符合要求吧?只不过我没有到达屏幕的最右边就开始向左滑动是为了理解更方便

其实图中的波状曲线并不是在右边一个一个的增加,而是数据增加,每次都全部重绘的一遍而已,看起来的效果就像右边在增加一样,这点要理解

先看代码

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">
    <View        android:layout_width="match_parent"        android:layout_height="300dp"        android:background="#000000" />
    <com.jinke.path.PathView        android:id="@+id/pathView"        android:layout_width="match_parent"        android:layout_height="300dp" /></RelativeLayout>
import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;
import java.util.Timer;import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
    private Timer timer;    private TimerTask timerTask;
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        final PathView pathView = findViewById(R.id.pathView);        //模拟实时数据        timer = new Timer();        timerTask = new TimerTask() {            @Override            public void run() {                Log.i("BLE", "11111111111111111");                pathView.setData(-100);            }        };        timer.schedule(timerTask, 0, 1000);    }
    @Override    protected void onDestroy() {        super.onDestroy();        timerTask.cancel();        timer.cancel();        timerTask = null;        timer = null;    }}
import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.util.Log;import android.view.View;
import java.util.ArrayList;import java.util.List;
public class PathView extends View {    //画笔    protected Paint paint;    //心电图折线    protected Path path;    //自身的大小    private int width, height;
    int tmpX;    //折现的颜色    private int lineColor = Color.parseColor("#76f112");
    private List<Integer> list = new ArrayList<>();
    public PathView(Context context) {        this(context, null);    }
    public PathView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }
    public PathView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        paint = new Paint();        path = new Path();    }
    private void drawPath(Canvas canvas) {        Log.i("BLE", "drawPath");        // 重置path        path.reset();        paint.reset();        tmpX = 0;        path.moveTo(tmpX, height / 2);        //调节好每个波的X轴距离,尽量和滑动的速度保持一致        for (int i = 0; i < list.size(); i++) {            path.lineTo(tmpX + 50, height / 2 + list.get(i));            path.lineTo(tmpX + 100, height / 2);            tmpX += 100;        }        Log.i("BLE", "TMP=" + tmpX);        //设置画笔style        paint.setStyle(Paint.Style.STROKE);        paint.setColor(lineColor);        paint.setStrokeWidth(5);        canvas.drawPath(path, paint);    }
    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        width = w;        height = h;        super.onSizeChanged(w, h, oldw, oldh);    }
    @Override    protected void onDraw(Canvas canvas) {        Log.i("BLE", "onDraw");        drawPath(canvas);        //x轴滑动速度,一开始不滑动,当波形图到达最右边的时候开始滑动        if (list.size() > 15) {            scrollBy(1, 0);        }    }
    public void setData(int data) {        Log.i("BLE", "");        //定期删除历史数据,防止图片过长导致崩溃        if (list.size() > 30) {            for (int i = 0; i < 15; i++) {                list.remove(i);            }            scrollTo(0, 0);        }        list.add(data);        Log.i("BLE", "list-size=" + list.size());        postInvalidate();    }}

自定义View大家都会写,关键是如何让这个自定义View不停的动态重绘呢,网上没有一个说明白的,我来告诉大家

重点:

1.MainActivity里的pathView.setData(-100);方法调用了PathView的setData方法,并传入了更新的值

2.PathView调用了postInvalidate方法,触发重绘

另外在开发中还遇到一个,就是当数据量比较大,View一直向左边滑动,到了某一个时刻,波状图会消失,一片漆黑,看报错原因,是因为滑动的太久,图片拉伸太长导致,手机系统对于长图有一个最长像素值,超过了这个值就会出问题

那么我是如何解决的呢?

1.当数据到达一定量的时候,删掉一部分历史的数据

2.删的同时通过scrollTo(0, 0)方法瞬间滑动最左边

这样就相当于一直在一个固定长度的View上绘图,就不会出问题了,只不过会有少许的偏差,可以调节到滑动的速度和每个波图的X轴距离尽可能的让用户感觉不到

GitHub地址:https://github.com/king1039/Path

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 安卓圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档