1.背景介绍

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

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

2.Android中View和SurfaceView对比

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

  View                SurfaceView

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

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

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

3.案例

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

  1. package com.devin;
  2.  
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.graphics.PixelFormat;
  8. import android.graphics.PorterDuff.Mode;
  9. import android.view.MotionEvent;
  10. import android.view.SurfaceHolder;
  11. import android.view.SurfaceHolder.Callback;
  12. import android.view.SurfaceView;
  13.  
  14. public class MyStockIndicatorView extends SurfaceView implements Callback {
  15. private SurfaceHolder surfaceHolder;
  16. private Paint paint;
  17. private float currentX;
  18. public MyStockIndicatorView(Context context) {
  19. super(context);
  20. // 初始化SurfaceHolder
  21. surfaceHolder = this.getHolder();
  22. surfaceHolder.addCallback(this);
  23.  
  24. // 让整个界面透明
  25. surfaceHolder.setFormat(PixelFormat.TRANSPARENT);
  26. setZOrderOnTop(true);
  27.  
  28.      //初始化画笔
  29. paint = new Paint();
  30. paint.setAntiAlias(true);
  31. paint.setColor(Color.WHITE);
  32.  
  33.     //设置界面可以点击
  34. setFocusable(true);
  35. }
  36.  
  37.   //触屏事件,每次响应事件后改变坐标值,然后重新绘制
  38. public boolean onTouchEvent(MotionEvent event) {
  39. int eventaction = event.getAction();
  40. int x = (int) event.getX();
  41. switch (eventaction) {
  42. case MotionEvent.ACTION_DOWN:
  43. currentX = x;
  44. paintIndicator();
  45. break;
  46. case MotionEvent.ACTION_UP:
  47. clearCavas();
  48. break;
  49. case MotionEvent.ACTION_MOVE:
  50. currentX;
  51. paintIndicator();
  52. break;
  53. case MotionEvent.ACTION_CANCEL:
  54. clearCavas();
  55. break;
  56. }
  57.  
  58. return true;
  59. }
  60.  
  61.   //画直线
  62. private void paintIndicator() {
  63. Canvas canvas = surfaceHolder.lockCanvas();
  64.     
  65.      //下面两句用来改变原点、同时把默认的坐标系转换成笛卡尔坐标系
  66. //canvas.translate(chartLeft, getHeight());
  67. //canvas.scale(1, -1);
  68. canvas.drawLine(currentX, 0, currentX, getHeight(), paint);
  69.  
  70. surfaceHolder.unlockCanvasAndPost(canvas);
  71. }
  72.  
  73.   //清屏
  74. private void clearCavas() {
  75.     //每次绘制前要锁定画布
  76. Canvas canvas = surfaceHolder.lockCanvas();
  77. canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
  78.     //绘制完成后解锁画布
  79. surfaceHolder.unlockCanvasAndPost(canvas);
  80. }
  81.  
  82. public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
  83. }
  84.  
  85. public void surfaceCreated(SurfaceHolder surfaceHolder) {
  86.      //在此处初始化数据
  87. initData();
  88. }
  89.  
  90. public void surfaceDestroyed(SurfaceHolder holder) {
  91. }
  92. }

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

Android: 利用SurfaceView绘制股票滑动直线解决延迟问题的更多相关文章

  1. 利用JFreeChart绘制股票K线图完整解决方案

    http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...

  2. Android 利用SurfaceView进行图形绘制

    SurfaceView使用介绍 SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作. 要使用SurfaceView进行绘制,步骤如下: 1.用SurfaceView ...

  3. android利用zbar二维码扫描-(解决中文乱码及扫描区域定义)

    写在最前(这是对上一篇博文的问题做的更新[android利用zbar二维码扫描]) project下载   zbarLib编译project  project下载0积分 bug 在2.3的系统中Hol ...

  4. Android中不同方向嵌套滑动的解决方式(ListView为样例)

    前言: 就像手机QQ的聊天消息列表.一个纵向滑动的ListView列举全部消息,但每一条消息能够横向滑动. 而默认情况下,仅仅能有一个地方消化处理触摸事件,要么ListView吃掉这个事件.要么子It ...

  5. android SurfaceView绘制实现原理解析

    在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面.由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独 ...

  6. Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹

    属性动画主要的几个类介绍: 1.ValueAnimator:这个类提供了一个简单的计时引擎运行动画动画计算值和设置目标对象.注意:使用该类时一般都是用:ObjectAnimator,而基于Object ...

  7. Android滑动冲突解决方法

    叙述 滑动冲突可以说是日常开发中比较常见的一类问题,也是比较让人头疼的一类问题,尤其是在使用第三方框架的时候,两个原本完美的控件,组合在一起之后,忽然发现整个世界都不好了. 关于滑动冲突 滑动冲突分类 ...

  8. android SurfaceView绘制 重新学习--基础绘制

    自从大二写了个android游戏去参加比赛,之后就一直写应用,一直没用过SurfaceView了,现在进入了游戏公司,准备从基础开始重新快速的学一下这个,然后再去研究openGL和游戏引擎. 直接上代 ...

  9. Android视图SurfaceView的实现原理分析(示例,出错代码)

    在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面.由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独 ...

随机推荐

  1. Unity批量生成Prefab

    在项目中有时会遇到批量生成Prefab的需求.于是写了一个编辑器,用来实现此功能. 在Hierarchy面板中选中多个GameObject,点击生成Prefab即可. 如果所选物体中包含自定义Mesh ...

  2. onkeydown

    <input onkeydown="(function(){ )//或者其他 alert("enter") })(event)"/> $(this) ...

  3. Zookeeper数据与存储

    一.前言 前面分析了Zookeeper对请求的处理,本篇博文接着分析Zookeeper中如何对底层数据进行存储,数据存储被分为内存数据存储于磁盘数据存储. 二.数据与存储 2.1 内存数据 Zooke ...

  4. php自定义函数: 遍历文件夹及其子文件夹

    function traverse_folder($path = '.') { $current_dir = opendir($path); while(($file = readdir($curre ...

  5. iOS 开发与H5交互(JavaScriptCore框架的使用)

    现在的iOS项目中嵌入了越来越多的Web界面,当然是为了方便,那么为了迎合这一趋势,作为iOS开发程序员,我们必须要了解怎么样用OC去和这些Web界面进行交互.这里介绍的是JavaScriptCore ...

  6. Django之stark组件1

    stark组件 stark组件是根据Django admin为原型写的一个组件,能够让我们告别增删改查.stark组件是可插拔试的组件, 移植性强,而且只用配置文件就能够得到想要的数据 一.stark ...

  7. Linux的分区

    1.磁盘分区 主分区: 最多只能有4个 扩展分区: 最多只能有1个 主分区加扩展分区最多只能有4个 不能写入数据,只能包含逻辑逻辑分区 逻辑分区: 磁盘号从5开始,只要看到磁盘号是5,一定是逻辑分区 ...

  8. (转)RequireJS shim 用法说明

    RequireJS中如果使用AMD规范,在使用的过程中没有太多的问题,如果加载非AMD规范的JS文件,就需要使用Require中的shim. require.config({ paths:{ jque ...

  9. ubuntu14.04下svn版本管理系统的安装及常用命令的使用整理

    ubuntu14.04下安装svn$sudo apt-get install subversion 执行这一步就安装完成了,在ubuntu先安装很方便 安装完成后,创建版本库目录,由于是本地环境,就在 ...

  10. Data Structure Binary Tree: Construct Tree from given Inorder and Preorder traversals

    http://www.geeksforgeeks.org/construct-tree-from-given-inorder-and-preorder-traversal/ #include < ...