MPAndroidChart中出现的MarkerView偏移问题!!

前段时间,做图表选择了MPAndroidChart,经过一段时间的研究,终于完成了,当然里面肯定没那么完美。但是由于还有其他的事情就先放了一下。最近安排的事情忙完了,自己发现MarkerView实现的标签,有偏移问题。实在是看不下去了今天就来解决一下子。

首先,我在查找了很多文章之后,了解到MarkerView中存在偏移量的问题。

在代码中设置MarkerView:

MPChartMarkerView markerView = new MPChartMarkerView(lineChart.getContext(), R.layout.custom_marker_view); 
markerView.setChartView(lineChart);
lineChart.setMarker(markerView);//设置 marker ,点击后显示的功能 ,布局可以自定义

其中,MPChartMarkerView是自定义的,继承了MarkerView。并且实现了里面部分方法。其中有几个方法要着重了解一下:

draw(),就是去画你自定义的MarkerView的内容,posX,posY,就是画在指定的点。 
refreshContent(),顾名思义,就是刷新MarkerView的内容。传了两个参数,一个是Entry,一个是Highlight,可以知道,这个与Highlight有密切的关系。也就是说,只有在选择了一个Entry高亮显示了,才会画出这个刷新画出MarkerView。 
getOffsetForDrawingAtPoint(),与画的点的位置有关系,一个偏移量 
getOffset(),就是偏移量。

还有两个方法也可以注意一下(在MarkerView源码中可以看到):

public void setChartView(Chart chart) {
    mWeakChart = new WeakReference<>(chart);
}

public Chart getChartView() {
    return mWeakChart == null ? null : mWeakChart.get();
}

这两个方法,为什么我要提一下呢,因为我在仿照大神的写法写的时候,发现了这么一行代码:

Chart chart = getChartView(); 

在下面的计算偏移量的时候,要用到对象chart,当时没注意结果就报null了。所以呢,必须在代码中写上

markerView.setChartView(lineChart);

这样你在获取对上就不会报空指针了。(记一下,警醒自己)

上面唠唠叨叨的讲了很多,实际解决问题的方案还在下面:

首先,是要说 getOffset()这个方法,在起初的设置中我是重写的它,然而发生了位置偏移。具体代码是这样写的:

    private MPPointF mOffset;
    @Override
    public MPPointF getOffset() {
        if(mOffset == null) {
            // center the marker horizontally and vertically
            mOffset = new MPPointF(-(getWidth() / 2), -getHeight());

        }

        return mOffset;
    }

getWidth()跟getHeight(),两个方法是获取view的宽跟高。moffset应该是返回的那个点击的点得偏移量。但是这样写是不正确的,总会出现偏移问题。

所以呢,在看了一篇文章:https://blog.csdn.net/fly7632785/article/details/79863086之后,仿照这位大牛的写法,将我自定义的MarkerView进行了重新修改。当然,这位大牛进行了判断,当出现标签挤出屏幕的时候,这时候就用到了getChartView()获得的对象了。并进行了处理。但是我因为画的视图没有那么灵活所以就没用只是将字体缩小了一下。

最主要的还是getOffsetForDrawingAtPoint()方法的重写:

public static final int ARROW_SIZE = 10; // 箭头的大小(可忽略,根据自己来设置)
private static final float STOKE_WIDTH = 5;//这里对于stroke_width的宽度也要做一定偏移

 

@Override
    public MPPointF getOffsetForDrawingAtPoint(float posX, float posY) {
        MPPointF offset = getOffset();
        Chart chart = getChartView();
        float width = getWidth();
        float height = getHeight();
// posY \posX 指的是markerView左上角点在图表上面的位置
//处理Y方向
        if (posY <= height + ARROW_SIZE) {// 如果点y坐标小于markerView的高度,如果不处理会超出上边界,处理了之后这时候箭头是向上的,我们需要把图标下移一个箭头的大小
            offset.y = ARROW_SIZE;
        } else {//否则属于正常情况,因为我们默认是箭头朝下,然后正常偏移就是,需要向上偏移markerView高度和arrow size,再加一个stroke的宽度,因为你需要看到对话框的上面的边框
            offset.y = -height - ARROW_SIZE - STOKE_WIDTH; // 40 arrow height   5 stroke width
        }
//处理X方向,分为3种情况,1、在图表左边 2、在图表中间 3、在图表右边(不考虑超出屏幕问题)
        offset.x = 0;
        if (posX > width / 2) {//如果大于markerView的一半,说明箭头在中间,所以向右偏移一半宽度
            offset.x = -(width / 2);
        }
        return offset;
    }

就这样很好的解决了我的问题。

写这个,只是想记录一下自己改bug的思路跟过程。

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值