基于RecyclerChart的KLine的繪制Scale詳解
本章節(jié)繼上次的底部Volume繪制的后續(xù),沒有再繼續(xù)畫底部的其它圖表,這只是一個舉一反三的過程,本章節(jié)實現(xiàn)的圖表的縮放,其實需求很明確,然后實現(xiàn)方式依照上章節(jié)末尾的方案,所以還算清晰,只是整個過程得慢慢的調(diào)試,慢慢地優(yōu)化,當然目前還有很多待改進的地方,但總體縮放的功能已經(jīng)實現(xiàn)了。
照舊先看gif效果圖,由于Android studio的錄屏沒法把我的手指觸控的小圓點錄上去,所以看不到我的手指,多指操作。

以下是實現(xiàn)前,以及實現(xiàn)過程中羅列的功能點。
1. BaseRecyclerViewChart 處理 OnTouch
2. 禁止掉多指拖動,影響測試。(這個暫時沒處理掉)
3. displayNumber 跟 detector.scaleFactor的關(guān)系計算,反比。
4. 設置 min、max limit level, 橫豎屏不一樣,不同的設置。
5. 修改displayNumber 后,RecyclerView 如何刷新。
6. 縮放時,刷新位置不準確,通過PointsX 找 Adapter, 找到虛擬手指中心點,對Adapter進行縮放。
7. maxDisplayNumber 為400, 180 ~ 400的區(qū)間 KLine Main 繪制 LineChart, 30 ~ 180 繪制目前的圖形。
8. 7的情況下,在LineChart下 drawFill()
1. 擴展縮放功能且兼容原有的觸摸體系
首先要保留原來的觸摸功能不變,同時添加現(xiàn)在的縮放,得修改BaseRecyclerviewChart的 OnTouch 方法, 最終保留BaseRecyclerviewChart不變,然后相關(guān)的功能放在了StockChartRecyclerView里,這樣就一點都不影響之前的圖表繪制了。

優(yōu)先處理 scaleGestureDetector 縮放,同時又保持了原來的觸摸體系,很好地擴展了目前的功能。
val result = scaleGestureDetector.onTouchEvent(event)
if (!scaleGestureDetector.isInProgress) {
//原來的邏輯
// Log.d(TAG, "scaleGestureDetector is not in Progress")
return super.onTouchEvent(event)
} else {
Log.d(TAG, "scaleGestureDetector is in Progress")
return result
}2. 具體的縮放邏輯處理
處理的就是上面羅列功能里的第3點,構(gòu)建了一個簡單的displayNumber跟detector.scaleFactor的模型,當scaleFactor增加的時候,displayNumber反而變少。
if (detector.scaleFactor >= 1) {//放大
displayNumber -= (displayNumber * (detector.scaleFactor - 1)).toInt()
} else {
displayNumber += (displayNumber * (1 - detector.scaleFactor)).toInt()
}理論上值返回是 0 ~ 無窮大,相應的displayNumber也變成 0 ~ 無窮大, 所以這里引入一個上下邊界。
var minDisplayNumber = 30 var maxDisplayNumber = 400 ? displayNumber = displayNumber.coerceAtLeast(minDisplayNumber).coerceAtMost(maxDisplayNumber)
3. 數(shù)據(jù)刷新
從以上的邏輯中拿到縮放后的displayNumber,如何給到Recyclerview進行刷新?首先在onScale()內(nèi)埋個鉤子,然后UI頁面在這個回調(diào)里進行數(shù)據(jù)刷新,這里對mAttrs中的displayNumber也做一個刷新,容錯處理,怕后續(xù)去讀這個里面的值。

resetDisplayNumber是一個高階函數(shù)的變量
var resetDisplayNumber: ((displayNumber:Int) -> Unit)? = null
接著就是UI頁面上的刷新處理,
recyclerView.resetDisplayNumber = { displayNumber ->
this@KLineDayFragment.displayNumber = displayNumber
mXAxis.resetDisplayNumber(this@KLineDayFragment.displayNumber)
mBarChartAdapter.updateXAxis(mXAxis)
}真正刷新的邏輯在mBarChartAdapter.updateXAxis(mXAxis),在BaseBarChartAdapter中添加updateXAxis
public void updateXAxis(XAxis xAxis){
this.mXAxis = xAxis;
notifyDataSetChanged();
}
上面的notifyDataSetChanged()之后就會對RecylcerView進行刷新:

這樣子就會因為 displayNumber的改變,然后修改XAxis,最終刷新RecyclerView。
4. 縮放過程KLine Main圖表變幻
這個實現(xiàn)的上面功能列表里的第7、8點,實現(xiàn)相對上面的縮放邏輯而言,功能比較簡單,本來打算借用StockEntry的close字段值去畫線的,這里先直接借用5日均線進行一個繪制,這個函數(shù)原來就有的,先實現(xiàn)功能。
直接看StockChartRenderer的繪制主邏輯代碼。

之前只有 if分支,這次添加了else里面的drawLine, 最后一個參數(shù)表示 是否drawFill, drawLine跟之前的LineChartRenderer里暫時去掉了邊界處理, drawFill里 bottom是 KLine Main 跟之前的Attache Chart的一個分割線

drawFill比較簡單,就是通過PointF1, PointF2, bottom 構(gòu)建一個path,然后drawPath 就可以了
private fun drawFill(canvas: Canvas,pointF: PointF, pointF1: PointF, bottom: Float) {
mLineFillPaint.color = ColorUtil.getResourcesColor(R.color.black_2)
val path = ChartComputeUtil.createColorRectPath(pointF, pointF1, bottom)
val drawable = LineChartDrawable(mLineFillPaint, path)
drawable.draw(canvas)
}
?
public static Path createColorRectPath(PointF pointF1, PointF pointF2, float bottom) {
Path path = new Path();
path.moveTo(pointF1.x, pointF1.y);
path.lineTo(pointF2.x, pointF2.y);
path.lineTo(pointF2.x, bottom);
path.lineTo(pointF1.x, bottom);
path.close();
return path;
}Okay, 縮放的邏輯大致就到此,然后還有一些bug, 例如縮放后,底部XAxis label的繪制在縮放過程中相應地變動。還有縮放模型的優(yōu)化,功能點里的6不知道是否跟目前一些晃動有關(guān),后續(xù)再慢慢優(yōu)化吧。
下次應該會添加底部的MACD圖,其實跟Volume的繪制是類同的工作,創(chuàng)建模擬MACD的Entity構(gòu)建,然后繪制就可以了,然后就是一個添加一個底部Attache Chart的一個 手勢監(jiān)測,目前的點擊是HighLight,然后需要替換成底部各個Attache Chart 圖表的一個替換,涉及到的一個之前沒處理過的一個View的上面部分跟底下點擊然后在自定義的情況下,用不同的Callback調(diào)用處理,應該還好處理,相比今天的縮放而言。
到此這篇關(guān)于基于RecyclerChart的KLine的繪制Scale詳解的文章就介紹到這了,更多相關(guān)RecyclerChart KLine繪制Scale內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 中jasperReport實現(xiàn)動態(tài)列打印的實現(xiàn)代碼
這篇文章主要介紹了Java 中jasperReport實現(xiàn)動態(tài)列打印的實現(xiàn)代碼的相關(guān)資料,希望通過本文大家能掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09
解決Springboot全局異常處理與AOP日志處理中@AfterThrowing失效問題
這篇文章主要介紹了解決Springboot全局異常處理與AOP日志處理中@AfterThrowing失效問題,文中介紹了兩種失效場景,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-05-05
Spring?Boot?中的?@HystrixCommand?注解原理及使用方法
通過使用 @HystrixCommand 注解,我們可以輕松地實現(xiàn)對方法的隔離和監(jiān)控,從而提高系統(tǒng)的可靠性和穩(wěn)定性,本文介紹了Spring Boot 中的@HystrixCommand注解是什么,其原理以及如何使用,感興趣的朋友跟隨小編一起看看吧2023-07-07
java通過Excel批量上傳數(shù)據(jù)的實現(xiàn)示例
Excel批量上傳是常見的一種功能,本文就來介紹一下java通過Excel批量上傳數(shù)據(jù)的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-10-10
HashMap紅黑樹入門(實現(xiàn)一個簡單的紅黑樹)
紅黑樹(Red Black Tree) 是一種自平衡二叉查找樹,是在計算機科學中用到的一種數(shù)據(jù)結(jié)構(gòu),典型的用途是實現(xiàn)關(guān)聯(lián)數(shù)組。 紅黑樹發(fā)明時被稱為平衡二叉B樹,后來修改為如今的“紅黑樹”2021-06-06
java實現(xiàn)微信公眾平臺自定義菜單的創(chuàng)建示例
這篇文章主要介紹了java實現(xiàn)微信公眾平臺自定義菜單的創(chuàng)建示例,需要的朋友可以參考下2014-04-04

