Android自定義折線圖
最近學習了一波自定義View,順便做了一個demo,是按照另一篇文章來實現的。我這裡主要分析一下思路,最後會附上全部程式碼。
ofollow,noindex">https://www.jianshu.com/p/baa08e3200bc效果圖

原圖去他的文章看,可以左右滑動。
思路解析
1、畫X軸
2、畫Y軸
3、畫虛線
4、畫折線和節點圓圈
5、滑動手勢
先給不太熟悉自定義View的朋友打打氣,以前我也以為這很難,但是一步步拆解開之後,真的不難。裡面無非就是繪製基本的圖形,畫線,滑動手勢監聽,繪製圖形的時候把位置確定後就行。
1、畫X軸
X軸由2部分組成,有刻度的地方+延伸出的箭頭。所以只需要確定折線圖的座標原點和x軸的終點即可。x軸上的刻度線和下方對應的文字也不難,只要確定x座標的間隔和總數,迴圈的 drawLine
、 drawText
即可。
2、畫Y軸
和畫X軸同理,只是方向變了而已。
3、畫虛線
虛線是用 DashPathEffect
、 drawPath
來實現,然後只需要通過y軸的間隔來確定虛線的起點和終點即可
4、畫折線和節點圓圈
畫折線最重要的是確定2個點的位置,折線上的點的x座標是很好確定的,因為第一個點的x座標是定死的,後面的只需要知道是第幾個點和x座標間隔就可以算出;而y座標要麻煩一點,具體思路如下:
//y軸最小單位的距離 float aver = (lableCountY - 1) * intervalY / (maxValueY - minValueY); Path path = new Path(); //先移動到第一個點的位置 path.moveTo(firstPointX, mHeight - paddingBottom - leftRightExtra - yValues.get(0) * aver + minValueY * aver); //繪製折線 for (int i = 0; i < yValues.size(); i++) { path.lineTo(firstPointX + i * intervalX, mHeight - paddingBottom - leftRightExtra - yValues.get(i) * aver + minValueY * aver); } canvas.drawPath(path, paintBlue);
畫連線2條線段的圓圈
// 折線中的圓點 for (int i = 0; i < yValues.size(); i++) { canvas.drawCircle(firstPointX + i * intervalX, mHeight - paddingBottom - leftRightExtra - yValues.get(i) * aver + minValueY * aver, bigCircleR, paintBlue); //小圓的顏色和view背景顏色相同,這樣看上去折線是沒有穿透圓的 canvas.drawCircle(firstPointX + i * intervalX, mHeight - paddingBottom - leftRightExtra - yValues.get(i) * aver + minValueY * aver, smallCircleR, paintBack); }
注意:這裡我用了2個圓圈,第二個小圓的目的是為了遮蓋圓圈中被折線穿過的那部分,你可以把第二個圓圈註釋掉看看效果就清楚了。
5、滑動手勢
不多講了,就是通過滑動監聽,改變折線上第一個點的位置就好。滑動的過程。

但是滑動過程,會有一部分超出座標原點了,那怎麼辦呢?其實沒那麼複雜,我用了一個最簡單的方式,畫一個矩形,範圍如圖所示,顏色和View的背景顏色相同,就可以遮擋住超出的這部分了,
Paint paintBack = new Paint(Paint.ANTI_ALIAS_FLAG); paintBack.setColor(Color.parseColor("#272727")); paintBack.setStyle(Paint.Style.FILL); //將折線超出x軸座標的部分擷取掉(左邊) paintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); RectF rectF = new RectF(0, 0, originX, mHeight); canvas.drawRect(rectF, paintBack);