【原创】彩票走势图的绘制(究极版)

一、效果图展示

chart_view_four.gif

二、分析

很多时候如果View超出了屏幕,我们希望能够靠两根手指对View进行放大和缩小。放大缩小的话我们就要用到矩阵 Matrix 的知识。

三、代码实现

监听手指的手势,需要用到一个类:

    //拉伸手势
    ScaleGestureDetector scaleGestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.OnScaleGestureListener() {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            isScaling = true;
            float scaleFactor = detector.getScaleFactor();
            if (getMatrixScaleY() * scaleFactor > 3) {
                scaleFactor = 3 / getMatrixScaleY();
            }
            if (firstScale) {
                anchorX = detector.getCurrentSpanX();
                anchorY = detector.getCurrentSpanY();
                firstScale = false;
            }

            if (getMatrixScaleY() * scaleFactor < 0.5) {
                scaleFactor = 0.5f / getMatrixScaleY();
            }
            matrix.postScale(scaleFactor, scaleFactor, anchorX, anchorY);
            //计算拉伸
            computecellLocation();
            invalidate();
            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return true;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            isScaling = false;
            firstScale = true;
        }
    });

当然如果你要确保监听的到,需要在 onTouchEvent() 里面加上一句话:

        //监听拉伸
        scaleGestureDetector.onTouchEvent(event);

然后回调到 onScale() 的时候,我们需要加一个边界判断,放大比例最大是3倍,缩小比例最小是 0.5 ,这个值可以写成变量。
(anchorX 和 anchorY 我以为是两根手指的中心点,参照这个点放大。很遗憾并不是,我修改为(5000, 5000),貌似还是从(0, 0)开始放大)

    matrix.postScale(scaleFactor, scaleFactor, anchorX, anchorY);

这句话就是整个核心,post 在网络请求有一个意思是添加,这里可以这样理解,在原有的放缩比上增加当前放缩比例。记录完之后,我们需要拿出来进行计算:

    /**
     * 计算每一个cell的位置
     */
    private void computecellLocation() {
        float scaleX = getMatrixScaleX();
        float scaleY = getMatrixScaleY();

        int columnCount = 0;
        int groupSize = cellGroups.size();
        for (int i = 0; i < groupSize; i++) {
            CellGroup cellGroup = cellGroups.get(i);
            cellGroup.setTitle("第" + (i + 1) + "期");
            cellGroup.setLocation(0, leftBarWidth, (int) (cellHeight * scaleY * i + topBarHeight), (int) (cellHeight * scaleY * (i + 1) + topBarHeight));
            List cells = cellGroup.getCells();
            int cellSize = cells.size();
            columnCount = cellSize;
            for (int j = 0; j < cellSize; j++) {
                Cell cell = cells.get(j);
                cell.setLocation(
                        (int) (cellWidth * scaleX * j + leftBarWidth),
                        (int) (cellWidth * scaleX * (j + 1) + leftBarWidth),
                        (int)(cellHeight * scaleY * i + topBarHeight),
                        (int)(cellHeight * scaleY * (i + 1) + topBarHeight));
            }
        }

        //计算顶部栏的位置
        int size = topCells.size();
        for (int i = 0; i < size; i++) {
            Cell cell = topCells.get(i);
            cell.setLocation((int) (cellWidth * scaleX * i + leftBarWidth), (int) (cellWidth * scaleX * (i + 1) + leftBarWidth), 0, topBarHeight);
        }

        maxWidth = (int) (columnCount * cellWidth * scaleX + leftBarWidth);
        maxHeight = (int) (groupSize * cellHeight * scaleY + topBarHeight);
    }

这个方法我们一直在修改,View放大了,并不是View的宽高变化了,只是我们记录的数据要改变。比如我们的宽以前是20,现在放大了3倍,那么就是宽变成了60。
左侧栏的宽度和顶部栏的高度不变化我们就不需要乘以比例。

以上就是所有代码。我在之前的主干分支上又切了一个 “伸缩版” 的分支,可以下载下来研究研究,好用给个star。3q

github地址

你可能感兴趣的:(【原创】彩票走势图的绘制(究极版))