众所周知,view是通过刷新来重绘视图的,Android系统通过发出VSYNC信号来进行屏幕重绘,刷新的时间间隔为16ms,如果在16ms内view完成你所需要的所有操作,那么用户在视觉上就不会产生卡顿的感觉;而如果执行的操作逻辑太多,特别是需要频繁刷新的界面,就会不断阻塞主线程,从而导致画面卡顿。

因此Android提供了surfaceView。

1.View主要适用于主动更新的情况,surfaceView主要适用于被动更新,例如频繁的刷新。

2.View在主线程 中对View进行刷新,surfaceView通常会用一个子线程来进行页面的刷新。

3.View在绘图时没有双缓冲机制,而surfaceView在底层就已经实现了双缓冲机制。

因此如果自定义view需要频繁刷新或者刷新时候的数据处理量比较大,那么就可以考虑使用surfaceView来代替View

使用SurfaceeView有一套模板,以下用一个例子说明:用surfaceView做出示波器的效果,画出正弦波。

package com.example.tangzh.MyView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView; import com.example.tangzh.mylearn.R; /**
* Created by TangZH on 2017/4/30.
*/
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable //继承并实现两个接口
{
private SurfaceHolder mHolder;
//用于绘图的Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;
//画笔
private Paint mPaint;
private Path mPath;
//x坐标
private int x=0;
//y坐标
private int y=400; public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
initView();
} public MySurfaceView(Context context)
{
super(context);
initView();
} public MySurfaceView(Context context, AttributeSet attrs)
{
super(context, attrs);
initView();
}
private void initView()
{
mHolder=getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
} @Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
mIsDrawing=true;
mPath=new Path();
mPath.moveTo(0,400);
mPaint=new Paint();
mPaint.setColor(getResources().getColor(R.color.colorTheme));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
new Thread(this).start();
} @Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { } @Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mIsDrawing=false;
} @Override
public void run() {
while (mIsDrawing)
{
draw();
x+=5;
y=(int)(100* Math.sin(x*2*Math.PI/180)+400);
mPath.lineTo(x,y);
}
} private void draw() {
try {
mCanvas=mHolder.lockCanvas();
//SurfaceView背景
mCanvas.drawColor(Color.WHITE);
mCanvas.drawPath(mPath,mPaint);
}catch (Exception e)
{
e.printStackTrace();
}finally {
if(mCanvas!=null)
mHolder.unlockCanvasAndPost(mCanvas); //对画布内容进行提交
}
}
}

要注意,通过SurfaceView对象的lockCanvas()方法,就可以获取当前的Canvas绘图对象,这个对象跟上次的Canvas对象是同一个,因此之前的绘图操作都会被保留,如果需要擦出,则可以在绘制前,通过drawColor()方法来进行清屏操作。

利用SurfaceView显示正弦曲线,仿造示波器的更多相关文章

  1. Android自定义surfaceView显示多张图片

    我自定义了一个surfaceview,我在上面绘制多张图片,让它能够上下方滚显示图片,但是onMeasure()方法在重写的时候遇到了问题,不知道如何设置它的高度, public class MySu ...

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

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

  3. 技巧:利用 Workflow 显示附近的免费 Wi-Fi

    得益于 Workflow 自 1.5.3 版本起更新的 Get Content of URL 动作,该 App 的潜力得到了极大的提升.本文分享一种有趣的用法,搜寻附近的免费 Wi-Fi 并择一显示在 ...

  4. DirectX11 With Windows SDK--08 Direct2D与Direct3D互操作性以及利用DWrite显示文字

    前言 注意:从这一章起到后面的所有项目无一例外都利用了Direct2D与Direct3D互操作性,但系统要求为Win10, Win8.x 或 Win7 SP1且安装了KB2670838补丁以支持Dir ...

  5. 利用shell显示wordcount功能

      Shell脚本编程是Linux系统最为核心的技术之一,它能够利用简单的命令来实现一些复杂的功能,同时,由于Linux提供了很多文本处理命令,如grep(grep family), tr, sed, ...

  6. 利用div显示隐藏实现的分页效果

    实现步骤: 1.创建对应切换div <div class="bottom_daohang"> <div class="bottom_daohang_zo ...

  7. 【Android 多媒体应用】使用MediaCodec解码使用SurfaceView显示视频

    1.MainActivity.java import android.app.Activity; import android.os.Bundle; import android.os.Environ ...

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

    1.背景介绍 最近项目要绘制股票走势图,并绘制能够跟随手指滑动的指示线(Indicator)来精确查看股票价格和日期.如下图所示: 上图中的那条白色直线就是股票的指示线,用来跟随手指精确确定股票的时间 ...

  9. XML利用接口显示并导入到数据库

    //控制器代码 /// <summary> /// 页面 /// </summary> /// <returns></returns> public A ...

随机推荐

  1. RocketMQ入门手册

    前言 继我上一篇博客后 分布式消息队列RocketMQ学习教程① 上一篇博客最主要介绍了几种常用的MQ,所以本博客再简单介绍一下RocketMQ的原理和简单的例子,基于Java实现,希望可以帮助学习者 ...

  2. ubuntu中环境变量文件/etc/profile、.profile、.bashrc、/etc/bash.bashrc之间的区别和联系

    一 /etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置.所以如果你有对/etc/pr ...

  3. 4-3 组件参数校验与非props特性

    本文参考脚本之家,https://www.jb51.net/article/143466.htm 通过属性的形式,父组件对子组件进行参数的传递 //如下图: //父组件设置content属性,向属性中 ...

  4. The EntityFramework package is not installed on project

    VS2015 使用EF的code first 报错 Get-Package : 找不到与参数名称“ProjectName”匹配的参数.所在位置 packages\EntityFramework.6.1 ...

  5. Docker学习之1—基础及安装

    Docker介绍: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制 ...

  6. app 性能

    Android App优化之性能分析工具 https://www.jianshu.com/p/da2a4bfcba68 -------------- 系列文: 背景:Android App优化, 要怎 ...

  7. Go pprof性能监控

    Go net/http/pprof包提供了一个在WEB项目中使用的性能监控的工具, 使用时只需要引用包: _"net/http/pprof" 然后就可以在浏览器中访问地址: htt ...

  8. apache用户认证访问机制(转)

    Apache服务器已经内置用户验证机制,大家只要适当的加以设置,便可以控制网站的某些部分要用户验证.前期准备,必须已经安装apache,如果还没安装,或者对安装很模糊的话,第1步:我们在/var/ww ...

  9. MySQL高可用之组复制技术(2):配置单主模型的组复制

    MySQL组复制系列文章: MySQL组复制大纲 MySQL组复制(1):组复制技术简介 MySQL组复制(2):配置单主模型的组复制 MySQL组复制(3):配置多主模型的组复制 MySQL组复制( ...

  10. Perl语法的基本规则

    因为是比较凌乱的用法规则收集,所以能看懂则看,不能看懂也无所谓.以后也会遇到. Perl脚本第一行使用#!.Perl的后缀名一般为".plx"或".pl",运行 ...