MPAndroidChart之chart源码分析

1、Chart的基本结构

在这里插入图片描述
在使用MPAndroidChart的时候,一会绘制是直接使用PieChart或者LineChart这些类去实现,他们都有一个公共的父类Chart,今天主要说一下这个类,从源头看一下MPAndroidChart的封装。

在这里插入图片描述
Chart自身是一个自定义的Viewgroup,所以其实核心操作也就是理解成自定义VIewGroup

2、流程分析

绘图有三宝onMeasureonLayoutonDraw,接下来就按照绘图流程来挨个击破

先看一下构造方法,常规这里面会初始化内容

2-1、先来瞅瞅构造方法初始化了啥?
protected void init() {
    setWillNotDraw(false);
    mAnimator = new ChartAnimator(new AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            postInvalidate();
        }
    });
    // initialize the utils
    Utils.init(getContext());
    mMaxHighlightDistance = Utils.convertDpToPixel(500f);
    mDescription = new Description();
    mLegend = new Legend();
    mLegendRenderer = new LegendRenderer(mViewPortHandler, mLegend);
    mXAxis = new XAxis();
    mDescPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    ...
}

第一行代码看到设置了setWillNotDraw(false);如果是有过自定义VIewGroup的朋友应该不会陌生,我们知道Android对于ViewGroup的绘制是有过优化处理的,默认情况下不会执行onDraw方法,而是执行的dispatchDraw,而这句话的意思就是让onDraw方法正常执行(当然还有一种方式也可以让onDraw执行,就是给布局设置背景)

接下里初始化了一个ChartAnimator对象,这个对象的声明是protected的,所以子类是可以自定覆盖实现的。

还初始化了Description(图表描述信息)和Legend(图例)以及Xasis(x坐标),因为这些属性都是每个绘图类型控件都会有的,所以会做公共初始化。

2-2、onMeasure & onLayout
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int size = (int) Utils.convertDpToPixel(50f);
    setMeasuredDimension(
            Math.max(getSuggestedMinimumWidth(),
                    resolveSize(size,
                            widthMeasureSpec)),
            Math.max(getSuggestedMinimumHeight(),
                    resolveSize(size,
                            heightMeasureSpec)));
}

这里的布局测量基本没什么可讲的,其实就是为布局设置了一个最小的宽高度为50DP。

@Override
 protected void onLayout(boolean changed, int left, int top,
  int right, int bottom) {
     for (int i = 0; i < getChildCount(); i++) {
         getChildAt(i).layout(left, top, right, bottom);
     }
 }

这里的布局排列也是一样,单纯的对子布局进行了排列,没啥特殊的。当然也是正常的,主要目的本来就是绘制。

2-3、onSizeChanged

在介绍onDraw之前先说下这个方法,相信精通绘制的大家对这个方法很熟悉了,他是在onLayout中调用的,所以这个方法中可以获取到布局的大小信息

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (w > 0 && h > 0 && w < 10000 && h < 10000) {
        mViewPortHandler.setChartDimens(w, h);
    } 
    notifyDataSetChanged();
    for (Runnable r : mJobs) {
        post(r);
    }
    mJobs.clear();
    super.onSizeChanged(w, h, oldw, oldh);
}

其实这块核心关注的就是mViewPortHandler.setChartDimens(w, h);,可以看到把布局的宽高度设置到了```ViewPortHandler``中。这个类后面会专门讲解,先不着急。`

2-4、onDraw
@Override
protected void onDraw(Canvas canvas) {
    if (mData == null) {
        boolean hasText = !TextUtils.isEmpty(mNoDataText);
        if (hasText) {
           //获取布局中心点
            MPPointF pt = getCenter();
            switch (mInfoPaint.getTextAlign()) {
                case LEFT:
                    pt.x = 0;
                    canvas.drawText(mNoDataText, pt.x, pt.y, mInfoPaint);
                    break;
                case RIGHT:
                    pt.x *= 2.0;
                    canvas.drawText(mNoDataText, pt.x, pt.y, mInfoPaint);
                    break;
                default:
                    canvas.drawText(mNoDataText, pt.x, pt.y, mInfoPaint);
                    break;
            }
        }
        return;
    }
    if (!mOffsetsCalculated) {
       //计算图表到边框的距离
        calculateOffsets();
        mOffsetsCalculated = true;
    }
}

有没有发现,这里只绘制了一个没有数据时候的展示文字,并没有绘制其他任何信息,连x轴、y轴都没有绘制,具体绘制的,下一篇文章会揭晓,包括ViewPortHandler等类

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值