欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义View折线图

程序员文章站 2022-05-30 22:46:10
...

自定义View的步骤我们应该都比较熟悉,其中几个比较重要的方法:

onSizeChanged

onMeasure

onDraw

自定义View折线图


我们可以在onSizeChanged中获取我们自定义View的宽和高,然后有助于我们后面的计算。在onDraw方法中进行一些折线和刻度值得绘制动作,这里直接上代码

(1)初始化参数的相关代码

/**
     * 初始化参数
     */
    private void initData() {

        //底部刻度高度为15px,文字占用15dp,文字和刻度间距为15px
        mTotalYPx = mHeight - mHeight * mMultiple - dipToPx(15) - 2 * mTextPadding;
        //底部两个刻度之间的大小px
        mBottomCalWidth = (int) ((mWidth - 2 * mWidth * mMultiple) / mXCalValues.length);
        //刻度之外的间距距离
        mDiffValue = mWidth - 2 * mWidth * mMultiple - mBottomCalWidth * (mXCalValues.length - 1);
        //y轴两个刻度之间的像素大小
        mYPxValue = mTotalYPx / mYCalCount;

        for (int i = 0; i < mYCalCount; i++) {

            mTotalYValue.add(String.valueOf((int) (mMaxYValue - i * mYPxValue)));
        }

        mTotalPoints = new ArrayList<>();
        float valueOfPx = mTotalYPx / mMaxYValue;   //每像素值的大小

        //初始化这线上每个点的坐标位置
        for (int i = 0; i < mXCalValues.length; i++) {
            Point point = new Point();
            if (i == 0)
                point.x = (int) (mWidth * mMultiple + mDiffValue / 2);
            else
                point.x = (int) (mWidth * mMultiple + mBottomCalWidth * i + mDiffValue / 2);

            point.y = (int) (mHeight - dipToPx(15) - 2 * mTextPadding - mChartValues[i] * valueOfPx);
            mTotalPoints.add(point);
            if (i == 0)  //连接所有的折线转折点
                mPath.moveTo(point.x, point.y);
            else
                mPath.lineTo(point.x, point.y);
        }
    }

(2)onDraw中具体的绘制过程(详情参考源代码)

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        drawDashLine(canvas);
        drawLeftCal(canvas);
        drawBottomLine(canvas);
        drawTimeCal(canvas);
        drawChartLine(canvas);
        drawPointCircle(canvas);
        drawRectBackGround(canvas);
    }
(3)对折线原点的触摸点击事件处理

@Override
    public boolean onTouch(View view, MotionEvent motionEvent) {

        boolean inArea = isInArea(motionEvent.getX(), motionEvent.getY());
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (inArea) {
                    postInvalidate();
                    return true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

    public boolean isInArea(float x, float y) {

        for (int i = 0; i < mTotalPoints.size(); i++) {
            int tempX = mTotalPoints.get(i).x;
            int tempY = mTotalPoints.get(i).y;
            if (x >= tempX - dipToPx(5) && x <= tempX + dipToPx(5) && y >= tempY - dipToPx(5) && y <= tempY + dipToPx(5)) {
                mPosition = i;
                return true;
            }
        }
        return false;
    }

源代码

相关标签: 自定义view