大家好,看我像不像蘑菇…因为我在学校呆的发霉了。

思而不学则殆

丽丽说得对,我有奇怪的疑问,大都是思而不学造成的,在我书读不够的情况下想太多,大多等于白想,所以革命没成功,同志仍需努力。

好了废话不说了,由于布总要做一个心电图的玩意,所以做来练练手,总之拿到的UI图如下:

做好的效果如下:



拿到图,先做一些简单的分析。呃..

  • 背景表格的绘制
  • 心电图的绘制

背景表格的绘制:

首先drawColor黑色,然后用循环来画线、

心电图的绘制:

看样子是path,应该没问题。

于是就大干一番,按照这俩步骤画完了。。结果发现,嗯。。确实画上去了,关键怎么让他动呢。。 轻而易举想到scrollBy吧。然后你就发现。。背景也跟着变了。。 遇到问题就要解决。。所以这里投机取巧一下 把两个View分离,即背景是一个View,折线图是一个View。

首先,创建一个View,用来做背景View。他有一些属性,因为这些View本来是一个,后来又有一个折现View需要相同的属性,所以索性偷懒改成protected修饰。。

转载请注明出处:http://blog.csdn.net/wingichoy/article/details/51023865

public class CardiographView extends View {
//画笔
protected Paint mPaint;
//折现的颜色
protected int mLineColor = Color.parseColor("#76f112");
//网格颜色
protected int mGridColor = Color.parseColor("#1b4200"); //小网格颜色
protected int mSGridColor = Color.parseColor("#092100");
//背景颜色
protected int mBackgroundColor = Color.BLACK;
//自身的大小
protected int mWidth,mHeight; //网格宽度
protected int mGridWidth = 50;
//小网格的宽度
protected int mSGridWidth = 10; //心电图折现
protected Path mPath ;

定义了这些属性,在构造器里初始化一下画笔和Path

public CardiographView(Context context) {
this(context,null);
} public CardiographView(Context context, AttributeSet attrs) {
this(context, attrs,0);
} public CardiographView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint();
mPath = new Path();
}

接下来拿到自身的宽高。注意为了简化例子,这里就不测量了

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mWidth = w;
mHeight = h;
super.onSizeChanged(w, h, oldw, oldh);
}

准备工作都完成,开始绘制背景,创建一个drawBackground(Canvas canvas)方法。

可以想到,用for循环来画横线竖线。横线的起始x坐标都是0,终止x坐标是mWidth, y坐标为i*mGridWidth(网格宽度),我们要拿到网格的个数,即宽高除以网格宽度,具体操作看代码:

 private void initBackground(Canvas canvas) {

        canvas.drawColor(mBackgroundColor);
//画小网格 //竖线个数
int vSNum = mWidth /mSGridWidth; //横线个数
int hSNum = mHeight/mSGridWidth;
mPaint.setColor(mSGridColor);
mPaint.setStrokeWidth(2);
//画竖线
for(int i = 0;i<vSNum+1;i++){
canvas.drawLine(i*mSGridWidth,0,i*mSGridWidth,mHeight,mPaint);
}
//画横线
for(int i = 0;i<hSNum+1;i++){ canvas.drawLine(0,i*mSGridWidth,mWidth,i*mSGridWidth,mPaint);
} //竖线个数
int vNum = mWidth / mGridWidth;
//横线个数
int hNum = mHeight / mGridWidth;
mPaint.setColor(mGridColor);
mPaint.setStrokeWidth(2);
//画竖线
for(int i = 0;i<vNum+1;i++){
canvas.drawLine(i*mGridWidth,0,i*mGridWidth,mHeight,mPaint);
}
//画横线
for(int i = 0;i<hNum+1;i++){
canvas.drawLine(0,i*mGridWidth,mWidth,i*mGridWidth,mPaint);
} }

现在的运行效果是这样的:



呃。。。看起来像点样子了。。

现在给加上Path吧。。新建一个View,写到相对布局的底部

<?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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.wingsofts.cardiograph.MainActivity">
<com.wingsofts.cardiograph.CardiographView
android:layout_width="match_parent"
android:layout_height="match_parent"></com.wingsofts.cardiograph.CardiographView> <com.wingsofts.cardiograph.PathView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

为了简单起见,新建一个View 继承CardiographView, 这里只需要重写他的ondraw方法即可,其他属性不需要定义。

 private void drawPath(Canvas canvas) {
// 重置path
mPath.reset(); //用path模拟一个心电图样式
mPath.moveTo(0,mHeight/2);
int tmp = 0;
for(int i = 0;i<10;i++) {
mPath.lineTo(tmp+20, 100);
mPath.lineTo(tmp+70, mHeight / 2 + 50);
mPath.lineTo(tmp+80, mHeight / 2); mPath.lineTo(tmp+200, mHeight / 2);
tmp = tmp+200;
}
//设置画笔style
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(mLineColor);
mPaint.setStrokeWidth(5);
canvas.drawPath(mPath,mPaint); }

好了,现在画出来是这样的:

那怎么让他动起来呢。 当然是scrollBy了~~ 这里注意下scrollBy 和scrollTo的区别,面试常考的,之后再postInvalidateDelayed即可

  @Override
protected void onDraw(Canvas canvas) {
drawPath(canvas);
scrollBy(1,0);
postInvalidateDelayed(10);
}

大功告成! 这样就和上面的实现图一样了:

当然这只是个demo,你可以根据自己的需求去不同的坐标去绘制,来达到真实的心电图效果。

如果你喜欢我的博客,请点关注哦。。

另外:如果你有职位 只要在广州 欢迎拉我,我刚辞实习工作,六月就要毕业了,即将失业了!!!

本项目地址(求star):点击打开

手把手教你打造一个心电图效果View Android自定义View的更多相关文章

  1. 手把手带你做一个超炫酷loading成功动画view Android自定义view

    写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾 ...

  2. 手把手带你画一个漂亮蜂窝view Android自定义view

    上一篇做了一个水波纹view  不知道大家有没有动手试试呢点击打开链接 这个效果做起来好像没什么意义,如果不加监听回调 图片就能直接替代.写这篇博客的目的是锻炼一下思维能力,以更好的面多各种自定义vi ...

  3. 手把手教你打造一个纯CSS图标库

    来,干了这碗安利 写这篇文章的目的其实就是为了安利一下我的图标库:iconoo,所以,开门见山,star吧少年少妇们!(这样的我是不是应该要加个github互粉的团伙了?) 主题说完了,下面进入正题. ...

  4. 手把手教你打造一个 Mac 风格的 Windows10(手动滑稽)

    Mark  https://www.sqlsec.com/2018/04/winmac.html 大佬写得很好,资瓷!! MyDock可能不是最新的,给出官方维护的网盘:https://pan.bai ...

  5. 简单说说Android自定义view学习推荐的方式

    这几天比较受关注,挺开心的,嘿嘿. 这里给大家总结一下学习自定义view的一些技巧.  以后写自定义view可能不会写博客了,但是可以开源的我会把源码丢到github上我的地址:https://git ...

  6. Android:手把手教你打造可缩放移动的ImageView(下)

    在上一篇Android:手把手教你打造可缩放移动的ImageView最后提出了一个注意点:当自定义的MatrixImageView如ViewPager.ListView等带有滑动效果的ViewGrou ...

  7. iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  8. 只有20行Javascript代码!手把手教你写一个页面模板引擎

    http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...

  9. PWA入门:手把手教你制作一个PWA应用

    摘要: PWA图文教程 原文:PWA入门:手把手教你制作一个PWA应用 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 简介 Web前端的同学是否想过学习app开发,以弥补自 ...

随机推荐

  1. Spring + mybatis 集成

    具体项目可参照:https://github.com/LuoXiaoyi/springmvc 一.环境准备:Spring4.3.5 + Mybatis3.4.6 + Mybatis-Spring 1. ...

  2. jQuery AJAX 简介

    AJAX 是与服务器交换数据的技术,它在不重载全部页面的情况下,实现了对部分网页的更新. jQuery AJAX 实例 使用 jQuery AJAX 修改文本内容 尝试一下 » 什么是 AJAX? A ...

  3. Docker常见仓库Node.js

    Node.js 基本信息 Node.js是基于 JavaScript 的可扩展服务端和网络软件开发平台. 该仓库提供了 Node.js 0.8 ~ 0.11 各个版本的镜像. 使用方法 在项目中创建一 ...

  4. 状态模式、职责链模式——省去if-else的繁琐结构

    小时候写日记都是这么写的:上午七点起床,八点之前洗脸刷牙吃早饭,十二点之前好好上课,中午一点,吃午饭,下午两点到六点,上课,下课,找请假,明天妈妈要带我去姥姥家,九点之前,看动画片,九点钟,收拾去姥姥 ...

  5. javaweb异常提示信息统一处理(使用springmvc,附源码)

    一.前言 后台出现异常如何友好而又高效地回显到前端呢?直接将一堆的错误信息抛给用户界面,显然不合适. 先不考虑代码实现,我们希望是这样的: (1)如果是页面跳转的请求,出现异常了,我们希望跳转到一个异 ...

  6. 初识gd库

    必备基础 开启GD拓展 列表使用 获取图片信息代码 图片详细信息 特效函数 示例 运行结果 分析 获取图片基本信息 获取图片宽度 获取图片高度 获取图片后缀名 获取图片mime类型 操作图片 添加文字 ...

  7. 递归的神奇之处在于你会发现问题竟然解决了--解N皇后谜题有感

    看sicp看到8皇后谜题, 突然兴致来了,尝试独立解决(scheme代码的好处在于,即使你瞟了眼答案, 也不会有任何收获, 除了知道那儿有一坨神秘的括号和英文字符外但Python代码就不同了),成功了 ...

  8. Android EditText在ScrollView中被输入法遮挡

    千言万语不如一张图来的实在,问题如下GIF图所示[输入框被输入法挡住了]: 为了不让底部的按钮随着输入法一起起来,我把windowSoftInputMode设置为adjustPan. <acti ...

  9. 2.关于QT中的Dialog(模态窗口),文件选择器,颜色选择器,字体选择器,消息提示窗口

     1 新建一个空项目 A 编写 .pro文件 QT += gui widgets HEADERS += \ MyDialog.h SOURCES += \ MyDialog.cpp B 编写MyD ...

  10. Github客户端以及Git shell的使用

    昨天介绍了怎么使用Git Shell来commit我们的代码,但是这都是简单的操作,我们还没有使用到Github是怎么进行版本控制的呢.所以,今天就来介绍一下,怎么来做版本控制吧. 必备材料 首先要确 ...