手把手教你打造一个心电图效果View Android自定义View
大家好,看我像不像蘑菇…因为我在学校呆的发霉了。
思而不学则殆
丽丽说得对,我有奇怪的疑问,大都是思而不学造成的,在我书读不够的情况下想太多,大多等于白想,所以革命没成功,同志仍需努力。
好了废话不说了,由于布总要做一个心电图的玩意,所以做来练练手,总之拿到的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的更多相关文章
- 手把手带你做一个超炫酷loading成功动画view Android自定义view
写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾 ...
- 手把手带你画一个漂亮蜂窝view Android自定义view
上一篇做了一个水波纹view 不知道大家有没有动手试试呢点击打开链接 这个效果做起来好像没什么意义,如果不加监听回调 图片就能直接替代.写这篇博客的目的是锻炼一下思维能力,以更好的面多各种自定义vi ...
- 手把手教你打造一个纯CSS图标库
来,干了这碗安利 写这篇文章的目的其实就是为了安利一下我的图标库:iconoo,所以,开门见山,star吧少年少妇们!(这样的我是不是应该要加个github互粉的团伙了?) 主题说完了,下面进入正题. ...
- 手把手教你打造一个 Mac 风格的 Windows10(手动滑稽)
Mark https://www.sqlsec.com/2018/04/winmac.html 大佬写得很好,资瓷!! MyDock可能不是最新的,给出官方维护的网盘:https://pan.bai ...
- 简单说说Android自定义view学习推荐的方式
这几天比较受关注,挺开心的,嘿嘿. 这里给大家总结一下学习自定义view的一些技巧. 以后写自定义view可能不会写博客了,但是可以开源的我会把源码丢到github上我的地址:https://git ...
- Android:手把手教你打造可缩放移动的ImageView(下)
在上一篇Android:手把手教你打造可缩放移动的ImageView最后提出了一个注意点:当自定义的MatrixImageView如ViewPager.ListView等带有滑动效果的ViewGrou ...
- iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- 只有20行Javascript代码!手把手教你写一个页面模板引擎
http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...
- PWA入门:手把手教你制作一个PWA应用
摘要: PWA图文教程 原文:PWA入门:手把手教你制作一个PWA应用 作者:MudOnTire Fundebug经授权转载,版权归原作者所有. 简介 Web前端的同学是否想过学习app开发,以弥补自 ...
随机推荐
- Go 语言环境安装
Go 语言支持以下系统: Linux FreeBSD Mac OS X(也称为 Darwin) Window 安装包下载地址为:https://golang.org/dl/. 各个系统对应的包名: 操 ...
- PHP 5 Array 函数
PHP Array 简介 PHP Array 函数允许您访问并操作数组. 支持简单的数组和多维数组. 安装 PHP Array 函数是 PHP 核心的组成部分.无需安装即可使用这些函数. PHP 5 ...
- Java课程设计常见技术问题(程序部署、数据库、JSP)
1. 部署方法 Eclipse下打包 右键点击项目-Export-Runnable JAR file,选择正确的Launch configuration,接下来根据提示可以将项目中用到的jar打入包中 ...
- Java实验链接
第1次实验 课堂实验内容:Java入门+Eclipse+PTA+Git+博客 实验任务书:第01次试验(安装JDK.编辑器.编写出第一个Java程序).pdf Eclipse简明教程(by郑如滨).p ...
- mongo 读分析
分布式读 读冲突 分布式中数据库有多份数据,各份数据可能存在不一致性. mongo 只会写到primary节点上,理论上来说不会有文档冲突,也就是说数据库中的数据都以primary节点为标准. 但是有 ...
- Objective-C与Java类的一些区别
Objective-C与Java类的一些区别 OC类和C一样,需要有声明和定义,先上一段OC代码 #import <Foundation/Foundation.h> /* * 声明一个Pe ...
- JAVA面向对象-----抽象类注意细节
抽象类可以没有抽象方法(java.awt.*的类就是这样子操作的). 抽象类可以继承普通类与抽象类. 抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化. 抽象类一定有构造方法 ...
- Impala中的代码生成技术
Cloudera Impala是一种为Hadoop生态系统打造的开源MPP(massive parallel processing)数据库,它主要为分析型查询负载而设计,而非OLTP.Impala能最 ...
- Ubuntu 安装 texlive2013 及中文支持
分享一下安装和配置经验. 1.材料准备 texlive的安装包:可以百度下,这里也提供一个下载地址: http://mirror.hust.edu.cn/CTAN/systems/texlive/Im ...
- DBoW2应用
图像对应的bag-of-words向量\(v_t\) 假设词典总共有\(W\)个单词,那么每一幅图像能够用一个\(W\)维的向量表示 \((t_1, t_2, t_3, ..., t_W)\)其中 \ ...