转至:http://blog.csdn.net/dawanganban/article/details/31445249
public class MyView extends View {
private static int ORIGIN_X = 60; // 原点x坐标
private static int ORIGIN_Y = 260;// 原点y坐标
private static int X_SCALE = 8; // 刻度长度
private static int Y_SCALE = 40;
private static int X_LENGTH = 380; // x轴总长度
private static int Y_LENGTH = 240;
private static int MAX_DATA_SIZE = X_LENGTH / X_SCALE; // 最大数据个数
private static int Y_SCALE_COUNT = Y_LENGTH / Y_SCALE; // y轴刻度个数
private List<Integer> data = new ArrayList<Integer>(); // 数据值集合
private String[] YLabels = new String[Y_LENGTH / Y_SCALE]; // Y轴标签
// View刷新
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0) {
MyView.this.invalidate();
}
};
};
Paint paint = new Paint();
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// 初始化y轴标签
for (int i = 0; i < YLabels.length; i++) {
YLabels[i] = i + "M/s";
}
// 每秒钟随机加入一个数据,删除第一个数据,然后刷新
randomData();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 画标签和坐标轴
drawLabelAndAxes(canvas);
// // 画数据,对应的线条
// // drawDataLine(canvas);//第一种方式
// 画数据,对应的路径
// // drawDataPath(canvas);//第二种方式
drawDataPath2(canvas);// 第二种方式,加一层外线
}
private void drawDataPath2(Canvas canvas) {
paint.setColor(Color.parseColor("#73B0C4"));
paint.setAntiAlias(true); // 去锯齿
paint.setStyle(Paint.Style.FILL);
Paint paintLine = new Paint();
paintLine.setColor(Color.RED);
paintLine.setAntiAlias(true); // 去锯齿
paintLine.setStyle(Paint.Style.STROKE);
if (data.size() > 1) {
Path path = new Path();
Path pathLine = new Path();
path.moveTo(ORIGIN_X, ORIGIN_Y); // 原点起
pathLine.moveTo(ORIGIN_X, ORIGIN_Y - data.get(0) * Y_SCALE);
for (int i = 0; i < data.size(); i++) {
path.lineTo(ORIGIN_X + i * X_SCALE, ORIGIN_Y - data.get(i)
* Y_SCALE); // 中间点
pathLine.lineTo(ORIGIN_X + i * X_SCALE, ORIGIN_Y - data.get(i)
* Y_SCALE); // 中间点
}
path.lineTo(ORIGIN_X + (data.size() - 1) * X_SCALE, ORIGIN_Y); // x轴上点结束
canvas.drawPath(path, paint);// 画线下背景
canvas.drawPath(pathLine, paintLine);// 画线
}
}
private void drawDataPath(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
if (data.size() > 1) {
Path path = new Path();
path.moveTo(ORIGIN_X, ORIGIN_Y); // 原点起
for (int i = 0; i < data.size(); i++) {
path.lineTo(ORIGIN_X + i * X_SCALE, ORIGIN_Y - data.get(i)
* Y_SCALE); // 中间点
}
path.lineTo(ORIGIN_X + (data.size() - 1) * X_SCALE, ORIGIN_Y); // x轴上点结束
canvas.drawPath(path, paint);
}
}
private void randomData() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (data.size() >= MAX_DATA_SIZE) {
data.remove(0);
}
data.add(new Random().nextInt(4) + 1);
handler.sendEmptyMessage(0);
}
}
}).start();
}
private void initPaint() {
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true); // 去锯齿
paint.setColor(Color.BLUE);
}
private void drawDataLine(Canvas canvas) {
if (data.size() > 1) {
for (int i = 1; i < data.size(); i++) {
canvas.drawLine(ORIGIN_X + (i - 1) * X_SCALE,
ORIGIN_Y - data.get(i - 1) * Y_SCALE, ORIGIN_X + i
* X_SCALE, ORIGIN_Y - data.get(i) * Y_SCALE,
paint);
}
}
}
private void drawLabelAndAxes(Canvas canvas) {
// 初始化画笔
initPaint();
// 画Y轴
canvas.drawLine(ORIGIN_X, ORIGIN_Y - Y_LENGTH, ORIGIN_X, ORIGIN_Y,
paint);
// Y轴箭头
canvas.drawLine(ORIGIN_X, ORIGIN_Y - Y_LENGTH, ORIGIN_X - 3, ORIGIN_Y
- Y_LENGTH + 6, paint);
canvas.drawLine(ORIGIN_X, ORIGIN_Y - Y_LENGTH, ORIGIN_X + 3, ORIGIN_Y
- Y_LENGTH + 6, paint);
// 添加刻度和文字
for (int i = 0; i < Y_SCALE_COUNT; i++) {
canvas.drawLine(ORIGIN_X, ORIGIN_Y - i * Y_SCALE, ORIGIN_X + 5,
ORIGIN_Y - i * Y_SCALE, paint); // 刻度
canvas.drawText(YLabels[i], ORIGIN_X - 50, ORIGIN_Y - i * Y_SCALE,
paint);// 文字
}
// 画X轴
canvas.drawLine(ORIGIN_X, ORIGIN_Y, ORIGIN_X + X_LENGTH, ORIGIN_Y,
paint);
}
}