Android 解決hellocharts與ViewPager滑動衝突以及有且僅有一組數據時不顯示的問題
前言
hellocharts也很長一段時間沒有更新維護了,地址在這裏:https://github.com/lecho/hellocharts-android
我最近的使用中就遇到了兩個問題:
- hellocharts與ViewPager滑動衝突
- 有且僅有一組數據時不顯示
hellocharts與ViewPager滑動衝突
在使用LineChartView的時候,恰好當前Activity是用ViewPager+Fragment組成的,恰好我需要左右滑動翻頁。這時候LineChartView的左右滑動查看數據的觸摸事件就被ViewPager給搶了。
解決方法
新建一個類繼承LineChartView,攔截觸摸事件。
/**
* @author D10NG
* @date on 2020/6/17 5:01 PM
*/
class FixLineChartView constructor(
context: Context,
attrs: AttributeSet?,
defStyle: Int
) : LineChartView(context, attrs, defStyle) {
constructor(context: Context) : this(context, null, 0)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
private var downPoint: PointF = PointF()
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
// 重點在這一句,是不是很誇張哈哈哈哈,其實是要根目錄的父組件,可以根據自己的佈局來修改
parent.parent.parent.parent.parent.parent.requestDisallowInterceptTouchEvent(true)
return super.dispatchTouchEvent(event)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
event?: return super.onTouchEvent(event)
when(event.action) {
MotionEvent.ACTION_DOWN -> {
downPoint.x = event.x
downPoint.y = event.y
}
MotionEvent.ACTION_MOVE -> {
if (scaleX > 1 && abs(event.x - downPoint.x) > 5) {
// 同樣的這裏也需要
parent.parent.parent.parent.parent.parent.requestDisallowInterceptTouchEvent(true);
}
}
}
return super.onTouchEvent(event)
}
}
有且僅有一組數據時不顯示
當只有一組數據的時候不顯示數據
解決方法
需要設置好兩個東西,一個是maximumViewport(最大顯示範圍),一個是currentViewport(當前顯示範圍)
// 首先拿到最大顯示範圍
val viewPort = Viewport(binding.chart.maximumViewport)
// maxY是我的Y軸最大值,需要做的是保證viewPort.bottom不能等於viewPort.top,也就是顯示範圍的高度不能等於0啊
viewPort.bottom = maxY -4
viewPort.top = maxY
// 接下來設置顯示寬度,左邊是 -0.5f就保證了最左側的數據能顯示出來,右邊的是數據量和5之間取最大值再減去0.5f,同樣是保證最右側的數據能顯示出來,當然viewPort.left不能等於viewPort.right
viewPort.left = -0.5f
viewPort.right = (labelsX.size.toFloat().coerceAtLeast(5f)) -0.5f
// 設置最大顯示範圍
binding.chart.maximumViewport = viewPort
// currentViewport一定要在設置maximumViewport之後,不然顯示的座標數據是不能左右滑動查看更多數據的
// 這是當前的現實範圍
viewPort.left = 0f
viewPort.right = 3f
binding.chart.currentViewport = viewPort
// 滾動到最開頭的位置
binding.chart.moveTo(-0.5f ,viewPort.bottom)