SurfaceView绘制动态直线

Ubuntu22.04+Docker一键部署Autoware Universe避坑指南(附鱼香ROS配置) 本文详细介绍了在Ubuntu22.04系统中使用Docker一键部署Autoware Universe的完整流程,包括鱼香ROS工具链配置、Docker环境优化及VSCode开发环境集成。通过实战指南帮助开发者快速搭建自动驾驶开发环境,解决常见部署问题,提升开发效率。 阅读详情

   

使用SurfaceView关键在于下面的3个回调方法。
当(SurfaceHolder.addCallback()成功时调用public void surfaceCreated(SurfaceHolder holder);
当SurfaceView的状态发生变化时调用public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) ;
当SurfaceView被销毁时调用public void surfaceDestroyed(SurfaceHolder holder) ;

1、xml文件如下,SurfaceView控件的使用,有2两种方法,一种是在xml中定义id,并在Activity中初始化(例如本文),另一种是自定义SurfaceView控件,在xml文件中之间引入类文件。


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SurfaceViewActivity">

    <ImageView
        android:id="@+id/sfv_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/henu"/>

    <SurfaceView
        android:id="@+id/sfv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal">

        <Button
            android:id="@+id/stop"
            android:gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:text="停止"/>
        
        <Button
            android:id="@+id/start"
            android:gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:text="开始"/>

    </LinearLayout>
</RelativeLayout>

2、SurfaceViewActivity.java文件

package ltd.ruiaixinan.test;
import android.graphics.PixelFormat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class SurfaceViewActivity extends AppCompatActivity {

    private SurfaceView surfaceView = null;
    private Button start = null;
    private Button stop = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_surface_view);

        this.surfaceView = this.findViewById(R.id.sfv);
        this.start = this.findViewById(R.id.start);
        this.stop = this.findViewById(R.id.stop);

        // 设置常亮
        this.surfaceView.setKeepScreenOn(true);

        // 设置surfaceView背景透明
        this.surfaceView.setZOrderOnTop(true);
        this.surfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

        // 调用SurfaceView
        final SurfaceViewModel model = new SurfaceViewModel(this, this.surfaceView);


        this.start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(SurfaceViewActivity.this,"开始绘画", Toast.LENGTH_SHORT).show();
                model.start();
            }
        });

        this.stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(SurfaceViewActivity.this,"停止绘画", Toast.LENGTH_SHORT).show();
                model.stop();
            }
        });

    }
}

3、SurfaceViewModel.java文件
package ltd.ruiaixinan.test;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SurfaceViewModel extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    private Canvas canvas = null;
    private Paint paint = null;
    private SurfaceHolder surfaceHolder = null;
    private int refreshInterval = 2000;
    private volatile boolean isDrawing = false;
    private Thread thread = null;

    public SurfaceViewModel(Context context, SurfaceView surfaceView) {
        super(context);

        // 初始化画笔
        this.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        this.paint.setColor(Color.RED);
        this.paint.setStrokeWidth(6);

        this.surfaceHolder = surfaceView.getHolder();
        // 触发回调函数
        this.surfaceHolder.addCallback(this);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d("----------", "surfaceCreated success");

        this.canvas = this.surfaceHolder.lockCanvas();
        // 清空canvas
        this.canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
        this.surfaceHolder.unlockCanvasAndPost(this.canvas);

        // 调用线程,对应下文相应的run()方法
        this.thread = new Thread(this);
        thread.start();

        // 设置绘图中
        this.isDrawing = true;

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.d("----------", "surfaceChanged success");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d("----------", "surfaceDestroyed success");
    }

    @Override
    public void run() {
        try {
            while (true) {
                if(this.isDrawing) {
                    Log.d("***", "run");
                    // Start time
                    long startTime = System.currentTimeMillis();

                    // The lock of thread
                    synchronized (this.surfaceHolder) {
                        this.canvas = this.surfaceHolder.lockCanvas();
                        // 设置canvas透明度
                        this.canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                        Log.d("-------", "drawECG_good_start");

                        this.drawECG((int) (1 + Math.random() * 400));
                        Log.d("-------", "drawECG_good_end");

                        this.surfaceHolder.unlockCanvasAndPost(this.canvas);
                    }
                    // 设置结束时间
                    long endTime = System.currentTimeMillis();
                    // 计算间期
                    int intervalTime = (int) (endTime - startTime);
                    // 确保间期相同
                    while (intervalTime <= this.refreshInterval) {
                        intervalTime = (int) (System.currentTimeMillis() - startTime);
                        // Thread wait
                        Thread.yield();
                    }
                }else {
                    Thread.yield();
                }
            }
        }finally {
            if(this.canvas != null){
                // 解锁
                this.surfaceHolder.unlockCanvasAndPost(this.canvas);
            }
        }
    }

    // Draw
    private boolean drawECG(int x){
        this.canvas.drawLine(x+10,x+10,x+100,x+100,this.paint);
        return true;
    }

    // 启动绘画
    public boolean start(){
        this.isDrawing = true;
        return true;
    }
    // 停止绘画
    public boolean stop(){
        Log.d("***","stop");
        this.isDrawing = false;
        return true;
    }

}

ESP32S3与ILI9341 LCD屏LVGL移植实战:从零构建嵌入式GUI界面 本文详细介绍了如何在ESP32S3平台上移植LVGL图形库并驱动ILI9341 LCD屏幕,从硬件选型、开发环境配置到显示驱动实现和内存优化。通过实战案例讲解移植过程中的关键步骤和常见问题解决方案,帮助开发者快速构建嵌入式GUI界面。 阅读详情

相关推荐

C# 进阶:打造WinForms中的动态交互式UserControl

本文深入探讨了如何在C# WinForms中创建动态交互式UserControl,以提升桌面应用的用户体验和代码复用性。通过剖析UserControl生命周期、事件体系,并结合一个可拖拽缩放的分割面板实战案例,详细讲解了鼠标键盘事件处理、自定义绘制、状态管理以及性能优化等核心技巧,帮助开发者封装复杂交互逻辑,打造专业级自定义控件。

weixin_29279153的博客 462

Android利用SurfaceView画坐标轴上的波形

  最近的一个Android项目中,需要在特定坐标轴上绘制一个数据波形(虚拟仪器之类),并且需要在不同分辨率的设备上保持波形上数据点的个数以及与坐标轴的一致性。   思路如下:   1、首先采用SurfaceView进行绘图操作,SurfaceView是View的继承类,绘图的效率较高。具体的使用方法是自定义视图类继承SurfaceView并实现SurfaceHolder.Callback接口...

weixin_30608503的博客 353

【项目实战】YOLOV5 +实时吸烟目标检测+手把手教学+开源全部

本原创项目长期更新,旨在完成校园异常行为实时精检测,做到集成+N次开发+优化(不止局限于调包)为止,近期将不断更新以下模型+数据+标注文件+教程。关注博主,Star 一下github,一起开始美妙的目标检测之路吧~~ 文章目录本原创项目长期更新,旨在完成校园异常行为实时精检测,做到集成+N次开发+优化(不止局限于调包)为止,近期将不断更新以下模型+数据+标注文件+教程。关注博主,Star 一下github,一起开始美妙的目标检测之路吧~~一、项目展示二、项目资源共享1:训练图片:香烟图片+吸烟手势+烟雾三、

cv君的博客 13万+

Android学习2: Android使用SurfaceView绘制一条移动的线段

今天 学习了一下, 怎样使用 SurfaceView. SurfaceHolder, Canvas 和 Paint 来绘制一条移动的线段 例子, 都是我从网上找的, 只不过是自已简化了一些, 改掉了一些过时的代码.都不是原创的, 只不过能明白原理就好 这个例子在运行时, 还有内存泄露.我怀疑是在 执行SimpleDraw() 函数的时候产生的. 不过现在还没法改. 定时器再次启动时

迎风的舵手 3821

使用modelscope加载报错:ImportError: cannot import name ‘AutoTokenizer’ from ‘modelscope’...如何解决?| 提供多种解决方案

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1243

Python地理数据处理 十七:植被物候提取和分析(Savitzky-Golay)

植被是陆地生态系统中最重要的组分之一,也是对气候变化最敏感的组分,其在全球变化过程中起着重要作用,能够指示自然环境中的大气、水、土壤等成分的变化,其年际和季节性变化可以作为地球气候变化的重要指标。此外,由于生态工程保护建设和植被自然生长等因素,中国陆地生态系统发挥了重要的碳汇作用。因此,定量评估植被时空动态变化是制定生态系统可持续发展目标和衡量生态系统固碳潜力的重要前提,卫星遥感数据衍生的生态参量产品为研究长时间序列全球及区域植被时空变化提供了重要数据源。SG滤波能够对物候信息进行平滑,并提取其中的物候信息

amyniez的博客,欢迎交流讨论 4247

surfaceView简单使用,绘制正弦线

class SurfaceViewTest :SurfaceView,SurfaceHolder.Callback,Runnable{ constructor(context:Context):super(context) constructor(context: Context,attrs:AttributeSet):super(context,attrs) constructor(context: Context,attrs: AttributeSet,defStyleAt

m0_37588684的博客 207

【Bug已解决】Codex App returns 401 Missing bearer/basic authentication after login on multiple Windows la

原始报错:Codex App returns 401 Missing bearer/basic authentication after login on multiple Windows laptops场景:用户在 Windows 笔记本上登录应用成功了,但随后每个业务请求都返回 401,提示"Missing bearer/basic authentication"。登录态像是"假的"——明明登了,请求却没带任何认证信息。多台 Windows 设备都能复现。

一键难忘的博客 595

SurfaceView画板操作

SurfaceView画板操作画板——画路径画板——画动态直线 画板——画路径 package com.example.review.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; ...

weixin_45697390的博客 409

无法将“choco”项识别为 cmdlet、函数、脚本文件或可运行程序的名称的解决方案

本文主要介绍了无法将“choco”项识别为 cmdlet、函数、脚本文件或可运行程序的名称的解决方案,希望能对使用wIndows的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 12万+

数据分析:蛋白质组的GO term的富集分析详解

在获取差异表达蛋白质的数据之后,依据蛋白质与基因的对应映射关系,开展GO(Gene Ontology)term的富集分析。通过这一分析流程,能够精准地识别出不同实验组中过表达基因所关联的显著富集的GO term通路。这些富集的GO term通路为后续的生物学研究提供了关键线索,有助于深入探究基因功能、揭示潜在的生物学机制,从而推动生物学发现的进程。

专注生信领域 1368

[学习笔记]用户界面优化之Android SurfaceView的使用

1、了解SurfaceView 与View的区别2、SurfaceView实践 绘制多个图形 1)创建工程SurfaceViewLearn new一个类MyView.javaMainActivity.javaimport android.support.v7.app.AppCompatActivity; import android.os.Bundle;public class Ma

神是念着倒 707

华为OD机考双机位C卷 - 手机App防沉迷系统(Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 手机App防沉迷系统(OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 2061

Andriod在摄像头预览的场景下,动态绘制直线

1、首先,绘制直线的数据是从客户端传送过来的,接受后更新SvDraw /*定义一个画矩形框的类*/ public class SvDraw extends SurfaceView implements SurfaceHolder.Callback{     SurfaceHolder sh;     private int mWidth;     private int mHei

yangxueping89的专栏 759

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

android飞机游戏敌机移动路径是什么样的

基础android的飞机类游戏,与前人一样,由surfaceView绘制游戏画面,另起线程控制绘制时间间隔达到动态效果。这里附上最近自己写的敌机自动飞行路径代码。请大家给点意见。 在敌机管理模块,加入此段代碼。movePingXing记录该飞机直线轨迹运行时,每次canvas绘制的x、y的偏量值。moveYuanHu记录该飞机按圆形轨迹运行时,每次canvas绘制的x、y的偏量值。Str...

jishublog 287

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android中Path类的lineTo方法和quadTo方法画线的区别

        当我们需要在屏幕上形成画线时,Path类的应用是必不可少的,而Path类的lineTo和quadTo方法实现的绘制线路形式也是不一样的,下面就以代码的实现来直观的探究这两个方法的功能实现区别;    1. Path--->quadTo(float x1, float y1, float x2, float y2):      该方法的实现是当我们不仅仅是画一条线甚

dongsheng186的专栏 434

Android Path lineTo和quadTo画线的区别

转至:http://blog.youkuaiyun.com/stevenhu_223/article/details/9229337    当我们需要在屏幕上形成画线时,Path类的应用是必不可少的,而Path类的lineTo和quadTo方法实现的绘制线路形式也是不一样的,下面就以代码的实现来直观的探究这两个方法的功能实现区别;    1. Path--->quadTo(float x1, floa

h183288132的专栏 813

安卓画板

Android中Path类的lineTo方法和quadTo方法画线的区别   当我们需要在屏幕上形成画线时,Path类的应用是必不可少的,而Path类的lineTo和quadTo方法实现的绘制线路形式也是不一样的,下面就以代码的实现来直观的探究这两个方法的功能实现区别;    1. Path--->quadTo(float x1, float y1, float x2, f

qq_25815655的博客 597

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

1.背景介绍   最近项目要绘制股票走势图,并绘制能够跟随手指滑动的指示线(Indicator)来精确查看股票价格和日期。如下图所示:   上图中的那条白色直线就是股票的指示线,用来跟随手指精确确定股票的时间和股票价格。不论是绘制股票图还是绘制指示线,我们首先想到的就是用Android中的自定义View来实现。实践证明,使用View能够很好地实现静态的图片,但是对用动态图像的绘制,往往会出

一朶婲 2623

android surfaceview bitmap,Android使用SurfaceView绘制静态图像

使用 SurfaceView 绘图需要为 SurfaceView 对象添加 SurfaceHoloder.Callback 接口,并在该接口的 surfaceCreated() 方法中通过 lockCanvas() 方法获取 Canvas 对象,以此保证当获取 Canvas 时,SurfaceView 对象可用。当绘图工作完成后,通过 SurfaceHoloder.unlockCanvas-And...

weixin_30382087的博客 1668
上一篇: android蓝牙扫描(简单
下一篇: 蓝牙BLE设备连接与通信
MasonYyp
博客等级 码龄9年 301粉丝 297原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值