由于折线统计图在绘制过程中,会经常拖动,而每次拖动都需要重新绘制,所以考虑使用surfaceview。

1、继承Surfaceview,实现SurfaceHolder.Callback, Runnable接口

    /**     * 画布创建时候执行的方法     *      * @param holder     */    @Override    public void surfaceCreated(SurfaceHolder holder) {        // 开始绘画        mIsDrawing = true;        // 启动绘画线程        new Thread(this).start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    /**     * 画布销毁时候执行的方法     */    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // 停止绘画        mIsDrawing = false;    }

2、绘制线程执行的方法

    /** 子线程,循环绘制折线 */    @Override    public void run() {        // 如果处于绘画状态,那么就开始绘制        while (mIsDrawing) {            // 设置滚动减速            setSpeedCut();            // 绘制方法            draw();        }    }    /**     * 设置快速滚动时,末尾的减速     */    private void setSpeedCut() {        if (!mIsTouch && isScroll) {            // 通过当前速度计算所对应的偏移量            mOffset = mOffset + mSpeed;            //当处于边缘时候使值不在变化            setOffsetRange();        }        // 每次偏移量的计算        if (mSpeed != 0) {            time++;            //这里设置的是快速滚动时间不操作两秒            //可以看成是一个Y轴交点为(0,xVelocity)            //          x轴交点为(40,xVelocity)            //          对称轴为40<每个单位时间为50毫秒,40对应两秒>            mSpeed = (int) (xVelocity + time * time *                     (xVelocity / 1600.0) - (xVelocity / 20.0) * time);        } else {            time = 0;            mSpeed = 0;        }    }    /** 具体的绘制方法 */    private void draw() {        try {            long start = System.currentTimeMillis();            // 获取并锁定画布            mCanvas = mHolder.lockCanvas();            // 设置画布背景为白色            mCanvas.drawColor(0xffffffff);            // 绘制坐标轴            drawAxis();            // 绘制曲线            drawLine();            long end = System.currentTimeMillis();            if (end - start < 50) {                Thread.sleep(50 - (end - start));            }        } catch (Exception e) {            e.printStackTrace();        } finally {            if (mCanvas != null) {                // 保证每次都将绘制的内容提交到服务器                mHolder.unlockCanvasAndPost(mCanvas);            }        }    }

3、绘制坐标轴

    /**     * 绘制x、y轴     */    private void drawXYLine() {        mAxisWidth = mWidth - 2 * mPaddint;        mAxisHeight = mHeight - 2 * mPaddint;        mCoordinatePaint.setStrokeWidth(mLineWidth);        mCoordinatePaint.setAntiAlias(true);        // 绘制x轴        mCoordinatePaint.setColor(mXLineColor);        mCanvas.drawLine(0, 0, mAxisWidth, 0, mCoordinatePaint);        // 绘制y轴        mCoordinatePaint.setColor(mYLineColor);        mCanvas.drawLine(0, 0, 0, -mAxisHeight, mCoordinatePaint);    }    /** 绘制刻度线和箭头 */    private void drawXYScale() {        // 画x轴的刻度        // x轴的分割线数量        mXScaleNum = mXRange / mXUnit;        // x轴尽头的空隙        mXBlank = dp2px(getContext(), DEFAULT_X_BLANK);        // 每个刻度的宽度        mXScaleWidth = (int) ((mAxisWidth - mXBlank) * 1.0 / mXScaleNum);        for (int i = 0; i < mXScaleNum; i++) {            mCanvas.drawLine(mXScaleWidth * (i + 1), 0, mXScaleWidth * (i + 1), -mScaleHeight, mCoordinatePaint);        }        // 画y轴的刻度        mYScaleNum = mYRange / mYUnit;        // y轴尽头的空间        mYBlank = dp2px(getContext(), DEFAULT_Y_BLANK);        mYScaleWidth = (int) ((mAxisHeight - mYBlank) * 1.0 / mYScaleNum);        for (int i = 0; i < mYScaleNum; i++) {            mCanvas.drawLine(0, -mYScaleWidth * (i + 1), mScaleHeight, -mYScaleWidth * (i + 1), mCoordinatePaint);        }        // 画X轴的箭头        mCanvas.drawLine(mAxisWidth, 0, mAxisWidth - mScaleHeight * 2, -mScaleHeight, mCoordinatePaint);        mCanvas.drawLine(mAxisWidth, 0, mAxisWidth - mScaleHeight * 2, mScaleHeight, mCoordinatePaint);        // 画Y轴的箭头        mCanvas.drawLine(0, -mAxisHeight, mScaleHeight, -mAxisHeight + 2 * mScaleHeight, mCoordinatePaint);        mCanvas.drawLine(0, -mAxisHeight, -mScaleHeight, -mAxisHeight + 2 * mScaleHeight, mCoordinatePaint);    }

4、绘制折线

    /** 绘制折线 */    private void drawLine() {        mCanvas.save();        mCanvas.translate(mPaddint, mHeight - mPaddint);        // 设置画笔属性        mLinePaint.setAntiAlias(true);        mLinePaint.setStrokeWidth(3);        mLinePaint.setColor(mLineColor);        mLinePaint.setStyle(Style.STROKE);        // 如果折线集合不为空        if (mLines != null && mLines.size() > 0) {            // 循环绘制所有线条            for (int i = 1; i < mLines.size(); i++) {                // 上一个点的xy坐标                int previousY = (int) (mLines.get(i - 1) * 1.0 / mYRange * (mAxisHeight - mYBlank));                int previousX = (i - 1) * mXScaleWidth + mOffset;                // 当前点的xy坐标                int thisY = (int) (mLines.get(i) * 1.0 / mYRange * (mAxisHeight - mYBlank));                int thisX = i * mXScaleWidth + mOffset;                // 保证只绘制坐标轴范围内的部分                if (previousX > 0 && previousX < mAxisWidth - mXBlank && thisX > 0 && thisX < mAxisWidth - mXBlank)                    // 两个坐标连线                    mCanvas.drawLine(previousX, -previousY, thisX, -thisY, mLinePaint);            }        }        mCanvas.restore();    }

5、触摸事件处理

    @Override    public boolean onTouchEvent(MotionEvent event) {        int rawX = (int) (event.getRawX());        // 计算当前速度        VelocityTracker velocityTracker = VelocityTracker.obtain();        velocityTracker.addMovement(event);        // 计算速度的单位时间        velocityTracker.computeCurrentVelocity(50);        switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            // 记录触摸点坐标            lastX = rawX;            mIsTouch = true;            break;        case MotionEvent.ACTION_MOVE:            // 计算便宜量            int offsetX = rawX - lastX;            // 在当前偏移量的基础上增加偏移量            mOffset = mOffset + offsetX;            setOffsetRange();            // 偏移量修改后下次重绘会有变化            lastX = rawX;            // 获取X方向上的速度            xVelocity = velocityTracker.getXVelocity();            mSpeed = (int) xVelocity;            break;        case MotionEvent.ACTION_UP:            mIsTouch = false;            break;        }        // 计算完成后回收内存        velocityTracker.clear();        velocityTracker.recycle();        return true;    }

最后附上源码下载地址:http://download.csdn.net/detail/h55l55/9528656

更多相关文章

  1. Android(安卓)第一个OpenGL ES程序
  2. Android(安卓)Material Design-Creating Apps with Material Des
  3. 自定义控件其实很简单(笔记一)
  4. Android取得当前屏幕静态布局的截图
  5. Android中Toolbar随着ScrollView滑动透明度渐变效果实现
  6. Android(安卓)drawable 可绘制资源总结
  7. Android(安卓)的第三方报表组件,AChartEngine 案列demo
  8. 运用开源 achartengine 绘制android端的折线图片,多表显示
  9. Android(安卓)Canvas drawArc方法介绍

随机推荐

  1. Android(安卓)Adobe工具类
  2. android 语音识别
  3. Android出现java.net.SocketException: P
  4. Android配置ip地址
  5. Android中的一些方法-----生生不息
  6. java.lang.IllegalStateException: Actio
  7. Android(安卓)Handler总结1-定义与用法
  8. Android(安卓)IOS 安全书籍
  9. Android之进程查看,关闭(可操作所有进程)
  10. android 中的MultipartEntity 类