首页 > 其他分享 >安卓-SurfaceView

安卓-SurfaceView

时间:2023-01-05 09:11:31浏览次数:38  
标签:canvas mPaint int 安卓 SurfaceView void context public

一、SurfaceView是View的孪生兄弟

View通过刷新来重绘视图,安卓系统通过发出VSYNC信号来进行屏幕重绘,刷新间隔是16ms。如果一次重绘耗时太长超过16ms会出现警告的log告诉你主线程可能做太多事情

SurfaceView的刷新是被动的,我们让他刷新的时候才执行刷新操作。并且SurfaceView使用了双缓冲而View没有

 

二、SurfaceView的使用

SurfaceView可以使用模板进行编写,这里做了一个模板如下所示

public abstract class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    public SurfaceViewTemplate(Context context) {
        super(context);
        initView(context);
    }

    public SurfaceViewTemplate(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(context);
    }

    protected SurfaceHolder mHolder;
    protected void initView(Context context) {
        mHolder = getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
        setKeepScreenOn(true);
        setFocusableInTouchMode(true);
    }

    boolean mIsDrawing;
    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        mIsDrawing = true;
        new Thread(this).start(); // 开线程出来进行绘制操作
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        mIsDrawing = false;
    }

    private final long DRAW_DURATION = 50;
    @Override
    public void run() {
        while (mIsDrawing) {
            long startTime = System.currentTimeMillis();
            drawSurface();
            long endTime = System.currentTimeMillis();
            if (endTime - startTime < DRAW_DURATION) { // 让drawSurface每50毫秒刷一次,低于50毫秒则通过sleep把资源让出来
                try {
                    Thread.sleep(DRAW_DURATION - (endTime - startTime));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void drawSurface() {
        Canvas canvas = null;
        try {
            canvas = mHolder.lockCanvas(); // 获取画布,并在该画布上面进行绘制
            if (canvas != null) {
                drawSurface(canvas);
            }
        } catch (Exception e) {

        } finally {
            if (canvas != null) {
                mHolder.unlockCanvasAndPost(canvas); // 将画布的内容进行提交
            }
        }
    }

    /**
     * 让子类实现该方法来执行绘图操作
     * */
    protected abstract void drawSurface(Canvas canvas);
}

 

三、使用二模板实现一个动态绘制正弦图的例子

    private Path mPath;
    private Paint mPaint;
    @Override
    protected void initView(Context context) { // 继承父类的initView进行初始化
        super.initView(context);

        mPath = new Path();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(10);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        mPath.moveTo(0, 400);
        super.surfaceCreated(holder);
    }

    private int x = 0;
    private int y = 0;
    @Override
    protected void drawSurface(Canvas canvas) { // 继承父类的drawSurface进行绘制想要的图
        canvas.drawColor(Color.WHITE);
        canvas.drawPath(mPath, mPaint);

        x += 1;
        y = (int) (100 * Math.sin(x * Math.PI / 180) + 400);
        mPath.lineTo(x, y);
    }

 

标签:canvas,mPaint,int,安卓,SurfaceView,void,context,public
From: https://www.cnblogs.com/czwlinux/p/17026550.html

相关文章

  • 安卓app上架流程
    ​上传APP的时候,遇到了问题,一直卡在AuthenticatingwiththeiTunesstore提示这里,​解决办法:在ApplicationLoader里面登录需要上传APP的开发者帐号就可以了​证书我们这边......
  • unity+高德定位=pokemon go 山寨demo安卓版
    这两周尝试了下用高德地理定位和Unity来做个山寨的pokemongo的demo,只能在安卓下使用。游戏过程视频:​​http://www.bilibili.com/video/av6836823/​​场景一这里是获取......
  • 安卓APP上架腾讯应用宝
    目录总览:一、搜索腾讯开放平台,选择应用开放平台二、注册账号,创建应用三、完善基本信息四、上架分发 一、注册腾讯开放平台,选择应用开放平台1.1搜索腾讯开放平......
  • 【安卓】Qt for Android开发环境搭建
    安装Qt略(参考网上的安装Qt即可,暂时不考虑其他组件)安装jdk17下载1.8版本网上推荐使用JDK1.8,而不是其他版本,不建议使用最新版。下载1.8JavaDownloads|Oracle设置环......
  • 安卓 RecyclerView的导入方式 标准方式!
    安卓RecyclerView的导入方式标准方式! RecyclerView是安卓开发中最常用的一个UI控件没有之一,下面介绍一种官方的导入方式  第一步点击:ProjectStructurestep......
  • 初识安卓系统​
    1安卓系统​1.1安卓系统简介​安卓系统(Android)是一种由Google公司和开放手机联盟领导及开发的操作系统,主要用于移动设备,如智能手机和平板电脑。它是基于开放源代码的Lin......
  • 记录tpt-the powder toy 安卓原版编译
    修改coross-exp下的安卓配置文件原仓库文件下有安卓文件夹,打开他,目录下有coross文件夹内部有对应平台的的相关配置,复制粘贴到仓库根目录下的coross-exp下的安卓配置文件,......
  • 安卓-PorterDuffXfermode
    一、当我们要实现两张图片之间的混合模式的时候经常会用到PorterDuffXfermode二、使用方法mPaint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.DST_IN));在mPa......
  • R语言对git安卓包分类统计、聚类、复杂网络可视化分析
    我们曾经为一位客户进行了短暂的咨询工作,他正在构建一个主要基于安卓包分类的分析应用程序。数据源是安卓的项目,把同一类功能的安卓代码的头部,每一个文件都有import 包名......
  • 适合编程初学者的开源项目:小游戏2048(安卓版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。安卓版效果图技术特点安卓Kotlin工程截图开源地址https://gitee.com/lblbc/game_2048关于厦门......