你好,游客 登录
背景:
阅读新闻

自己定义的View曲线图 多点触控 canvas -

[日期:2013-04-14] 来源:  作者: [字体: ]

源码 可能不太优雅 但是主要是提供给出大家一点 思路 相信 Android 只有想不到 没有做不到的。

先看一下效果图:

静止

单点触控

多点触控

部分代码:

EnergyItem.java

package com.example.energycurve.ben;

/**
 * 能耗 Bean
 * @author keven.cheng
 *
 */
public class EnergyItem {

    public String date;    //时间值
    public float value;    //能量
    public String time;    //使用时间
    
    public EnergyItem() {
        super();
    }
    public EnergyItem(String date, float value, String time) {
        super();
        this.date = date;
        this.value = value;
        this.time = time;
    }
    
    
}

 

/**
     * 初始化绘制
     * 
     * @param canvas
     * @param paint
     */
    private void initDraw(Canvas canvas, Paint paint) {
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(3);
        /* 裁剪出一个需要的矩阵图 */
        Path path = new Path();
        PointF point = null;
        path.moveTo(SPACING, mGradientHeight + SPACING_HEIGHT);
        for (int i = 0; i < points.size(); i++) {
            point = points.get(i);
            path.lineTo(point.x, point.y - SPACING_HEIGHT);
        }
        path.lineTo(point.x, mGradientHeight + SPACING_HEIGHT);
        path.lineTo(SPACING, mGradientHeight + SPACING_HEIGHT);
        path.close();
        Bitmap btm = Bitmap.createBitmap((int) mGradientWidth,
                (int) mGradientHeight, Config.ARGB_8888);
        Bitmap creatBitmap = creatBitmap(paint, path, btm);
        /* 绘制底部的横线、文字、以及向上的线条 */
        canvas.drawLine(SPACING, mGradientHeight + SPACING_HEIGHT,
                mGradientWidth, mGradientHeight + SPACING_HEIGHT, paint);
        for (int i = 0; i < energyItems.size(); i++) {
            EnergyItem energy = energyItems.get(i);
            PointF textPoint = points.get(i);
            paint.setColor(Color.GRAY);
            paint.setStrokeWidth(1);
            // 绘制底部 到上面的线
            canvas.drawLine(textPoint.x, mGradientHeight + SPACING_HEIGHT,
                    textPoint.x, SPACING_HEIGHT + WEIGHT + 3, paint);
            paint.setColor(Color.WHITE);
            // 绘制底部的 文字
            canvas.drawText(energy.date, textPoint.x - 15, mGradientHeight
                    + SPACING_HEIGHT + 20, paint);
        }
        /* 绘制虚线 */
        Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        PathEffect effects = new DashPathEffect(new float[] { 3, 3, 3, 3 }, 3);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(1);
        mPaint.setPathEffect(effects);
        float dottedSpacing = (mGradientHeight - WEIGHT) / 4;
        float smallDotted = dottedSpacing / 10;
        for (int i = 1; i <= 4; i++) {
            Path dottedPath = new Path();
            mPaint.setColor(Color.GRAY);
            mPaint.setAlpha(0x50);
            dottedPath.moveTo(SPACING, mGradientHeight + SPACING_HEIGHT
                    - dottedSpacing * i);
            dottedPath.lineTo(mGradientWidth, mGradientHeight + SPACING_HEIGHT
                    - dottedSpacing * i);
            canvas.drawPath(dottedPath, mPaint);
        }
        /* 左边刻度尺 */
        float digit = ((maxEnergy.value) / 4 + maxEnergy.value) / 4;
        for (int i = 1; i <= 4; i++) {
            paint.setStrokeWidth(1);
            int digitInt = (int) (digit * i + 1.0e-6);
            canvas.drawText(String.valueOf(digitInt), SPACING - 25,
                    mGradientHeight + SPACING_HEIGHT - dottedSpacing * i + 5,
                    paint);
            canvas.drawLine(SPACING, mGradientHeight + SPACING_HEIGHT
                    - dottedSpacing * i, SPACING + 10, mGradientHeight
                    + SPACING_HEIGHT - dottedSpacing * i, paint);
            for (int j = 0; j <= 10; j++) {
                if (j == 5) {
                    canvas.drawLine(SPACING, mGradientHeight + SPACING_HEIGHT
                            - dottedSpacing * i + smallDotted * j,
                            SPACING + 10, mGradientHeight + SPACING_HEIGHT
                                    - dottedSpacing * i + smallDotted * j,
                            paint);
                } else {
                    canvas.drawLine(SPACING, mGradientHeight + SPACING_HEIGHT
                            - dottedSpacing * i + smallDotted * j, SPACING + 5,
                            mGradientHeight + SPACING_HEIGHT - dottedSpacing
                                    * i + smallDotted * j, paint);
                }
            }
        }
        // 绘制裁剪后的矩阵图
        canvas.drawBitmap(creatBitmap, 0, SPACING_HEIGHT, paint);

        /* 绘制曲线 覆盖 剪切后的锯齿 */
        for (int i = 0; i < points.size(); i++) {
            paint.setStrokeWidth(3);
            PointF startPoint = points.get(i);
            if (i + 1 == points.size()) {
                // 绘制最后一个圆点到底部的 竖线
                paint.setStrokeWidth(1);
                canvas.drawLine(startPoint.x, startPoint.y, startPoint.x,
                        mGradientHeight + SPACING_HEIGHT, paint);
                // 绘制 最后一个圆点 为剪切的图片
                canvas.drawBitmap(mLastPoint,
                        startPoint.x - mLastPoint.getWidth() / 2, startPoint.y
                                - mLastPoint.getHeight() / 2, paint);
                break;
            }
            PointF endPoint = points.get(i + 1);
            // 绘制曲线,并且覆盖剪切后的锯齿
            canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y,
                    paint);
            // 为了使线条圆滑 绘一个点 每个坐标系 绘制一个圆点
            canvas.drawPoint(startPoint.x, startPoint.y, paint);
        }
// 绘制左边的竖线,以及温度的刻度 (由于需要与顶边 产生间距SPACING_HEIGHT)———— 目前模拟 待修改
  canvas.drawLine(SPACING, SPACING_HEIGHT, SPACING, mGradientHeight
    + SPACING_HEIGHT, paint);
  // 绘制右边的 字(时、天、月)通过Type来进行修改———— 目前模拟 待修改
  paint.setTextSize(16);
  canvas.drawText("天", mGradientWidth + 5, mGradientHeight
    + SPACING_HEIGHT + 5, paint);
  canvas.drawText("度", SPACING - 8, 30, paint);
 }

单点触摸

/**
     * 单点触控操作
     * 
     * @param canvas
     * @param paint
     */
    private void SinglePointTouch(Canvas canvas, Paint paint) {
        // 顶部的度数框
        if (moveXOfFirst < points.get(0).x) {
            moveXOfFirst = points.get(0).x;
        }
        if (moveXOfFirst > points.get(points.size() - 1).x) {
            moveXOfFirst = points.get(points.size() - 1).x;
        }
        float moveX = moveXOfFirst;
        // 绘制度数框 背景后的 横线
        canvas.drawBitmap(mTitleLine, SPACING, mGradientHeight + SPACING_HEIGHT
                - mTrendLine.getHeight() + 5, paint);
        // 绘制 移动的 点
        onPointMove(canvas, paint, moveXOfFirst, isDown);
        canvas.drawBitmap(
                mDegree,
                moveX - mDegree.getWidth() / 2,
                (mGradientHeight + SPACING_HEIGHT - mTrendLine.getHeight() + 5) / 2,
                paint);

        // 绘制 变动的 能耗为多少

        float moveY = getMoveY(moveXOfFirst);
        float energyHeight = (float) (mGradientHeight + SPACING_HEIGHT) - moveY;

        String energyText = String.valueOf(energyHeight / spacingOfY);
        // 为了避免误差 如果单点 手指在X轴 在预定的 X点上 那么直接将显示读书设置为 服务器传回的数据
        EnergyItem energy = isInPoint(moveXOfFirst);
        if (energy != null) {
            energyText = String.valueOf(energy.value);
        }
        int indexOf = energyText.indexOf(".");
        String substring = energyText.substring(0, indexOf + 2);
        paint.setTextSize(28);
        paint.setColor(Color.BLACK);
        canvas.drawText(substring + "度", moveX - mDegree.getWidth() / 3,
                mGradientHeight + SPACING_HEIGHT - mTrendLine.getHeight()
                        + mDegree.getHeight() / 3, paint);
    }

多点触摸

/**
     * 多点触控操作
     * 
     * @param canvas
     * @param paint
     */
    private void multiPointTouch(Canvas canvas, Paint paint) {
        paint.setColor(Color.rgb(240, 150, 40));
        paint.setStrokeWidth(4);
        // 计算 多点选择 的两个点 分别处在 屏幕的 某个区域内 并且计算出区域中的点
        float pointSpacing = 0.0f; // 两点之间的间距
        if (moveXOfFirst < points.get(0).x) {
            moveXOfFirst = points.get(0).x;
        }
        if (moveXOfFirst > points.get(points.size() - 1).x) {
            moveXOfFirst = points.get(points.size() - 1).x;
        }
        if (moveXOfSecond < points.get(0).x) {
            moveXOfSecond = points.get(0).x;
        }
        if (moveXOfSecond > points.get(points.size() - 1).x) {
            moveXOfSecond = points.get(points.size() - 1).x;
        }
        int moveXOfOne = getLocation(moveXOfFirst);
        int moveXOfTwo = getLocation(moveXOfSecond);
        // 第一个点 小于 第二个点
        if (moveXOfOne < moveXOfTwo) {
            if (!(moveXOfSecond == points.get(points.size() - 1).x)) {
                moveXOfTwo = moveXOfTwo - 1;
            }
            // 重绘 两点间的 的连接线
            canvas.drawLine(moveXOfFirst, getMoveY(moveXOfFirst),
                    points.get(moveXOfOne).x, points.get(moveXOfOne).y, paint);
            for (int j = moveXOfOne; j < moveXOfTwo; j++) {
                PointF startPoint = points.get(j);
                if (j + 1 == points.size()) {
                    // 绘制 最后一个圆点 为剪切的图片
                    canvas.drawBitmap(mLastPoint,
                            startPoint.x - mLastPoint.getWidth() / 2,
                            startPoint.y - mLastPoint.getHeight() / 2, paint);
                    break;
                }
                PointF endPoint = points.get(j + 1);
                // 绘制曲线,并且覆盖剪切后的锯齿
                canvas.drawLine(startPoint.x, startPoint.y, endPoint.x,
                        endPoint.y, paint);
                // 为了使线条圆滑 绘一个点 每个坐标系 绘制一个圆点
                canvas.drawPoint(startPoint.x, startPoint.y, paint);
            }
            canvas.drawLine(points.get(moveXOfTwo).x, points.get(moveXOfTwo).y,
                    moveXOfSecond, getMoveY(moveXOfSecond), paint);
        }
        // 第一个点 大于 第二个点
        if (moveXOfOne > moveXOfTwo) {
            if (!(moveXOfFirst == points.get(points.size() - 1).x)) {
                moveXOfOne = moveXOfOne - 1;
            }
            // 重绘 两点间的 的连接线
            canvas.drawLine(moveXOfSecond, getMoveY(moveXOfSecond),
                    points.get(moveXOfTwo).x, points.get(moveXOfTwo).y, paint);
            for (int j = moveXOfTwo; j < moveXOfOne; j++) {
                PointF startPoint = points.get(j);
                if (j + 1 == points.size()) {
                    // 绘制 最后一个圆点 为剪切的图片
                    canvas.drawBitmap(mLastPoint,
                            startPoint.x - mLastPoint.getWidth() / 2,
                            startPoint.y - mLastPoint.getHeight() / 2, paint);
                    break;
                }
                PointF endPoint = points.get(j + 1);
                // 绘制曲线,并且覆盖剪切后的锯齿
                canvas.drawLine(startPoint.x, startPoint.y, endPoint.x,
                        endPoint.y, paint);
                // 为了使线条圆滑 绘一个点 每个坐标系 绘制一个圆点
                canvas.drawPoint(startPoint.x, startPoint.y, paint);
            }
            canvas.drawLine(points.get(moveXOfOne).x, points.get(moveXOfOne).y,
                    moveXOfFirst, getMoveY(moveXOfFirst), paint);
        }
        // 第一个点 等于 第二个点
        if (getArea(moveXOfFirst) == getArea(moveXOfSecond)) {
            canvas.drawLine(moveXOfFirst, getMoveY(moveXOfFirst),
                    moveXOfSecond, getMoveY(moveXOfSecond), paint);
        }
        float allEnergy = 0.0f; // 区域内的温度总和
        // 第一点小于第二点的情况
        if (moveXOfFirst < moveXOfSecond) {
            pointSpacing = Math.abs(moveXOfSecond - moveXOfFirst) / 2
                    + moveXOfFirst;
            // 得到两点间的 能量总计
            for (int j = moveXOfOne; j <= moveXOfTwo; j++) {
                allEnergy += energyItems.get(j).value;
            }
        }
        // 第一点大于第二点的情况
        if (moveXOfFirst > moveXOfSecond) {
            pointSpacing = Math.abs(moveXOfFirst - moveXOfSecond) / 2
                    + moveXOfSecond;
            for (int j = moveXOfTwo; j <= moveXOfOne; j++) {
                allEnergy += energyItems.get(j).value;
            }
        }
        // 第两点相等的情况
        if (moveXOfFirst == moveXOfSecond) {
            pointSpacing = Math.abs(moveXOfFirst);
        }
        // 绘制 移动的 点
        onPointMove(canvas, paint, moveXOfFirst, isDown);
        if (eventCount >= 2) {
            onPointMove(canvas, paint, moveXOfSecond, isDown);
        }
        // 绘制度数框 背景后的 横线
        canvas.drawBitmap(mTitleLine, SPACING, mGradientHeight + SPACING_HEIGHT
                - mTrendLine.getHeight() + 5, paint);
        // 顶部的度数框
        canvas.drawBitmap(mDegree, pointSpacing - mDegree.getWidth() / 2
                + mTrendLine.getWidth() / 2, (mGradientHeight + SPACING_HEIGHT
                - mTrendLine.getHeight() + 5) / 2, paint);
        // 绘制 总共消耗的能耗为多少
        String energyText = String.valueOf(allEnergy);
        int indexOf = energyText.indexOf(".");
        String substring = energyText.substring(0, indexOf + 2);
        paint.setTextSize(28);
        paint.setColor(Color.BLACK);
        canvas.drawText(substring + "度", pointSpacing - mDegree.getWidth() / 4,
                mGradientHeight + SPACING_HEIGHT - mTrendLine.getHeight()
                        + mDegree.getHeight() / 3, paint);
    }

源码下载:EnergyCurve.rar

 






收藏 推荐 打印 | 录入:admin | 阅读:
相关新闻