Android图表控件MPAndroidChart库非常强大,支各种图表。虽然已经很强大,但是有些时候还是不能满足我们的需求,类似MarkerView的显示问题,如果不加以修改显示内容会在屏幕之外,达不到预期的效果。如下图:
完成看不到值。
解决方案:判断当前位置和显示控件的宽度超过图表的宽度则重新计算绘制坐标
重新写一个NewMarkerView,源码和官方基本上一致,稍微加上我们自己的判断即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | import android.content.Context; import android.graphics.Canvas; import android.view.LayoutInflater; import android.view.View; import android.widget.RelativeLayout; import com.github.mikephil.charting.charts.Chart; import com.github.mikephil.charting.components.IMarker; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.utils.MPPointF; import java.lang.ref.WeakReference; public class NewMarkerView extends RelativeLayout implements IMarker { private MPPointF mOffset = new MPPointF(); private MPPointF mOffset2 = new MPPointF(); private WeakReference<Chart> mWeakChart; /** * Constructor. Sets up the MarkerView with a custom layout resource. * * @param context * @param layoutResource the layout resource to use for the MarkerView */ public NewMarkerView(Context context, int layoutResource) { super (context); setupLayoutResource(layoutResource); } /** * Sets the layout resource for a custom MarkerView. * * @param layoutResource */ private void setupLayoutResource( int layoutResource) { View inflated = LayoutInflater.from(getContext()).inflate(layoutResource, this ); inflated.setLayoutParams( new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT)); inflated.measure(MeasureSpec.makeMeasureSpec( 0 , MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec( 0 , MeasureSpec.UNSPECIFIED)); // measure(getWidth(), getHeight()); inflated.layout( 0 , 0 , inflated.getMeasuredWidth(), inflated.getMeasuredHeight()); } public void setOffset(MPPointF offset) { mOffset = offset; if (mOffset == null ) { mOffset = new MPPointF(); } } public void setOffset( float offsetX, float offsetY) { mOffset.x = offsetX; mOffset.y = offsetY; } @Override public MPPointF getOffset() { return mOffset; } public MPPointF getOffsetRight() { return mOffset; } public void setChartView(Chart chart) { mWeakChart = new WeakReference<>(chart); chart.setMarker( this ); } public Chart getChartView() { return mWeakChart == null ? null : mWeakChart.get(); } @Override public MPPointF getOffsetForDrawingAtPoint( float posX, float posY) { Chart chart = getChartView(); MPPointF offset = getOffset(); float width = getWidth(); float height = getHeight(); mOffset2.x = offset.x; if (chart != null && posX + width + mOffset2.x > chart.getWidth()) { offset = getOffsetRight(); mOffset2.x = offset.x; } mOffset2.y = offset.y; if (posX + mOffset2.x < 0 ) { mOffset2.x = -posX; } /*else if (chart != null && posX + width + mOffset2.x > chart.getWidth()) { mOffset2.x = chart.getWidth() - posX - width; }*/ if (posY + mOffset2.y < 0 ) { mOffset2.y = -posY; } else if (chart != null && posY + height + mOffset2.y > chart.getHeight()) { mOffset2.y = chart.getHeight() - posY - height; } return mOffset2; } @Override public void refreshContent(Entry e, Highlight highlight) { measure(MeasureSpec.makeMeasureSpec( 0 , MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec( 0 , MeasureSpec.UNSPECIFIED)); layout( 0 , 0 , getMeasuredWidth(), getMeasuredHeight()); } @Override public void draw(Canvas canvas, float posX, float posY) { MPPointF offset = getOffsetForDrawingAtPoint(posX, posY); int saveId = canvas.save(); // translate to the correct position and draw canvas.translate(posX + offset.x, posY + offset.y); draw(canvas); canvas.restoreToCount(saveId); } } |
主要是加了一个getOffsetRight函数,在getOffsetForDrawingAtPoint函数中判断,何时调用getOffsetRight即可。演示代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | NewMarkerView marker = new NewMarkerView( this , R.layout.layout_markview) { private TextView view; @Override protected void onLayout( boolean changed, int l, int t, int r, int b) { super .onLayout(changed, l, t, r, b); view = (TextView) super .findViewById(R.id.id_value); } @Override public void refreshContent(Entry e, Highlight l) { // TODO Auto-generated method stub StringBuffer buffer = new StringBuffer(); if (e.getData() instanceof Data) { Data data = (Data) e.getData(); buffer.append(data.getDate()); buffer.append( "\r\n" ); buffer.append(data.getData()); buffer.append(data.getStatus()); } view.setText(buffer); super .refreshContent(e, l); //必须加上该句话;This sentence must be added. } @Override public MPPointF getOffset() { return new MPPointF( 0 , -getHeight() >> 1 ); } @Override public MPPointF getOffsetRight() { return new MPPointF(-getWidth(), -getHeight()); } }; marker.setChartView(chart); |
最终效果图:
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2302
- 用户1336
- 访客10979821
每日一句
If you want to achieve greatness, stop asking for permission.
如果你想获得伟大,别再请求许可。
如果你想获得伟大,别再请求许可。
排名前5的开源在线机器学习
Android自定义蜂窝view
Android应用性能优化系列视图篇——隐藏在资源图片中的内存杀手
Java中的(耦合)控制反转
OpenGL读取帧缓存数据
首发:Thinkpad T550黑苹果10.13.4安装教程
反编译修改class文件变量
IntelliJ IDEA2018~2019.1激活码-注册码
p2p通信,打洞技术,穿越NAT的实现(附NAT环境检测工具)
【黑苹果安装】——如何在windows下操作EFI分区
Could not resolve io.flutter 解决方法
MPAndroidChart标记控件MarkerView的使用方法
imencode和imdecode使用
新会员