博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 身高体重曲线的实现
阅读量:7234 次
发布时间:2019-06-29

本文共 6823 字,大约阅读时间需要 22 分钟。

场景

产品需求,需要增加一个身高体重曲线的模块,设计图如下

体重曲线也是这样。

准备

先来一张实现的粗略效果图

曲线图,折线图等,大多使用流行强大的MPandroidChart库,这里也是。 在网上找了一些类似的效果,都不是很符合设计图,

实现

直接附上代码,注释都很清楚。主要调用库的方法

mLineChart = binding.lineChart        mLineChart.setDrawBorders(true)        var xAxis = mLineChart.xAxis        /*设置X轴的位置(默认在上方)*/        xAxis.position = XAxis.XAxisPosition.BOTTOM        /*设置X轴坐标之间的最小间隔*/        xAxis.granularity = 1f        xAxis.mAxisMaximum = 72f        /*设置X轴值为字符串*/        xAxis.setValueFormatter(object : IAxisValueFormatter {            override fun getFormattedValue(value: Float, axis: AxisBase?): String {                return PinyinUtils.getFormatXLabel(value.toInt())            }        })        /* 右侧Y轴不显示*/        var axisRight = mLineChart.axisRight        axisRight.isEnabled = false        /*隐藏图例*/        mLineChart.legend.isEnabled = false        /*隐藏描述*/        var description = Description()        description.isEnabled = false        mLineChart.description = description        /*X,Y轴同时缩放,false则X,Y轴单独缩放,默认false*///        mLineChart.setPinchZoom(true);        mLineChart.setScaleEnabled(false)        // 重置所有缩放与拖动,使图标完全符合其边界//        mLineChart.fitScreen();        /* y轴是否自动缩放;当缩放时,y轴的显示会自动根据x轴范围内数据的最大最小值而调整。财务报表比较有用,默认false*/        mLineChart.setAutoScaleMinMaxEnabled(true);        mLineChart.setExtraLeftOffset(10f);   // 这个与上面的区别是不会忽略其自己计算的偏移。//        mLineChart.setDoubleTapToZoomEnabled(false);//双击屏幕缩放//        mLineChart.setScaleEnabled(false);//        mLineChart.setScaleXEnabled(true);//        mLineChart.setScaleYEnabled(false);/*        var axisLeft = mLineChart.getAxisLeft()//        axisLeft.axisMinimum = 45f        //如果设置为true那么下面方法设置最小间隔生效,默认为false        axisLeft.setGranularityEnabled(true);        //设置Y轴的值之间的最小间隔。这可以用来避免价值复制当放大到一个地步,小数设置轴不再数允许区分两轴线之间的值。        axisLeft.setGranularity(10f);        binding.viewModel?.requestGrowthData("1")*/        initHeightWidth(true)//初始化    fun initHeightWidth(isHeight: Boolean) {        binding.tvTopTip.text = if (isHeight) "身高(cm)" else "体重(kg)"        mLineChart.setExtraLeftOffset(if (isHeight) 10f else 5f);   // 这个与上面的区别是不会忽略其自己计算的偏移。        var axisLeft = mLineChart.getAxisLeft()        //如果设置为true那么下面方法设置最小间隔生效,默认为false        axisLeft.setGranularityEnabled(true)        axisLeft.setGranularity(if (isHeight) 10f else 1f)        axisLeft.axisMinimum = if (isHeight) 45f else 1f        var xAxis = mLineChart.xAxis        /*设置X轴的位置(默认在上方)*/        xAxis.position = XAxis.XAxisPosition.BOTTOM        /*设置X轴坐标之间的最小间隔*/        xAxis.granularity = 1f        xAxis.mAxisMaximum = 72f        /*设置X轴值为字符串*/        xAxis.setValueFormatter(object : IAxisValueFormatter {            override fun getFormattedValue(value: Float, axis: AxisBase?): String {                return PinyinUtils.getFormatXLabel(value.toInt())            }        })        binding.viewModel?.requestGrowthData(if (isHeight) "1" else "0")    }//设置数据 fun setData(data: GrowthBean?) {        xList.clear()        //一个LineDataSet就是一条线        var entriesMax = mutableListOf
() var entriesMin = mutableListOf
() var entriesUser = mutableListOf
() data?.max?.forEach { entriesMax.add(Entry(it.x, it.y)) } data?.min?.forEach { xList.add("${it.x}") entriesMin.add(Entry(it.x, it.y)) } data?.user?.forEach { entriesUser.add(Entry(it.x, it.y)) } var set97 = LineDataSet(entriesMax, "97%") set97.setColor(Color.parseColor("#FF7449")); set97.setLineWidth(2f); set97.setFillAlpha(65); set97.setHighLightColor(Color.rgb(244, 117, 117)); set97.setDrawCircleHole(false); set97.setDrawCircles(false) set97.setDrawValues(false) set97.setDrawFilled(true) set97.setFillColor(Color.parseColor("#FFC9C3")); set97.label = "97%" set97.setDrawHighlightIndicators(false) var set3 = LineDataSet(entriesMin, "3%") set3.setColor(Color.parseColor("#FF7449")) set3.setLineWidth(2f) set3.setDrawCircleHole(false) set3.setDrawCircles(false) set3.setDrawValues(false) set3.label = "3%" set3.setDrawHighlightIndicators(false) Collections.sort(entriesUser, EntryXComparator()) var setUser = LineDataSet(entriesUser, "宝宝") setUser.setColor(Color.parseColor("#FD5A7B")) setUser.setLineWidth(2f) setUser.setDrawCircleHole(false) setUser.setDrawCircles(true) setUser.setDrawValues(true) setUser.setCircleRadius(5f) setUser.setCircleColor(Color.parseColor("#FD5A7B")) setUser.setDrawHighlightIndicators(false) var lineData: LineData if (entriesUser.size > 0) { lineData = LineData(set97, set3, setUser) } else { lineData = LineData(set97, set3) } //设置数据 mLineChart.setData(lineData) //设置一页最大显示个数为6,超出部分就滑动 val ratio = xList.size.toFloat() / 6.toFloat() //显示的时候是按照多大的比率缩放显示,1f表示不放大缩小 mLineChart.zoom(ratio, 1f, 0f, 1f) mLineChart.isScaleYEnabled = false mLineChart.setNoDataText("暂无数据") //可以设置一条警戒线,如下: val ll = LimitLine(data!!.monthAge.toFloat(), "今日") ll.lineColor = Color.parseColor("#FF7449") ll.lineWidth = 1f ll.enableDashedLine(10f, 10f, 0f); ll.textColor = Color.parseColor("#FF5A7D") ll.textSize = 12f ll.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM) mLineChart.xAxis.addLimitLine(ll) //移到某个位置 mLineChart.moveViewTo(data!!.monthAge.toFloat() - 3, if (isHeight) 160f else 80f, YAxis.AxisDependency.RIGHT) /*渲染区间背景*/ set97.setFillFormatter(MyFillFormatter(set3)) mLineChart.renderer = MyLineLegendRenderer(mLineChart, mLineChart.animator, mLineChart.viewPortHandler) }复制代码

还有一个效果没有实现,就是滑动悬浮的线上的数。

重点

渲染区间背景 是自定义的FillFormatter

public class MyFillFormatter implements IFillFormatter {    private ILineDataSet boundaryDataSet;    public MyFillFormatter() {        this(null);    }    //Pass the dataset of other line in the Constructor    public MyFillFormatter(ILineDataSet boundaryDataSet) {        this.boundaryDataSet = boundaryDataSet;    }    @Override    public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {        return 0;    }    //Define a new method which is used in the LineChartRenderer    public List
getFillLineBoundary() { if(boundaryDataSet != null) { return ((LineDataSet) boundaryDataSet).getValues(); } return null; }}复制代码

调用:

/*渲染区间背景*/        set97.setFillFormatter(MyFillFormatter(set3))        mLineChart.renderer = MyLineLegendRenderer(mLineChart, mLineChart.animator, mLineChart.viewPortHandler)复制代码

这里是在Stack Overflow里看到的

#最后 附上参考的文章

转载地址:http://urpfm.baihongyu.com/

你可能感兴趣的文章
下表描述了Foundation 2010 、 SharePoint Server 2010 和 FAST Search Server 2010三者的搜索能力...
查看>>
《H3C路由器配置与管理完全手册》(第二版)前言和目录
查看>>
《.NET最佳实践》与Ext JS/Touch的团队开发
查看>>
虚拟磁盘工具vmkfstools的使用
查看>>
Linux Bash Shell高级重定向操作--深入了解标准错误输出和标准输出
查看>>
HP LaserJet Pro P1106网络打印机64位驱动安装
查看>>
JDK和JAXB的对应
查看>>
Numpy快速入门
查看>>
Nginx查看 并发连接数
查看>>
Hyper-V虚拟机快照占用磁盘空间过多,导致虚拟机不能启动怎么办
查看>>
技术随想---互帮互助
查看>>
Trie图的学习过程
查看>>
【博客话题】我的linux戏曲
查看>>
linux生产服务器有关网络状态的优化措施
查看>>
继之前SCVMM WinRM问题后重新添加群集后Windows Azure Pack创建虚拟机失败
查看>>
【沟通的艺术】 心随形动
查看>>
第十六集被忽视的帧中继:原理及实验
查看>>
那些年,我玩过的操作系统
查看>>
Skype for Business Server 2015-09-测试-基本功能(建议:看PDF!)
查看>>
6425C-Lab5 管理计算机帐户
查看>>