目录
1、需求
实现分数,心跳的折线图,本文主要介绍三方库里折线图的基础实现,详细的API作用和一些扩展
2、折线图具体实现
2.1 xml布局
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginHorizontal="20dp"
android:layout_marginTop="40dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
库版本不同可能会导致前缀不同,输入LineChart肯定会有提示的。
2.2 代码实现
private fun initLineChart1() {
binding.chart.isDragEnabled = true
val xAxis: XAxis = binding.chart.xAxis //获取x轴
xAxis.apply {
position = XAxisPosition.BOTTOM
setDrawGridLines(false)
granularity = 1f
setLabelCount(5, false)
axisMinimum = (0.5f)
mAxisMaximum = (5.5f)
}
//x轴的标签
xAxis.valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float, axis: AxisBase?): String {
val i = value.toInt()
return "数据$i"
}
}
val poitList = ArrayList<Entry>()
for (i in 1..5) {
val mult = 90
val value = (Math.random() * mult).toFloat() + 10
poitList.add(Entry(i.toFloat(), value))
}
val dataSet = LineDataSet(poitList, "data 1")
if (dataSet.colors.isEmpty()){
dataSet.color = getColor(R.color.color_ff8561)
}
dataSet.axisDependency = YAxis.AxisDependency.LEFT
dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER //设置为贝塞尔曲线
dataSet.highLightColor = Color.RED // 设置点击某个点时,横竖两条线的颜色
dataSet.setDrawValues(true) //在点上显示数值 默认true
dataSet.valueTextSize = 12f //数值字体大小,同样可以设置字体颜色、自定义字体等
binding.chart.data = LineData(dataSet)
val leftAxis: YAxis = binding.chart.axisLeft //获取左轴
leftAxis.apply {
mAxisMinimum = 0f
mAxisMaximum = 100f
granularity = 10f
}
binding.chart.axisRight.isEnabled = false //隐藏右轴 默认显示
binding.chart.animateX(500)//画折线图的时间
}
2.3 实现效果

2.4 常用API解析
2.4.1 表格基础设置
// 设置是否绘制背景
mChart.setDrawGridBackground(false);
// 设置是否绘制边框
mChart.setDrawBorders(false);
// 设置是否可以缩放图表
mChart.setScaleEnabled(true);
// 设置是否可以用手指移动图表
mChart.setDragEnabled(true);
// 不显示描述数据
mChart.getDescription().setEnabled(true);
mChart.getAxisRight().setEnabled(false);
// 设置描述
mChart.getDescription().setText("text desc");
// 设置描述显示的位置,默认是显示在图表的右下角的
mChart.getDescription().setPosition(200,100);
2.4.2 表格的轴线
val xAxis: XAxis = binding.chart.xAxis //获取x轴
xAxis.apply {
position = XAxisPosition.BOTTOM//展示在底部,默认顶部
setDrawGridLines(false)//不绘制网格线
granularity = 1f//表格刻度step,例如你的Entry里的x都是5的倍数,就可以设置为5
setLabelCount(5, false)//设置x轴上的标签个数
axisMinimum = (0.5f)//最小应该为0f,但是如果值展示在y轴上不好看,我进行了0.5的偏折
mAxisMaximum = (5.5f)//最大值的偏折,如果你的数据是后端给的,那就后端列表的size
}
val leftAxis: YAxis = binding.chart.axisLeft //获取左轴Y轴
leftAxis.apply {
mAxisMinimum = 0f
mAxisMaximum = 100f
granularity = 10f//step
}
binding.chart.axisRight.isEnabled = false //隐藏右轴 默认显示
2.4.3 LineDataSet
在 MPAndroidChart 库中,DataSet 主要用于存储和管理数据点,它是所有数据集(如 LineDataSet、BarDataSet、PieDataSet 等)的基类。
构造函数:我加了注释
public LineDataSet(List<Entry> yVals, String label) {
super(yVals, label); // 调用父类构造方法,初始化数据集
this.mMode = LineDataSet.Mode.LINEAR; // 线条模式,默认为线性 (LINEAR),可选 CUBIC_BEZIER(平滑曲线) 等模式
this.mCircleColors = null; // 圆点的颜色列表(曲线上点的颜色)
this.mCircleHoleColor = -1; // 圆点中心的颜色,-1 代表透明
this.mCircleRadius = 8.0F; // 圆点的半径(单位:dp)
this.mCircleHoleRadius = 4.0F; // 圆点中心空洞的半径(单位:dp)
this.mCubicIntensity = 0.2F; // 平滑曲线的强度,数值越大曲线越平滑(仅适用于 CUBIC_BEZIER 模式)
this.mDashPathEffect = null; // 虚线样式,null 代表实线
this.mFillFormatter = new DefaultFillFormatter(); // 用于填充区域的格式化器
this.mDrawCircles = true; // 是否绘制折线上的圆点
this.mDrawCircleHole = true; // 是否绘制圆点中心的空洞(如果 `false`,圆点将是实心的)
// 初始化 rangeColors 和 rangeValues,可能用于特定数据范围的颜色显示
this.rangeColors = new int[1];
this.rangeValues = new float[1];
// 确保 mCircleColors 不为 null,并初始化默认颜色
if (this.mCircleColors == null) {
this.mCircleColors = new ArrayList<>();
}
this.mCircleColors.clear(); // 清空已有的颜色
this.mCircleColors.add(Color.rgb(140, 234, 255)); // 默认圆点颜色(淡蓝色)
}
补充说明
mCircleColors:用于存储折线图上数据点的颜色,可以支持多个颜色(多个点会循环使用颜色)。mCircleHoleColor:如果mDrawCircleHole = true,那么这个颜色决定了圆点的中心颜色,-1代表透明。mCircleRadius&mCircleHoleRadius:分别控制外圈半径和中心空洞的半径,确保mCircleHoleRadius小于mCircleRadius,否则空洞会覆盖整个点。mCubicIntensity:用于调整CUBIC_BEZIER模式下的曲线平滑程度,取值范围通常在0.05 - 1.0之间。mDashPathEffect:如果要绘制虚线,可赋值new DashPathEffect(new float[]{10f, 5f}, 0f)(表示 10dp 实线 + 5dp 空白的间隔模式)。mFillFormatter:用于填充折线图下方区域的 formatter,可以自定义透明度等效果。
2.4.4 空数据处理
fun setNoData() {
binding.chart.clear()
binding.chart.setNoDataText("你还没有记录数据!")
binding.chart.setNoDataTextColor(getColor(R.color.black))
binding.chart.invalidate()
}
3.折线图实现点图
3.1 实现效果

3.2 实现代码
private fun initLineChart2() {
// 定义周一到周日的标签
val weekLabels = arrayOf("周一", "周二", "周三", "周四", "周五", "周六", "周日")
// 自定义 X 轴标签格式化
class WeekdayFormatter(private val labels: Array<String>) : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
val index = value.toInt()
return if (index in labels.indices) labels[index] else ""
}
}
class MoodFormatter : ValueFormatter() {
override fun getFormattedValue(p0: Float): String {
return when {
p0 < 5 -> ""
p0 < 15 -> "happy"
p0 in 15.0..30.0 -> "calm"
else -> "angry"
}
}
}
// 创建数据点(X 轴对应 0~6,代表周一到周日)
val entries = listOf(
Entry(0f, 10f), // 周一
Entry(1f, 20f), // 周二
Entry(2f, 15f), // 周三
Entry(3f, 25f), // 周四
Entry(4f, 60f), // 周五
Entry(5f, 18f), // 周六
Entry(6f, 82f) // 周日
)
val dataSet = LineDataSet(entries, "Data Points").apply {
setDrawCircles(true) // 仅画点
setDrawValues(false) // 显示数值
color = Color.TRANSPARENT // 隐藏线条
lineWidth = 0f
circleRadius = 7f
circleHoleRadius = 0f
circleColors = listOf(Color.BLUE, Color.GREEN, Color.RED, Color.YELLOW, Color.MAGENTA, Color.CYAN, Color.BLACK)
}
// 设置 LineData
val lineData = LineData(dataSet)
binding.lineChartTest2.data = lineData
// 设置 X 轴
binding.lineChartTest2.xAxis.apply {
valueFormatter = WeekdayFormatter(weekLabels) // 使用自定义格式化
granularity = 1f // 设置刻度间隔,确保每个整数值都有对应的标签
position = XAxisPosition.BOTTOM // 让 X 轴显示在底部
setDrawGridLines(false) // 隐藏 X 轴网格线
setDrawAxisLine(true) // 显示 X 轴本身
axisMinimum = -0.5f
axisMaximum = 6.5f
}
binding.lineChartTest2.axisLeft.apply {
valueFormatter = MoodFormatter() // 使用自定义 Y 轴格式化
granularity = 5f
setDrawGridLines(false) // 隐藏 Y 轴网格线
}
// 隐藏 Y 轴网格线
binding.lineChartTest2.axisLeft.setDrawGridLines(false)
binding.lineChartTest2.axisRight.isEnabled = false
}
4. 折线图-渐变色填充
4.1实现效果

4.2实现代码
private fun initlineChartTest3() {
// 定义 X 轴标签(星期)
val labels = arrayOf("SUN", "MON", "Tue", "Wed", "Thu", "Fri", "Sat")
// 设置 X 轴的标签格式化器,使其显示自定义的星期名称
binding.lineChartTest3.xAxis.valueFormatter = object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
val index = value.toInt()
return if (index in labels.indices) labels[index] else ""
}
}
// 设置 X 轴线条为透明
binding.lineChartTest3.xAxis.axisLineColor = Color.TRANSPARENT
// 设置左侧 Y 轴线条为透明
binding.lineChartTest3.axisLeft.axisLineColor = Color.TRANSPARENT
// 设置 X 轴标签的字体大小和颜色
binding.lineChartTest3.xAxis.textSize = 11f
binding.lineChartTest3.xAxis.textColor = getColor(R.color.color_cacaca)
// 设置 Y 轴(左侧)标签的字体大小和颜色
binding.lineChartTest3.axisLeft.textSize = 11f
binding.lineChartTest3.axisLeft.textColor = getColor(R.color.color_cacaca)
// 配置 X 轴属性
binding.lineChartTest3.xAxis.apply {
position = XAxis.XAxisPosition.BOTTOM // X 轴标签显示在底部
setDrawGridLines(false) // 关闭 X 轴网格线
setDrawAxisLine(true) // 允许绘制 X 轴线
setLabelCount(7, false) // 设置 X 轴的标签数量为 7(即一周 7 天)
// 设置 X 轴从 -0.5 开始,以便首尾的标签居中对齐
axisMinimum = -0.5f
granularity = 1f // 设置 X 轴的步长为 1
axisMaximum = labels.size.toFloat() - 0.5f // X 轴最大值
}
// 配置 Y 轴(左侧)
binding.lineChartTest3.axisLeft.apply {
setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART) // Y 轴标签显示在图表外
axisMinimum = 0f // Y 轴的最小值
granularity = 25f // Y 轴间隔
labelCount = 5 // 设置 Y 轴的标签数量
gridColor = getColor(R.color.ededed) // 设置 Y 轴网格线的颜色
enableGridDashedLine(12f, 12f, 0f) // 设置虚线网格线
gridLineWidth = 1f // 设置网格线宽度
}
// 关闭右侧 Y 轴
binding.lineChartTest3.axisRight.isEnabled = false
// 禁用图表的交互功能(禁用缩放、拖拽等)
binding.lineChartTest3.isEnabled = false
// 设置图表的描述信息(这里设置为 "哈哈哈")
binding.lineChartTest3.description = Description().apply {
text = "哈哈哈"
}
// 创建数据点列表
val poitList = ArrayList<Entry>()
for (i in 0..6) {
val mult = 90 / 2f // 最大值的一半
val value = (Math.random() * mult).toFloat() + 10 // 生成随机值(10 ~ 55)
poitList.add(Entry(i.toFloat(), value)) // 添加数据点
}
// 创建折线数据集
val dataSet = LineDataSet(poitList, "data 2").apply {
axisDependency = YAxis.AxisDependency.LEFT // 依赖左侧 Y 轴
setDrawCircles(false) // 不绘制数据点的圆圈
color = getColor(R.color.color_ff8561) // 线条颜色
setDrawValues(false) // 不显示数据点的数值
mode = LineDataSet.Mode.CUBIC_BEZIER // 设置折线为贝塞尔曲线
lineWidth = 5f // 线条宽度
setDrawFilled(true) // 启用折线下方的填充颜色
fillDrawable = getDrawable(R.drawable.line_bg_red) // 设置填充颜色
}
// 禁用点击高亮和拖拽高亮
binding.lineChartTest3.isHighlightPerTapEnabled = false
binding.lineChartTest3.isHighlightPerDragEnabled = false
// 设置折线图的数据并刷新
binding.lineChartTest3.data = LineData(dataSet)
}
代码补充:上面的代码注释很完整,主要是新增了填充渐变色,Y轴设置的虚线,不展示点,x,y轴不展示等等
后续在进行补充

6万+

被折叠的 条评论
为什么被折叠?



