public class HeartRateView extends View {
private static final String TAG = HeartRateView.class.getSimpleName();
private int pulses;
private int pointsOfEachPulse;
private Paint paint;
private Path path;
private int[] pointsHeight;
private int[] newPointHeight;
private int points;
private boolean isInit = false;
public HeartRateView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
public HeartRateView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
init(context, attrs);
}
public HeartRateView(Context context) {
this(context, null);
init(context, null);
}
private void init(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.HeartRateLine);
pulses = array.getInt(R.styleable.HeartRateLine_pulses, 2);
pointsOfEachPulse = array.getInt(R.styleable.HeartRateLine_pointsOfEachPulse, 5);
array.recycle();
path = new Path();
paint = new Paint();
paint.setColor(context.getResources().getColor(R.color.light_blue));
paint.setAntiAlias(true);
paint.setStrokeWidth(3f);
paint.setStyle(Paint.Style.STROKE);
CornerPathEffect pathEffect = new CornerPathEffect(20);
paint.setPathEffect(pathEffect);
//在view可视区内的点数
points = pulses * pointsOfEachPulse;
//+pointsOfEathPulse是增加在View的非可视区内的点数(即在非可视区加载一个脉冲),
pointsHeight = new int[points + pointsOfEachPulse];
newPointHeight = new int[points + pointsOfEachPulse];
}
@Override
protected void onDraw(Canvas canvas) {
//点与点之间的间隔
int intervalBetweenPoints = getWidth() / (pulses * pointsOfEachPulse - 1);
//初始化所有点的高,使之全部等于高的一半
if (!isInit) {
for (int i = 0; i < pointsHeight.length; i++) {
pointsHeight[i] = getHeight() / 2;
}
isInit = true;
}
//创建一条路径,并按点与点的间隔递增和poitsHeight数据得到点的位置
path.reset();
path.moveTo(0, getHeight() / 2);
for (int i = 0; i < pointsHeight.length; i++) {
Log.e(TAG, "========>" + pointsHeight[i]);
path.lineTo(intervalBetweenPoints * i, pointsHeight[i]);
}
//画路径
canvas.drawPath(path, paint);
}
public void setData(int data) {
//将数据平移,新数据补位到最后一个位置
for (int i = 0; i < pointsHeight.length; i++){
if (i < pointsHeight.length - 1){
newPointHeight[i] = pointsHeight[i + 1];
}else {
newPointHeight[i] = data;
}
}
//将新数据再次返给旧数组,组成画线的数据
for (int i = 0; i < newPointHeight.length; i++){
pointsHeight[i] = newPointHeight[i];
}
postInvalidate();
}
}
在attrs中添加配置
在Activity中的应用
布局
<com…HeartRateView
android:id="@+id/speed_view"
android:layout_width=“match_parent”
android:layout_height=“match_parent” />
Activity(使用Kotlin语言)
fun startPowerPath(){
//模拟实时数据
val random = Random()
timer = Timer()
timerTask = object : TimerTask() {
override fun run() {
speed_view.setData(random.nextInt(130))
}
}
timer!!.schedule(timerTask, 0, 80)
}
fun stopSpeedPath(){
timerTask!!.cancel()
timer!!.cancel()
timerTask = null
timer = null
}