Android 模拟一个电子画板同屏的效果

Android电子白板 视频会议电子白板 Android电子白板   实现了功能。服务器传送和转发没放:废话不说直接贴代码了 MainActitvty.java(主类) package com.ubi.whitebord; import comm.ubi.util.DashPoint; import comm.ubi.util.Point; import comm.ubi.util.PointData; import an 阅读详情

年初的时候刚把去年底的一个电子书包的项目完结了,这不刚过了几天又收到了boss新的需求:添加一个电子白板,要求老师端绘画的时候,学生端的屏幕也能看到老师端的操作。

难点:

        1.画板的写法

         2.如何推送数据到学生端,该推送什么格式的数据

         3.学生端收到数据该如何绘制。


思路:

         1.画板的写法ok,网上一大堆

         2.老师端绘制的时候,绘制的每一个操作,又都横纵坐标记录,我只要推送这些记录给学生端,让学生端再根据             坐标绘制

         3.依然采取1.0的方案,客户端用socket(tcp)服务器端用(walkman)方式推送数据(已解决)


方案:

         1.画板采用github上星星最多的AndroidDrawingView,前人种树好乘凉,我的建议是最好下载源码自己先看一遍他的思路,当然这里我早就发现这个demo完全契合我的项目。这个demo竟然已经为你扩展了如何实现同屏。请看

DrawingView.java里的这个接口:

 /**
     * 绘制代理,通知状态变更和获取数据
     */
    public interface DrawingStepDelegate {
        /**
         * 当前绘制step创建时回调,通常用于远程同步
         * step处于变化状态
         *
         * @param drawingView 当前view
         * @param step        当前绘制step,任意修改此step可能导致错误
         */
        void onDrawingStepBegin(DrawingView drawingView, DrawingStep step);

        /**
         * 当前绘制step变更时回调,每次touch绘制都会执行,text图层修改内容也会执行,此回调执行频繁,通常用于远程同步
         * step处于变化状态
         *
         * @param drawingView 当前view
         * @param step        当前绘制step,任意修改此step可能导致错误
         */
        void onDrawingStepChange(DrawingView drawingView, DrawingStep step);

        /**
         * 当前绘制状态已改变,绘制一笔或进行撤销/重做/清空等变更记录数据的操作都会触发此回调
         * step已经完成
         *
         * @param drawingView 当前view
         * @param step        当前绘制step,任意修改此step可能导致错误
         */
        void onDrawingStepEnd(DrawingView drawingView, DrawingStep step);

        /**
         * 当前step撤销
         *
         * @param drawingView 当前view
         * @param step        当前绘制step,任意修改此step可能导致错误
         */
        void onDrawingStepCancel(DrawingView drawingView, DrawingStep step);
    }

很明显,当我在DrawingView上绘图时会触发这个接口里的四个方法,我想这里就应该是我想要的坐标数据,我只要推送这些数据就行了,那么问题来了,现在我推送只能推送json数据,接收的时候再转成我想要的类,那么DrawingStep如何才能变json呢,点到DrawingStep类里你就回恍然大悟,才会发现此人早就替你想好这一点。原来这个类本身就是个json解析类。他的思路应该是这样的,绘画的时候每一步记录坐标(JSon数据)——解析成DrawingStep——然后drawingView根据DrawingStep绘制,DrawingData存放DrawingStep的集合。既然它是个解析Json的类,那么自然有类转JSon的方法


    /**
     * 复制step
     * @return 复制的step
     */
    public DrawingStep copy() {
        return new Json<>(this.getClass()).modelFromJson(this.toJson());
    }

那么现在就差与服务器约定 命令的请求头,将这坐标数据发送出去

 dv.setDrawingStepDelegate(new DrawingView.DrawingStepDelegate() {
            @Override
            public void onDrawingStepBegin(DrawingView drawingView, DrawingStep step) {

                //drawingView.getDrawingData().addDrawingStep(step);
                Logger.i("画板操作onDrawingStepBegin::"+step.toJson().toString());
                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");
                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));



            }

            @Override
            public void onDrawingStepChange(DrawingView drawingView, DrawingStep step) {
                Logger.i("画板操作onDrawingStepChange::"+step.toJson().toString());
                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");
                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));
            }

            @Override
            public void onDrawingStepEnd(DrawingView drawingView, DrawingStep step) {
                Logger.i("画板操作onDrawingStepEnd::"+step.toJson().toString());

                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");
                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));
            }

            @Override
            public void onDrawingStepCancel(DrawingView drawingView, DrawingStep step) {
                Logger.i("画板操作onDrawingStepCancel::"+step.toJson().toString());

                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");

                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));
            }
        });

数据发送出去了,学生端该接受数据:那么问题又来了,画板该如何跟据坐标绘制呢,让我们看drawingView里的方法:

/**
     * 在当前绘制基础上增加绘制传入的step,如果传入的step与当前未完成的step是同一step(编号相同,远程同步step可能有未完成和已完成两种状态),更新当前step
     *
     * @param step 将要绘制的step
     */
    public void drawNextStep(@NonNull DrawingStep step) {
        step.setRemote(true);
        if (step.getStep() != getCurrentDrawingStep().getStep()) {
            endUnfinishedStep();
            getDrawingData().addDrawingStep(step);
        } else {
            getDrawingData().replaceDrawingStep(step);
        }

        if (step.isCanceled()) {
            internalCancelCurrentStep();
            getDrawingData().cancelDrawingStep();
        } else {
            internalUpdateCurrentStep(false);
        }
    }

    /**
     * 在当前绘制基础上增加绘制传入的step,此step必须是stepOver状态
     * 在远程同步绘制时,采用低频同步,仅在每一步绘制完成后同步时调用此方法
     * 不可与{@link #drawNextStep(DrawingStep)}同时使用
     *
     * @param step 将要绘制的step
     */
    public void drawNextOverStep(@NonNull DrawingStep step) {
        if (!step.isStepOver()) {
            return;
        }

        getDrawingData().addDrawingStep(step);

        if (step.isCanceled()) {
            return;
        }

        internalUpdateCurrentStep(true);
    }
那么接下来就是soeasy了:

 private void initBroadCastReceiver() {

        IntentFilter filter = new IntentFilter();
        filter.addAction("SOCKET_MESSAGE");
        if (receiver==null){
            receiver=new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {

                    if (intent.getAction().equals("SOCKET_MESSAGE")) {


                        Bundle data = intent.getBundleExtra("data");
                        String msg = data.getString("message", "none");
                        Log.i("服务器返回信息::", msg);

                        try {
                            ReceiveOrderBean receiveOrderBean = JSON.parseObject(msg, ReceiveOrderBean.class);

                            switch (receiveOrderBean.getType()) {
                                case "userSendPositionReceive":
                                    Toast.makeText(TestActivity.this,"获取到坐标数据",Toast.LENGTH_SHORT).show();
                                   // Logger.i("获取到坐标数据"+receiveOrderBean.getData());
                                    DrawingStep drawingStep = new Json<>(DrawingStep.class).modelFromJsonString(receiveOrderBean.getData());

                                    Logger.i("获取到坐标数据"+drawingStep.toJson().toString());

                                    dv.drawNextStep(drawingStep);
                                    dv.drawNextOverStep(drawingStep);
//                                    dv.getDrawingData().addDrawingStep(drawingStep);
//                                    dv.refreshWithDrawingData(dv.getDrawingData());
                                    break;
                            }

                        } catch (com.alibaba.fastjson.JSONException ex) {
                            Log.i("命令解析出错", msg + "");

                        }

                    }

                }
            };
            App.localBroadcastManager.registerReceiver(receiver, filter);
        }
    }

附页:学生端应该是看老师端操作,自己不能操作,所以要设置:

   dv.setDisableTouchDraw(true);//true是设置不能画,false反之

问题:已丢包的形式传递一些命令数据好像是可以,比如开关机之类的,但如果要实现类似于直播,屏幕的完全监控好像有点力不从心,可能与流媒体有关,这也是我需要不断学习的地方。










  



Android端与PC端同步绘画板(二)-适配手机和PC屏幕大小 前言关于手机端与PC端如何建立通讯,请参考: Android端与PC端同步绘画板(一)-使用Socket建立连接 这篇文章我们来简单说一下关于手机端和PC端的屏幕适配问题,因为我们都知道因为Android碎片化问题,屏幕适配一直是个难题,所以android和pc之间画板也是需要屏幕适配的,否则会造成一系列问题;问题 从上图我们可以看到假如手机端为全屏绘制,屏幕的分辨率为1280*720,可绘制 阅读详情

相关推荐

微信小程序横屏手写签名组件开发:Canvas API、横屏适配与性能优化实战

Canvas作为前端图形渲染的核心技术,通过其2D绘图上下文API,开发者能够在网页或小程序中实现丰富的交互式图形绘制。其原理在于利用JavaScript操作像素网格,实时响应触摸事件,将坐标轨迹转化为矢量路径进行渲染。这一技术对于构建需要原生交互体验的应用具有重要价值,尤其在电子签名、绘图白板、数据可视化等场景中不可或缺。本文聚焦于微信小程序环境下的Canvas深度应用,针对【横屏适配】与【性能优化】两大挑战,详细解析了如何从零构建一个高可用的手写签名组件,涵盖了从触摸事件处理、坐标转换、离屏渲染到图片导

weixin_34163553的博客 348

(转)Android电子白板实现,Canvas画布

前一阵子做了一个项目,里面有用到画板,在手机上画图,类似一个电子白板,画出曲线,圆,矩形。。 后来查了资料,看了些大神的博客 单独优化出了一个小程序,在原来基础上新增了橡皮檫功能,画出的图形可以是曲线,直线,矩形,正方形,圆,椭圆,也可以筛选相册图片显示到画板, 画图的同时更改画笔的颜色 基本思路是在画板上确认两个点,一个起点,一个终点,根据选择的图形样式,拖动的时候有预览图形,松...

weixin_34297704的博客 934

从一句祝福到一个表达系统:情人节项目化实践指南

在数字化时代,个性化表达与用户体验设计已成为内容创作和情感连接的核心。其原理在于通过系统性的策划与执行,将单向的信息传递升级为多维的互动体验,从而显著提升沟通的深度与温度。这一实践不仅具有情感价值,在项目管理、创意工具应用和自动化流程方面也体现了技术价值。它广泛应用于节日祝福、品牌营销、团队建设等需要增强互动与记忆点的场景。本文以情人节祝福为例,深入探讨如何运用个性化(Personalization)和媒介创新(Medium Innovation)等热词理念,结合轻量级技术工具,构建一套从策划到落地的完整表

weixin_34413103的博客 364

手持弹幕高级版 利用手机模拟LED显示屏、LED跑马灯 非常有趣实用的APP

摘要:手持弹幕高级版是一款趣味性强的手机应用,能将屏幕模拟成LED显示屏或跑马灯,适用于粉丝应援、接机约会、店铺促销等场景。该应用操作简单,提供多种动画特效,可自定义文字颜色和速度,已解锁高级会员功能。同类软件还有LED屏幕秀等,均为免费实用工具。下载链接已提供。

2601_96656352的博客 189

电容式触摸屏原理与架构解析:从自互电容到In-Cell技术

触摸交互是人机交互的核心技术之一,其基础原理在于通过传感器感知用户输入。电容式触摸屏作为主流技术,主要基于自电容和互电容两种传感模式工作。自电容通过检测电极对地电容变化实现单点触控,而互电容通过测量交叉电极间的耦合电容变化,支持真正的多点触控,这是现代智能设备流畅交互的技术基础。从技术价值看,触摸系统实现了从物理按压到电子感应的演进,大幅提升了交互的自然性和效率。在实际应用场景中,触摸技术已广泛应用于智能手机、平板电脑、工业控制面板等领域。本文聚焦于触摸系统的完整架构,深入探讨了从传感器、触摸控制器到驱动软

weixin_33778544的博客 489

Android 白板应用开发实战:WhiteBoard 源码解析与实践

Android白板应用是一个集成了多种交互式绘图和实时协作功能的平台,它为用户提供了一个自由绘制和共享创意的空间。在数字化和远程协作日益成为主流的今天,这种应用显得尤为重要。本章将为您概述Android白板应用的基本特点、应用场景以及其在现代教育和商业会议中的重要性。Android白板应用允许用户在平板电脑或智能手机上绘制草图、图形和文本,能够即时分享给其他设备或用户。应用通常包括以下基本功能:基本绘图工具:提供各种画笔、颜色和图形工具供用户绘制。共享与同步。

weixin_35752233的博客 610

推荐:极致体验的手写签字控件——带笔锋效果的Android神器

推荐:极致体验的手写签字控件——带笔锋效果的Android神器 去发现同类优质开源项目:https://gitcode.com/ 在这个数字化的时代,手写签名的功能在许多应用程序中显得尤为重要,无论是电子合同还是在线订单,都需要用户的亲笔确认。为此,我们很高兴地向您推荐一个专为Android平台设计的开源项目——一个功能强大的、带有逼真笔锋效果的手写签字控件。 项目介绍 该项目提供了一个原生的An...

gitblog_00052的博客 1094

Android 画板(白板)源码 涂鸦 画图 图画

非常好的android画图源码,可以绘制线段、直线、矩形、圆,可以插入图片、更换背景、还可以将画图保持成图片。

乙巳马年春联生成终端实操手册:多终端适配(PC/Pad/触控大屏)

本文介绍了如何在星图GPU平台上自动化部署“乙巳马年·皇城大门春联生成终端W”镜像,实现多终端适配的AI春联创作。该应用基于强大的文心模型,用户只需输入关键词,即可在PC、平板或触控大屏上快速生成具有皇家美学风格的个性化春联,适用于家庭新年仪式、企业互动营销等场景。

weixin_30978239的博客 389

完整的安卓画板源代码 Android小画板

实现了画板的各种功能,网上找的,共享了。

电子白板源代码

供学习和项目开发借鉴使用.代码结构非常清晰,易懂

vivo Pad5e深度评测:2000元价位如何打造极致学习平板体验

在移动计算领域,硬件性能与软件生态的协同优化是提升用户体验的核心。其原理在于通过精准的硬件选型与深度的系统定制,将有限资源聚焦于特定场景,从而实现高效能输出。这一技术路径的价值在于,它能够为预算敏感且需求明确的用户群体提供高度匹配的解决方案,尤其在教育、轻办公等垂直场景中意义显著。应用场景广泛覆盖了在线学习、文档处理与知识管理等环节,要求设备在屏幕素质、续航能力和交互效率上具备突出表现。本文聚焦的vivo Pad5e,正是这一理念的实践典范,其搭载的**学习空间**功能与**原子笔记**应用,共同构建了一个

weixin_30879833的博客 433

android 白板实现

使用了pdfviewer的pdf显示控件,并且在上一层实现了一个bitmap,可以进行绘图,实现了在pdf上进行标记的功能,并且可以换颜色,调标记的笔迹的粗细。

5 个关键点:IsaacLab 中配置 UR10e 与 Robotiq 2F-85 夹爪的完整指南

在 IsaacLab 里首次跑 UR10e + Robotiq 2F-85 时,最常见的翻车姿势是:夹爪复位后僵在某个半开姿态、两根手指收合不同步、或者 episode 刚开始手臂就明显下垂。问题通常不在资产没加载,而在联动关节(mimic joints,即一个驱动关节机械带动其他关节的耦合结构)和驱动参数没按夹爪机械结构配置。本文以框架内置的 UR10e + 2F-85 为例,讲清楚 5 步如何

gitblog_00406的博客 498

android 电子白板

根据手势画出滑动轨迹、只是一个demo,还需要完善,可以用来学习Android开发,需要的朋友可以下载

WhiteBoard_电子白板_

屏幕的电子白板,屏幕的捕获,可以对可显示的窗口进行捕获。

零代码开发移动应用:MIT App Inventor可视化编程完全指南

你是否曾想过开发自己的手机应用,却被复杂的编程语言和开发环境吓退?或者作为教育工作者,想要在课堂上引入编程教学却找不到合适的工具?MIT App Inventor正是为解决这些问题而生的开源可视化编程平台——它让你无需编写一行代码,就能创建功能完整的Android和iOS应用!🎉 想象一下,你的学生可以在几小时内制作出自己的第一个应用,创业者可以在几天内完成产品原型,而这一切都不需要计算机科学

gitblog_00683的博客 422

IIR数字滤波器原理,设计方法及嵌入式应用

基于STM32的二阶直接II型巴特沃斯低通滤波器设计方法及应用

weixin_38342580的博客 1万+
上一篇: android 广播的知识积累
下一篇: Android 积累一些JNI与NDK的知识
泡温泉的咸鱼
博客等级 码龄11年 39粉丝 48原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值