上一章讲过折线图,但是如果只是普通的图片似乎太简单。设计师又不能忍了。
于是有了下面的效果:
一、效果图:
二、代码实现:
重写onTouchEvent事件:
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (x > width / 14 && x < width * 3 / 14) {
touchMonth = 1;
invalidate();
}
if (x > width * 3 / 14 && x < width * 5 / 14) {
touchMonth = 2;
invalidate();
}
if (x > width * 5 / 14 && x < width * 7 / 14) {
touchMonth = 3;
invalidate();
}
if (x > width * 7 / 14 && x < width * 9 / 14) {
touchMonth = 4;
invalidate();
}
if (x > width * 9 / 14 && x < width * 11 / 14) {
touchMonth = 5;
invalidate();
}
if (x > width * 11 / 14 && x < width * 13 / 14) {
touchMonth = 6;
invalidate();
}
break;
case MotionEvent.ACTION_MOVE:
if (x > width / 14 && x < width * 3 / 14) {
touchMonth = 1;
invalidate();
}
if (x > width * 3 / 14 && x < width * 5 / 14) {
touchMonth = 2;
invalidate();
}
if (x > width * 5 / 14 && x < width * 7 / 14) {
touchMonth = 3;
invalidate();
}
if (x > width * 7 / 14 && x < width * 9 / 14) {
touchMonth = 4;
invalidate();
}
if (x > width * 9 / 14 && x < width * 11 / 14) {
touchMonth = 5;
invalidate();
}
if (x > width * 11 / 14 && x < width * 13 / 14) {
touchMonth = 6;
invalidate();
}
break;
case MotionEvent.ACTION_UP:
// touchMonth = 0;
// invalidate();
break;
}
return true;
}
说明一下:touchMonth是一个标志位,按下,移动,抬起的时候改变相应数值。在onDraw方法中通过标志位改变UI。看代码:
@Override
protected void onDraw(Canvas canvas) {
width = getMeasuredWidth();
height = getMeasuredHeight();
super.onDraw(canvas);
// 绘制纵向百分比
for (int i = 1; i < 7; i++) {
canvas.drawText(strings[i - 1], dp2px(2), height * i / 7 - sp2px(12), paintYText);
}
// 绘制横向线条
for (int i = 1; i < 7; i++) {
canvas.drawLine(0, height * i / 7, width, height * i / 7
, xLinePaint);
}
// 设置底部的月份
for (int i = 0; i < 6; i++) {
float textWidth = titlePaint.measureText(xMonths.get(i) + "");
canvas.drawText(xMonths.get(i), width * (i + 1) / 7 - textWidth / 2, height - height / 24
, titlePaint);
}
//绘制折线
for (int i = 0; i < 6; i++) {
if (i + 1 < 6) {
canvas.drawLine(width * (i + 1) / 7,
(int) (height * 6 / 7 - yPercents.get(i) * (height * 5 / 7)),
width * (i + 2) / 7,
(int) (height * 6 / 7 - yPercents.get(i + 1) * (height * 5 / 7)), paintLine);
}
}
//根据触摸事件重绘
if (touchMonth != 0) {
int i = touchMonth;
float textWidth = paintBac.measureText(xMonths.get(i - 1) + "");
//垂直线
canvas.drawLine(width * i / 7, height - height / 24, width * i / 7, (int) (height * 6 / 7 - yPercents.get(i - 1) * (height * 5 / 7)), paintLine);
//白底绿圆
canvas.drawCircle(width * i / 7, (int) (height * 6 / 7 - yPercents.get(i - 1) * (height * 5 / 7)), dp2px(5), paintBac);
canvas.drawCircle(width * i / 7, (int) (height * 6 / 7 - yPercents.get(i - 1) * (height * 5 / 7)), dp2px(4), paintLine);
//圆角矩形
RectF oval = new RectF(width * (touchMonth) / 7 - textWidth / 2 - dp2px(2), height - height / 24 - sp2px(12), width * (touchMonth) / 7 + textWidth / 2 + dp2px(2), height - height / 24 + dp2px(2));
canvas.drawRoundRect(oval, dp2px(4), dp2px(4), paintOval);
canvas.drawText(xMonths.get(i - 1), width * (touchMonth) / 7 - textWidth / 2, height - height / 24
, paintBac);
float percentWidth = paintYText.measureText(text.get(i-1) + "%");
float IllDataWidth = paintYText.measureText("--");
//百分比文字显示
if ("-1".equals(text.get(i-1))){
canvas.drawText("--", width * (touchMonth) / 7 - IllDataWidth / 2, (int) (height * 6 / 7 - yPercents.get(i - 1) * (height * 5 / 7) - sp2px(12)), paintYText);
}else{
canvas.drawText(text.get(i-1) + "%", width * (touchMonth) / 7 - percentWidth / 2, (int) (height * 6 / 7 - yPercents.get(i - 1) * (height * 5 / 7) - sp2px(12)), paintYText);
}
}
}
原理说完了,上一个项目地址。欢迎下载。