| title | date | tags | categories | cover | top_img |
|---|---|---|---|---|---|
Android杂食店-一次MpAndroidChart美化过程 |
2021年12月28日 07:41:44 -0800 |
android
view
自定义
MpAndroidChart
|
MpAndroidChart |
false |
半年更系列回来了
MpAndroidChart的真好用
完全使用默认的配置进行展示,
| 默认效果 | 折线优化 | 四周优化 | 覆盖物优化 | UI设计:源链接 |
可以看到相比于完全没有优化, 效果差的不是一点点
这里主要是ui优化, 除开整体元素设计来说, 页面风格适配就可以了. 不过我们可以将ui优化分为以下几个方向
这里需要一个下方的过渡效果即可
看起来没有需要优化的部分
我们的折线图本体, 也是我们优化的重点
就如在优化思路中所说, ui优化需要适配这个页面的风格, 这里的四周(尤其是底部), 都是服务与想要表达的主体(折线图的), 实现起来页相对荣幸, 不需要考虑重叠动态计算相关位置的问题, 使用一个合适渐变就可以了.
接下来是我们优化的重点部分, 也是我们页面信息显示的主题, 折线图.
从效果看来, Y轴对我们来说是一个多余的元素, 我们将其移除即可, 不过为了整体的效果, 还是需要进行一个相关的设置.
YAxis yAxis = binding.lcReportInfo.getAxisLeft(); //控制y轴最大最小范围, 避免因为使用了曲线而导致的折线截断 yAxis.setAxisMinimum(-100); yAxis.setAxisMaximum(1100); //关闭两侧y轴显示 binding.lcReportInfo.getAxisRight().setEnabled(false); yAxis.setEnabled(false);
X轴还是有许多工作需要进行的
XAxis xAxis = binding.lcReportInfo.getXAxis(); //将x轴置于底部 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM_INSIDE); //两侧设置留空效果, 具体数值可以根据实际调整 xAxis.setAxisMinimum(-0.3f); xAxis.setAxisMaximum(entries.size() - 0.7f); //x轴文件显示颜色 xAxis.setTextColor(Color.WHITE); //关闭网络线 xAxis.setDrawGridLines(false); //关闭延x轴线 xAxis.setDrawAxisLine(false); //可选, 是否控制x轴间隔数量 xAxis.setGranularityEnabled(true); xAxis.setGranularity(1); List<String> xAxisValues = new ArrayList<>(); //自定义x轴显示样式 for (Entry entry: entries){ xAxisValues.add(Math.round(entry.getX()) + "时"); } xAxis.setValueFormatter(new IndexAxisValueFormatter(xAxisValues));
除此之外我们还需要一个和整体风格匹配的折线效果
//设置一条折线信息 LineDataSet dataSet = new LineDataSet(entries, ""); //设置折线下部阴影是否填充 dataSet.setDrawFilled(true); //设置折现填充的颜色(透明度为0x85/0x255 在33左右) //详情原因可以查看{@link LineRadarDataSet#mFillAlpha 参数相关定义} dataSet.setFillColor(Color.parseColor("#c04851")); //设置折现的颜色 dataSet.setColor(Color.parseColor("#c04851")); //折线的宽度 dataSet.setLineWidth(2); //设置折线模式为圆滑的曲线 dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER); //是否绘制 dataSet.setDrawValues(false); //是否绘制折线的点(下面会手动添加) dataSet.setDrawCircles(false); //是否绘制高亮效果 dataSet.setDrawHighlightIndicators(false); //设置折线信息, 一个折线图中可以包含多个折线, 这么只添加了一条折线 LineData lineData = new LineData(); lineData.addDataSet(dataSet);
//设置折线图显示的数据 binding.lcReportInfo.setData(lineData); //不可手动缩放 binding.lcReportInfo.setDragDecelerationEnabled(true); Matrix matrix = new Matrix(); //图标缩放显示, 使得一次最多显示6个数据 matrix.postScale(entries.size() / 6f, 1f); binding.lcReportInfo.getViewPortHandler().refresh(matrix, binding.lcReportInfo, false); //设置四周边界位移 binding.lcReportInfo.setMinOffset(0); //设置空描述 binding.lcReportInfo.setDescription(null); //关闭缩放 binding.lcReportInfo.setScaleEnabled(false); //设置图例不显示 Legend legend = binding.lcReportInfo.getLegend(); legend.setEnabled(false); // //创建覆盖物并选择中心位置数据高亮 if (entries.size() != 0) { createMakerView(); //此操作需要晚于setData(), 否则会导致空指针异常 binding.lcReportInfo.highlightValue(getChartMiddle(), 0); updateBottomInfo(entries.get(getChartMiddle()).getY()); } //设置滑动监听 binding.lcReportInfo.setOnChartGestureListener(onChartGestureListener); //监听选中 binding.lcReportInfo.setOnChartValueSelectedListener(new OnChartValueSelectedListener() { @Override public void onValueSelected(Entry e, Highlight h) { //查看覆盖物是否被回收 if (binding.lcReportInfo.isMarkerAllNull()) { //重新绑定覆盖物 createMakerView(); //并且手动高亮覆盖物 binding.lcReportInfo.highlightValue(h); } updateBottomInfo(e.getY()); } @Override public void onNothingSelected() { } }); binding.lcReportInfo.invalidate(); // refresh
我们可以看到, 默认的覆盖物效果和我们整体的风格十分不搭, 所以我们还需要进行覆盖物的设置, 不过默认LineChart只能设置一个覆盖物, 所以我们需要重新实现LineChart
//在对应点上添加选择信息覆盖物 reportInfoMarkerView.refreshContent(e, highlight); reportInfoMarkerView.draw(canvas, pos[0], pos[1] - reportInfoMarkerView.getHeight() / 2); //在对挺点位置条件选择点覆盖物 reportPointMarkerView.refreshContent(e, highlight); reportPointMarkerView.draw(canvas, pos[0], pos[1] + reportPointMarkerView.getHeight() / 2); //判断是否可以绘制虚线 if (this.getHeight() - 50 > pos[1] + reportPointMarkerView.getHeight() / 2) { //通过canvas绘制虚线 Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(this.getContext().getColor(R.color.color_orange)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(3); mPaint.setPathEffect(new DashPathEffect(new float[]{15, 10}, 0)); Path mPath = new Path(); mPath.reset(); mPath.moveTo(pos[0], pos[1] + reportPointMarkerView.getHeight() / 2); mPath.lineTo(pos[0], this.getHeight() - 50); canvas.drawPath(mPath, mPaint); }
最后我们就可以看到一个显示效果不错的折线图了, 当然其中还有许多可以优化的部分.
相关代码, 我的GitHub: https://github.com/clwater/MPAndroid_LineChart