重写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> ...
随机推荐
- 【从零之六&完结】android口语对话系统(RavenClaw java版 含所有源代码)
! !! 更新:最新源码放到了github上,认为还不错点个星啊! 点击打开链接 做了一个半月最终完毕了,以下这个就是我參考Olympus/RavenClaw系统编写的对话管理系统.眼下实现了一个简单 ...
- leetcode第一刷_Add Binary
二进制相加,本质上就是大整数加法,有关大整数加法我的舍友教过我一个非常好的方法,先用一个int数组保存结果,将两个数相应位置相加,所有加完后.再统一处理进位的问题.这种方法相同适用于大整数的乘法. 这 ...
- Baby_Step,Gaint_Step(分析具体解释+模板)
下面是总结自他人博客资料.以及本人自己的学习经验. [Baby_Step,Gaint_Step定义] 高次同余方程. BL == N (mod P) 求解最小的L.因为数据范围非常大,暴力不行 这里用 ...
- Python菜鸟晋级12----多线程
Python 多线程 多线程类似于同一时候执行多个不同程序,多线程执行有例如以下长处: 使用线程能够把占领长时间的程序中的任务放到后台去处理. 用户界面能够更加吸引人.这样比方用户点击了一个butto ...
- php设计模式适配器模式
php设计模式适配器模式 简介 适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的.一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起. 其实就是通过一个转换类,这个转 ...
- ORA-00980:synonym translation is no longer valid
今天要把测试环境DB的数据更新成最新Production环境的数据,期间发生了一些问题: 1.首先从正式环境exp出想要用户的dmp档 2.drop掉测试环境底下相应用户 3.create测试环境底下 ...
- xBIM 实战01 在浏览器中加载IFC模型文件
系列目录 [已更新最新开发文章,点击查看详细] 一.创建Web项目 打开VS,新建Web项目,选择 .NET Framework 4.5 选择一个空的项目 新建完成后,项目结构如下: 二.添 ...
- POJ 2184 DP
思路: f[j]表示当ts的和为j的时候tf的最大值. 这时候要分情况讨论: (我把状态平移了101000) 若ts[i]>=0倒序循环 否则正序 (防止ts被用了多次) f[101000]=0 ...
- sql server 数据库distinct的用法
Distinct:用来过滤重复记录.往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值.其原因是distinct只有用二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直 ...
- ES6 | 关于class类 继承总结
子类必须在constructor方法中调用super方法,否则新建实例时会报错.这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工.如果不调用super方法,子类就得不到 ...