重写MPAndroidChart显示标记
MPAndroidChart是实现图表功能的优秀控件, 能够完毕大多数绘制需求. 对于改动第三方库而言, 优秀的架构是继承开发, 而不是把源代码拆分出去. MP在显示标记控件(MarkView)时, 会有异常, 导致标志在图表边缘显示不全, 则须要重写控件解决这个问题.
继承LineChart, 提取高亮位置坐标getHighLightPos
, 重绘标记drawMarkers
.
/**
* 数据中心的图表折线图, 继承MPChart的折线图
* <p>
* Created by wangchenlong on 15/10/13.
*/
public class CYDataLineChart extends LineChart {
@SuppressWarnings("unused")
private static final String TAG = "DEBUG-WCL: " + CYDataLineChart.class.getSimpleName();
// 默认构造器
public CYDataLineChart(Context context) {
super(context);
}
public CYDataLineChart(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CYDataLineChart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// 获取高亮点坐标
public float[] getHighLightPos(Entry e, Highlight highlight) {
return getMarkerPosition(e, highlight);
}
// 重写这种方法, 修复Bug
@Override
protected void drawMarkers(Canvas canvas) {
// if there is no marker view or drawing marker is disabled
if (mMarkerView == null || !mDrawMarkerViews || !valuesToHighlight())
return;
Rect newRect = canvas.getClipBounds();
newRect.inset(-80, 0); //make the rect larger
canvas.clipRect(newRect, Region.Op.REPLACE);
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < mIndicesToHighlight.length; i++) {
Highlight highlight = mIndicesToHighlight[i];
int xIndex = highlight.getXIndex();
if (xIndex <= mDeltaX && xIndex <= mDeltaX * mAnimator.getPhaseX()) {
Entry e = mData.getEntryForHighlight(mIndicesToHighlight[i]);
// make sure entry not null
if (e == null || e.getXIndex() != mIndicesToHighlight[i].getXIndex())
continue;
float[] pos = getMarkerPosition(e, highlight);
// Marker偏移
float tmpY = pos[1] - 8 * AppUtils.getPerDp();
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
// noinspection deprecation
paint.setColor(getResources().getColor(R.color.chart_circle));
canvas.drawCircle(pos[0], pos[1], 2 * AppUtils.getPerDp(), paint);
// check bounds
if (!mViewPortHandler.isInBounds(pos[0], tmpY))
continue;
mMarkerView.refreshContent(e, highlight);
mMarkerView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mMarkerView.layout(0, 0, mMarkerView.getMeasuredWidth(),
mMarkerView.getMeasuredHeight());
if (tmpY - mMarkerView.getHeight() <= 0) {
float y = mMarkerView.getHeight() - tmpY;
mMarkerView.draw(canvas, pos[0], tmpY + y);
} else {
mMarkerView.draw(canvas, pos[0], tmpY);
}
}
}
}
}
getMarkerPosition
是LineChart类中的protected方法, 继承类, 使用public方法导出.
float tmpY = pos[1] - 8 * AppUtils.getPerDp();
, 又一次计算Y坐标, 偏离原始画布.
可是这样做有一个问题, 在移动MarkView时, 父控件会有残留. 怎样解决呢?
办法就是在移动时, 重绘父控件的canvas, 使用invalidate()
函数.
// 设置图表点击事件, 监听高亮位置
mLcChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
@Override
public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
int index = e.getXIndex();
Log.e(TAG, "index = " + index);
setChartIndex(index);
mCallback.setCurIndex(index);
mIndex = index;
float[] pos = mLcChart.getHighLightPos(e, h);
Log.e(TAG, "x: " + pos[0] + ", y: " + pos[1]);
mLlContainer.invalidate(); // 重绘父控件, 避免残留
}
@Override
public void onNothingSelected() {
// 再次点击时调用这个, 要不非高亮
mLcChart.highlightValue(mIndex, 0);
}
});
// 外部设置图表高亮
private void setChartHighlight(int index) {
if (mLcChart.getData() == null) return;
mMarkerView.setDateText(mMarkers.get(index));
mLcChart.highlightValue(index, 0);
mLlContainer.invalidate(); // 重绘父控件, 避免残留
}
在图表控件中, 内部外部都会触发高亮位置.
OK, Enjoy It!
重写MPAndroidChart显示标记的更多相关文章
- 2019.03.20 读书笔记 as is 以及重写隐式/显示
强转.as is 的用法 强制转换类型有两种:子类转基类,重写隐式(implicit )\显示(explicit) 转换操作符 class myclass { private int value; p ...
- IIS-URL重写模块配置参考
本文提供了URL重写模块的概述,并解释了该模块使用的配置概念. 功能概述URL重写模块将请求URL重写为显示给用户或Web应用程序的简单,用户友好和搜索引擎友好的地址.URL重写使用定义的规则进行评估 ...
- 【MyLocations】标记位置App开发体会
实现功能: 1.能通过Cora Location获取地址信息 2.用户获取地址信息后能编辑相关信息 3.使用Core Data保存数据 4.使用MapKit,在Map上显示标记的位置,并可以编辑位置信 ...
- jquery.validate 以alert方式显示错误方法
$.validator.setDefaults({ submitHandler: function() { alert("submitted!");return false; } ...
- html标记语言 --格式标记
html标记语言 --格式标记 一.格式标记 1.<br>单标记,强制换行标记,让后面的文字.图片.表格等显示在下一行 2.<p>换段落标记 3.<center>居 ...
- android scrollview listview显示不全
原来处理方法是重写ListView import android.content.Context; import android.util.AttributeSet; import android.v ...
- Html常用标记总结
超文本标记语言的结构包括“头”部分(英语:Head).和“主体”部分(英语:body),其中“头”部提供关于网页的信息,“主体”部分提供网页的具体内容. Web页面绝大多数都是由html所编写的. 一 ...
- opencv+python视频实时质心显示
利用opencv+python实现以下功能: 1)获取实时视频,分解帧频: 2)将视频做二值化处理: 3) 将视频做滤波处理(去除噪点,获取准确轮廓个数): 4)识别图像轮廓: 5)计算质心: 6)描 ...
- html相关标记的含义
HTML标记含义1.<html>...</html> :html 文档标记2.<head>...</head> :文档头标记3.<title> ...
随机推荐
- if判断语句
6)if判断语句 if ... then else end if; if ... then elsif ... then elsif ... then else ...
- web_custom_request函数做get接口测试
最近研究了使用loadrunner做接口测试,刚开始一直不成功,后来加了QQ群,遇到大神了,经指导终于成功 下面是具体实例代码: //{"signIOS":1,"sign ...
- angular-HTML DOM
ng-disabled用法 <div ng-app="" ng-init="mySwitch=true"> <p> <button ...
- 仿写从iOS8开始支持的UIAlertController:BGAAlertController-Android
工作以来公司UI设计师出的Android效果图都是iOS风格的UIAlertView和UIActionSheet,新项目还是用原来那一套,不想重复造轮子,所以仿写了从iOS8开始支持的UIAlertC ...
- hdoj--5500--Reorder the Books(技巧)
Reorder the Books Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- 使用wpa_supplicant连接WIFI
让树莓派可以开机就连接制定的wifi, 可以通过wpa_supplicant来实现. 在 /etc/wpa_supplicant 下写一个配置文件: wpa_supplicant.conf 内容如下: ...
- Go语言结构体转json的坑
Go语言结构体转json的坑 标签(空格分隔): go json.Marshal() JSON输出的时候必须注意,只有导出的字段(首字母是大写)才会被输出,如果修改字段名,那么就会发现什么都不会输出, ...
- KMP字符串查找算法
#include <iostream> #include <windows.h> using namespace std; void get_next(char *str,in ...
- ie浏览器下get方式获取数据无效问题
在ie浏览器用get方式获取数据时因为发送得到参数地址都是一样的,所以浏览器会优先从缓存获取数据,而不去服务器请求数据,post由于参数不同所以不会影响. 解决方法: 1. Internet选项-- ...
- java类型与Hadoop类型之间的转换
java基本类型与Hadoop常见基本类型的对照Long LongWritableInteger IntWritableBoolean BooleanWritable String Text ...