码迷,mamicode.com
首页 > 移动开发 > 详细

Android: 利用SurfaceView绘制股票滑动直线解决延迟问题

时间:2015-06-15 20:29:07      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

1.背景介绍

  最近项目要绘制股票走势图,并绘制能够跟随手指滑动的指示线(Indicator)来精确查看股票价格和日期。如下图所示:

技术分享

  上图中的那条白色直线就是股票的指示线,用来跟随手指精确确定股票的时间和股票价格。不论是绘制股票图还是绘制指示线,我们首先想到的就是用Android中的自定义View来实现。实践证明,使用View能够很好地实现静态的图片,但是对用动态图像的绘制,往往会出现延迟的现象。就如上图的指示线,实际用View类实现的,跟随手指移动时,指示线就会出现延迟的现象,严重影响了用户体验,这里自然而然的要用到SurfaceView以提高性能,提高滑动的流畅度。

 

2.Android中View和SurfaceView对比

  下面例举了一下二者的区别:

  View                SurfaceView

  只能在UI主线程中更新画面      UI主线程和新起的独立线程中都可更新画面

  无双缓冲机制            采用双缓冲机制,速度快

  还有其他区别希望大家补充。

 

3.案例

  下面是该程序实现的主要代码,隐去了数据的填充。

package com.devin;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class MyStockIndicatorView extends SurfaceView implements Callback {
private SurfaceHolder surfaceHolder;
    private Paint paint;
    private float currentX;
public MyStockIndicatorView(Context context) {
        super(context);
        // 初始化SurfaceHolder
        surfaceHolder = this.getHolder();
        surfaceHolder.addCallback(this);

        // 让整个界面透明
        surfaceHolder.setFormat(PixelFormat.TRANSPARENT);
        setZOrderOnTop(true);

     //初始化画笔
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);

    //设置界面可以点击
        setFocusable(true);
    }

  //触屏事件,每次响应事件后改变坐标值,然后重新绘制
public boolean onTouchEvent(MotionEvent event) {
        int eventaction = event.getAction();
        int x = (int) event.getX();
        switch (eventaction) {
        case MotionEvent.ACTION_DOWN:
            currentX = x;
            paintIndicator();
            break;
        case MotionEvent.ACTION_UP:
            clearCavas();
            break;
        case MotionEvent.ACTION_MOVE:
            currentX;
            paintIndicator();
            break;
        case MotionEvent.ACTION_CANCEL:
            clearCavas();
            break;
        }

        return true;
    }

  //画直线
    private void paintIndicator() {
        Canvas canvas = surfaceHolder.lockCanvas();
    
     //下面两句用来改变原点、同时把默认的坐标系转换成笛卡尔坐标系
        //canvas.translate(chartLeft, getHeight());
        //canvas.scale(1, -1);
        canvas.drawLine(currentX, 0, currentX, getHeight(), paint);

        surfaceHolder.unlockCanvasAndPost(canvas);
    }

  //清屏
    private void clearCavas() {
    //每次绘制前要锁定画布
        Canvas canvas = surfaceHolder.lockCanvas();
        canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
    //绘制完成后解锁画布
        surfaceHolder.unlockCanvasAndPost(canvas);
    }

   public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
    }

    public void surfaceCreated(SurfaceHolder surfaceHolder) {
     //在此处初始化数据
        initData();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
    }
}

上述代码关键地方都有注释。对于SurfaceView的实现,需要继承SurfaceView和实现Callback接口,同时需要实现三个方法:surfaceCreated、surfaceDestroyed、surfaceChanged方法,分别表示SurfaceView创建、销毁、界面改变时执行的方法。在构造函数中要初始化SurfaceHolder,同时每次绘图前要锁定画布,绘制完成后解锁画布。

Android: 利用SurfaceView绘制股票滑动直线解决延迟问题

标签:

原文地址:http://www.cnblogs.com/chengzhengfu/p/4579038.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!