您的位置:首页 > 移动开发 > Android开发

自定义view之心率线

2016-04-06 11:47 489 查看
先发个图:



我拿着设计图问美工MM,中间这波浪是什么鬼。她说是心率线。额,,,,好吧,无语,画呗。

再怎么说你也弄个正弦波出来啊,算了,看你颜值的份上。。。

效果图:



基本原理图如下,在view的右侧非可视区内加载脉冲数组,一个脉冲数组记录了脉冲那几个点在view中的高度



1.  定义attr属性,并在构造体初始化。

attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="HeartRateLine">
<attr name="pulses" format="integer"/>
<attr name="pointsOfEachPulse" format="integer"/>
<attr name="speed" format="integer"/>
</declare-styleable>
</resources>2.onMeasure不重写,直接onDraw(), layout_width和layout_height最好赋确定值,下面放整个view的代码。
HeartRateLine.java:

public class HeartRateLine extends View {

//脉冲个数
private int pulses;
//每个脉冲的点数,用于画path
private int pointsOfEachPulse;
//心率线每移动一个点距所需的时间
private int speed;
private Paint paint;

private int[] pointsHeight;
private int points;
private boolean isInit=false;
private int count;

public HeartRateLine(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub

TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.HeartRateLine);
pulses=array.getInt(R.styleable.HeartRateLine_pulses, 5);
pointsOfEachPulse=array.getInt(R.styleable.HeartRateLine_pointsOfEachPulse, 10);
speed=array.getInt(R.styleable.HeartRateLine_speed, 100);

array.recycle();

paint=new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStrokeWidth(1f);
paint.setStyle(Style.STROKE);

//在view可视区内的点数
points=pulses*pointsOfEachPulse;
//+pointsOfEathPulse是增加在View的非可视区内的点数(即在非可视区加载一个脉冲),
//+1是为了数组前后依次赋值时避免到最后一个点赋值越界的情况
pointsHeight=new int[points+pointsOfEachPulse+1];

}

public HeartRateLine(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}

public HeartRateLine(Context context) {
this(context, null);
// TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub

//点与点之间的间隔
int intervalBetweenPoints=getWidth()/(pulses*pointsOfEachPulse-1);

//初始化所有点的高,使之全部等于高的一半
if(!isInit){
for(int i=0; i<pointsHeight.length; i++){
pointsHeight[i]=getHeight()/2;
}
isInit=true;
}

//创建一条路径,并按点与点的间隔递增和poitsHeight数据得到点的位置
Path path=new Path();
path.moveTo(0, getHeight()/2);
for(int i=0; i<pointsHeight.length; i++){
path.lineTo(intervalBetweenPoints*i, pointsHeight[i]);
}

//画路径
canvas.drawPath(path, paint);

//使pointsHeight前后依次赋值并重绘,使路径一个点距一个点距地动起来,
//且每一个pulse周期(即pointsOfEachPulse),则在view的右边不可视区域加载新的pulse
postDelayed(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0; i<points+pointsOfEachPulse; i++){
pointsHeight[i]=pointsHeight[i+1];
}
if(count==pointsOfEachPulse){
//随机一个高度以内的数值
int height=(int) (Math.random()*getHeight()/2);

//在pointsOfEachPulse这几个点之内画好你想要的pulse形状
//这里实例只是简单地上下放一个随机高度而已
//这里要确保pointsOfEachPulse>3,否则越界
for(int i=0; i<pointsOfEachPulse; i++){
if(i==1){
pointsHeight[points+i]=getHeight()/2-height;
}else if(i==2){
pointsHeight[points+i]=getHeight()/2+height;
}else{
pointsHeight[points+i]=getHeight()/2;
}
}
count=0;
}
count++;

invalidate();
}
}, speed);
}

}

我只是简单地画了一个闪电状的脉冲图形,其实还可以增加脉冲点数,利用CornerPathEffect可以画出正弦波图形的,这里就简单显示一下而已。

代码下载:github
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息