不需要依赖第三方框架,直接使用Canvas
drawLine,drawPath,drawCircle
复制代码
等几个简单的API即可搞定
效果图
?
源码:https://github.com/woshiwzy/trendviews
部分代码节选
onDraw?
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
w = getWidth();
h = getHeight();
this.coordinate_pading_v = (int) (h * this.coordinate_pading_v_percent);
canvas.drawColor(Color.WHITE);
mPaint.setStrokeWidth(paintSolideSmall);
mPaint.setTextSize(label_text_size);
int title_width = (int) mPaint.measureText(this.titlle);
mPaint.setStyle(Style.FILL);
mPaint.setColor(Color.BLACK);
canvas.drawText(this.titlle, w / 2 - title_width / 2, 50, mPaint);
// 画背景网格
if (0 == (countListSize(mArrayListHolderAllLastYear) + countListSize(mArrayListHolderAllThisYear) +
countListSize(mArrayListHolderLocalLastYears) + countListSize(mArrayListHolderLocalThisYears))) {
} else {
drawGrid(canvas);
}
}
drawGrid 绘制主要内容
public void drawGrid(Canvas canvas) {
mPaint.setColor(0x33dbdbdb);
// 画垂直网格
// coordinate_pading_h
int cell_width = (w - coordinate_pading_h * 2) / (months - 1);
this.mPointsAll.clear();
this.mPointsLocal.clear();
float pix_value_unit = (h - h * coordinate_pading_v_percent - coordinate_pading_b) / (this.highest - this.lowerest);
Path pathLocalThis = new Path();//本公司今年
pathLocalThis.reset();
Path pathLocalLast = new Path();//本公司去年
pathLocalLast.reset();
Path pathAllThis = new Path();//全市场今年
pathAllThis.reset();
Path pathAllLast = new Path();//全市场去年
pathAllLast.reset();
for (int i = 0, isize = months; i < isize; i++) {
int startX = coordinate_pading_h + i * cell_width;
int startY = 0;
int stopX = coordinate_pading_h + i * cell_width;
int stopY = h;
canvas.drawLine(startX, startY, stopX, stopY, mPaint);// 竖直网格
canvas.drawLine(startX + cell_width / 2, startY, startX + cell_width / 2, stopY, mPaint);// 竖直网格
if (i == 0) {
canvas.drawLine(startX - cell_width / 2, startY, startX - cell_width / 2, stopY, mPaint);// 竖直网格
}
if (null != mArrayListHolderLocalThisYears && !mArrayListHolderLocalThisYears.isEmpty()) {
//本公司今年
if (i < mArrayListHolderLocalThisYears.size()) {
Holder holderLocalThisYear = mArrayListHolderLocalThisYears.get(i);
if (null == this.mPointsLocal) {
this.mPointsLocal = new ArrayList<MyPoint>();
}
int x = startX;
float y = h - pix_value_unit * (holderLocalThisYear.getValue() - this.lowerest) - coordinate_pading_b;
MyPoint mypointlocalthisyear = new MyPoint(x, (int) y, holderLocalThisYear);
if (i == 0) {
pathLocalThis.moveTo(x, y);
} else {
pathLocalThis.lineTo(x, y);
}
this.mPointsLocal.add(mypointlocalthisyear);
} else {
this.mPointsLocal = null;
}
}
if (null != mArrayListHolderLocalLastYears && !mArrayListHolderLocalLastYears.isEmpty()) {
//本公司去年
if (i < mArrayListHolderLocalLastYears.size()) {
Holder holderLocalLastYear = mArrayListHolderLocalLastYears.get(i);
if (null == this.mPointsLast) {
this.mPointsLast = null;
}
int x = startX;
float y = h - pix_value_unit * (holderLocalLastYear.getValue() - this.lowerest) - coordinate_pading_b;
MyPoint mypointlocallastyear = new MyPoint(x, (int) y, holderLocalLastYear);
if (i == 0) {
pathLocalLast.moveTo(x, y);
} else {
pathLocalLast.lineTo(x, y);
}
this.mPointsLast.add(mypointlocallastyear);
} else {
this.mPointsLast = null;
}
}
if (null != mArrayListHolderAllThisYear && !mArrayListHolderAllThisYear.isEmpty()) {
//全市场今年
if (i < mArrayListHolderAllThisYear.size()) {
Holder holderAllHolderThisYear = mArrayListHolderAllThisYear.get(i);
if (null == this.mPointsAll) {
this.mPointsAll = new ArrayList<MyPoint>();
}
int x = startX;
float y = h - pix_value_unit * (holderAllHolderThisYear.getValue() - this.lowerest) - coordinate_pading_b;
MyPoint mypointallthisyear = new MyPoint(x, (int) y, holderAllHolderThisYear);
if (i == 0) {
pathAllThis.moveTo(x, y);
} else {
pathAllThis.lineTo(x, y);
}
this.mPointsAll.add(mypointallthisyear);
} else {
this.mPointsAll = null;
}
}
if (null != mArrayListHolderAllLastYear && !mArrayListHolderAllLastYear.isEmpty()) {
//全市场去年
if (i < mArrayListHolderAllLastYear.size()) {
Holder holderAllHolderLastYear = mArrayListHolderAllLastYear.get(i);
if (null == this.mPointsAllLast) {
this.mPointsAllLast = new ArrayList<MyPoint>();
}
int x = startX;
float y = h - pix_value_unit * (holderAllHolderLastYear.getValue() - this.lowerest) - coordinate_pading_b;
MyPoint mypointalllastyear = new MyPoint(x, (int) y, holderAllHolderLastYear);
if (i == 0) {
pathAllLast.moveTo(x, y);
} else {
pathAllLast.lineTo(x, y);
}
this.mPointsAllLast.add(mypointalllastyear);
} else {
this.mPointsAllLast = null;
}
}
}
//组装path结束
// 画水平网格
int cell_height = h / (months * 2);
for (int i = 0, isize = months * 2; i <= isize; i++) {
canvas.drawLine(0, cell_height * i, w, cell_height * i, mPaint);
}
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeWidth(radiusBig);
mPaint.setColor(0xff667788);//
canvas.drawPath(pathLocalThis, mPaint);
mPaint.setColor(0xff908765);//
canvas.drawPath(pathLocalLast, mPaint);
mPaint.setColor(0xff114477);//
canvas.drawPath(pathAllThis, mPaint);
mPaint.setColor(0xff765432);//
canvas.drawPath(pathAllLast, mPaint);
mPaint.setColor(0xffdbe4e6);
mPaint.setStyle(Style.FILL);
// canvas.drawLine(0, h-coordinate_pading_b, w, h-coordinate_pading_b, mPaint);
canvas.drawRect(0, h - coordinate_pading_b / 2, w, h, mPaint);// 标注x刻度
mPaint.setColor(Color.BLACK);
mPaint.setTextSize((label_text_size / 3) * 2);
ArrayList<MyPoint> locationPoints = getNotNullPointList();
if (locationPoints != null) {
for (int i = 0, isize = months; i < isize; i++) {
MyPoint p = locationPoints.get(i);
canvas.drawText(p.getHolder().getStamp(), p.x - 5, h - coordinate_pading_b / 2 + 25, mPaint);
}
}
mPaint.setStrokeWidth(paintSolideBig / 2);
mPaint.setColor(0xffb0b9c2);// 底部分割线
canvas.drawLine(0, h, w, h, mPaint);
mPaint.setStrokeWidth(paintSolideBig);
if (isSetting) {
ArrayList<MyPoint> templist = getNotNullPointList();
if (null != templist) {
// 找到第一个点
if (this.startIndex < templist.size()) {
MyPoint startPoint = templist.get(this.startIndex);
drawMoveLine(canvas, startPoint, cell_width);
//画第二根线
if (endIndex < startIndex) {
endIndex = startIndex + 1;
}
if (endIndex < templist.size() && templist.size() > 1) {
MyPoint endPoint = templist.get(endIndex);
drawMoveLine(canvas, endPoint, cell_width);
drawRectransparent(canvas, startPoint, endPoint);
}
}
}
} else {
ArrayList<MyPoint> notNullPoints = getNotNullPointList();
Object rets[] = findNearestPoint(notNullPoints);
if (rets.length > 1) {
MyPoint nearestPoint = (MyPoint) rets[0];//最近的触摸点
//第一个点距离触摸点的
if (1 == notNullPoints.size()) {
mPaint.setColor(0xff34DE71);
drawMoveLine(canvas, nearestPoint, cell_width);
} else {
if (startIndex < 0) {
startIndex = 0;
}
if (endIndex < startIndex) {
endIndex = startIndex + 1;
}
if (endIndex >= notNullPoints.size()) {
endIndex = notNullPoints.size() - 1;
}
if (startIndex >= 0 && startIndex < endIndex) {
//找到离触摸点最近的点
float dstart = cputeDistanceX(mTouchPoint, notNullPoints.get(this.startIndex));
float dend = cputeDistanceX(mTouchPoint, notNullPoints.get(this.endIndex));
int index = (Integer) rets[1];
if (dstart < dend) {
//将起始点移动到触摸点 ,备注:效果图要求不移动
this.startIndex = index;
}
if (dstart > dend) {
//将结束点移动到触摸点
this.endIndex = index;
}
MyPoint startPoint = notNullPoints.get(this.startIndex);
MyPoint endPoint = notNullPoints.get(this.endIndex);
drawMoveLine(canvas, startPoint, cell_width);//画第一根线
drawMoveLine(canvas, endPoint, cell_width);//画第二根线
drawRectransparent(canvas, startPoint, endPoint);//画半透明区域
}
}
if (null != moveListener) {
moveListener.onMove(this.endIndex);
}
}
}
}
|