Android: 利用SurfaceView绘制股票滑动直线解决延迟问题
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绘制股票滑动直线解决延迟问题的更多相关文章
- 利用JFreeChart绘制股票K线图完整解决方案
http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...
- Android 利用SurfaceView进行图形绘制
SurfaceView使用介绍 SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作. 要使用SurfaceView进行绘制,步骤如下: 1.用SurfaceView ...
- android利用zbar二维码扫描-(解决中文乱码及扫描区域定义)
写在最前(这是对上一篇博文的问题做的更新[android利用zbar二维码扫描]) project下载 zbarLib编译project project下载0积分 bug 在2.3的系统中Hol ...
- Android中不同方向嵌套滑动的解决方式(ListView为样例)
前言: 就像手机QQ的聊天消息列表.一个纵向滑动的ListView列举全部消息,但每一条消息能够横向滑动. 而默认情况下,仅仅能有一个地方消化处理触摸事件,要么ListView吃掉这个事件.要么子It ...
- android SurfaceView绘制实现原理解析
在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面.由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独 ...
- Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹
属性动画主要的几个类介绍: 1.ValueAnimator:这个类提供了一个简单的计时引擎运行动画动画计算值和设置目标对象.注意:使用该类时一般都是用:ObjectAnimator,而基于Object ...
- Android滑动冲突解决方法
叙述 滑动冲突可以说是日常开发中比较常见的一类问题,也是比较让人头疼的一类问题,尤其是在使用第三方框架的时候,两个原本完美的控件,组合在一起之后,忽然发现整个世界都不好了. 关于滑动冲突 滑动冲突分类 ...
- android SurfaceView绘制 重新学习--基础绘制
自从大二写了个android游戏去参加比赛,之后就一直写应用,一直没用过SurfaceView了,现在进入了游戏公司,准备从基础开始重新快速的学一下这个,然后再去研究openGL和游戏引擎. 直接上代 ...
- Android视图SurfaceView的实现原理分析(示例,出错代码)
在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面.由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独 ...
随机推荐
- vue-router实现页面的整体跳转
直接看效果图: 代码地址:https://github.com/YalongYan/vue-router-jump
- Javascript获取各种浏览器可见窗口大小
function getInfo() { var s = ""; s += " 网页可见区域宽:"+ document.body.clientWidth; s ...
- swoole创建TCP服务端和客户端
服务端: server.php <?php //创建Server对象,监听 127.0.0.1:9501端口 $serv = new swoole_server("127.0.0 ...
- 测试站如何最快获取正式站的最新数据: ln -s
针对静态数据, 比如图片/js等文件, 测试站如何获取最新的呢? ln -s /alidata/www/mysite/uploads /alidata/www/mysite_test/uploads ...
- c++操作flash
c++操作falsh,忘了原文在哪了,自己尝试了,直接贴代码 // SDK版本 //////////////////////////////////////////////////////////// ...
- ABAP OO 开发语法整理
[转自 http://blog.csdn.net/saphome/article/details/6956933] 在类中,只能用TYPE 附加关键字指定数据类型. •TYPES: 一般的类型定义方法 ...
- awk 字符串函数
awk 提供了许多强大的字符串函数,见下表: awk 内置字符串函数 gsub(r,s) 在整个 $0 中用 s 替代 r gsub(r,s,t) 在整个 t 中用 s 替代 r index(s,t) ...
- 牛客练习赛13 B 幸运数字Ⅱ 【暴力】【二分】
题目链接 https://www.nowcoder.com/acm/contest/70/B 思路 没有代码限制 先打表 打出 幸运数字的表 然后 二分查找 第一个 大于 r 的幸运数字 然后 往 L ...
- mini2440移植uboot 2014.04(四)
我修改的代码已经上传到github上,地址:https://github.com/qiaoyuguo/u-boot-2014.04-mini2440.git 参考文章: <mini2440移植u ...
- uitableview 刷新一行
ios UITableview 刷新某一行 或 section //一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWith ...