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

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

难点:git

        1.画板的写法github

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

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

 

思路:app

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

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

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

 

方案:学习

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

DrawingView.java里的这个接口:

 

[java] view plain copy

 在CODE上查看代码片派生到个人代码片

  1. /** 
  2.     * 绘制代理,通知状态变动和获取数据 
  3.     */  
  4.    public interface DrawingStepDelegate {  
  5.        /** 
  6.         * 当前绘制step建立时回调,一般用于远程同步 
  7.         * step处于变化状态 
  8.         * 
  9.         * @param drawingView 当前view 
  10.         * @param step        当前绘制step,任意修改此step可能致使错误 
  11.         */  
  12.        void onDrawingStepBegin(DrawingView drawingView, DrawingStep step);  
  13.   
  14.        /** 
  15.         * 当前绘制step变动时回调,每次touch绘制都会执行,text图层修改内容也会执行,此回调执行频繁,一般用于远程同步 
  16.         * step处于变化状态 
  17.         * 
  18.         * @param drawingView 当前view 
  19.         * @param step        当前绘制step,任意修改此step可能致使错误 
  20.         */  
  21.        void onDrawingStepChange(DrawingView drawingView, DrawingStep step);  
  22.   
  23.        /** 
  24.         * 当前绘制状态已改变,绘制一笔或进行撤销/重作/清空等变动记录数据的操做都会触发此回调 
  25.         * step已经完成 
  26.         * 
  27.         * @param drawingView 当前view 
  28.         * @param step        当前绘制step,任意修改此step可能致使错误 
  29.         */  
  30.        void onDrawingStepEnd(DrawingView drawingView, DrawingStep step);  
  31.   
  32.        /** 
  33.         * 当前step撤销 
  34.         * 
  35.         * @param drawingView 当前view 
  36.         * @param step        当前绘制step,任意修改此step可能致使错误 
  37.         */  
  38.        void onDrawingStepCancel(DrawingView drawingView, DrawingStep step);  
  39.    }  
  40. 很明显,当我在DrawingView上绘图时会触发这个接口里的四个方法,我想这里就应该是我想要的坐标数据,我只要推送这些数据就好了,那么问题来了,如今我推送只能推送json数据,接收的时候再转成我想要的类,那么DrawingStep如何才能变json呢,点到DrawingStep类里你就回恍然大悟,才会发现此人早就替你想好这一点。原来这个类自己就是个json解析类。他的思路应该是这样的,绘画的时候每一步记录坐标(JSon数据)——解析成DrawingStep——而后drawingView根据DrawingStep绘制,DrawingData存放DrawingStep的集合。既然它是个解析Json的类,那么天然有类转JSon的方法

     

     

    [java] view plain copy

     在CODE上查看代码片派生到个人代码片

  41. /** 
  42.  * 复制step 
  43.  * @return 复制的step 
  44.  */  
  45. public DrawingStep copy() {  
  46.     return new Json<>(this.getClass()).modelFromJson(this.toJson());  
  47. }  

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

  1. dv.setDrawingStepDelegate(new DrawingView.DrawingStepDelegate() {  
  2.            @Override  
  3.            public void onDrawingStepBegin(DrawingView drawingView, DrawingStep step) {  
  4.   
  5.                //drawingView.getDrawingData().addDrawingStep(step);  
  6.                Logger.i("画板操做onDrawingStepBegin::"+step.toJson().toString());  
  7.                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");  
  8.                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));  
  9.   
  10.   
  11.   
  12.            }  
  13.   
  14.            @Override  
  15.            public void onDrawingStepChange(DrawingView drawingView, DrawingStep step) {  
  16.                Logger.i("画板操做onDrawingStepChange::"+step.toJson().toString());  
  17.                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");  
  18.                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));  
  19.            }  
  20.   
  21.            @Override  
  22.            public void onDrawingStepEnd(DrawingView drawingView, DrawingStep step) {  
  23.                Logger.i("画板操做onDrawingStepEnd::"+step.toJson().toString());  
  24.   
  25.                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");  
  26.                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));  
  27.            }  
  28.   
  29.  @Override  
  30.            public void onDrawingStepCancel(DrawingView drawingView, DrawingStep step) {  
  31.                Logger.i("画板操做onDrawingStepCancel::"+step.toJson().toString());  
  32.   
  33.                SendOrderBean sendOrderBean=new SendOrderBean("userSendPositionRequest",JSON.toJSONString(new UserSendPositionRequest("4450187",step.toJson().toString())),System.currentTimeMillis()+"");  
  34.   
  35.                singleSocket.sendMessage(JSON.toJSONString(sendOrderBean));  
  36.            }  
  37.        });  

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

     

     

    [java] view plain copy

     在CODE上查看代码片派生到个人代码片

  39. /** 
  40.      * 在当前绘制基础上增长绘制传入的step,若是传入的step与当前未完成的step是同一step(编号相同,远程同步step可能有未完成和已完成两种状态),更新当前step 
  41.      * 
  42.      * @param step 将要绘制的step 
  43.      */  
  44.     public void drawNextStep(@NonNull DrawingStep step) {  
  45.         step.setRemote(true);  
  46.         if (step.getStep() != getCurrentDrawingStep().getStep()) {  
  47.             endUnfinishedStep();  
  48.             getDrawingData().addDrawingStep(step);  
  49.         } else {  
  50.             getDrawingData().replaceDrawingStep(step);  
  51.         }  
  52.   
  53.         if (step.isCanceled()) {  
  54.             internalCancelCurrentStep();  
  55.             getDrawingData().cancelDrawingStep();  
  56.         } else {  
  57.             internalUpdateCurrentStep(false);  
  58.         }  
  59.  }  
  60.   
  61.     /** 
  62.      * 在当前绘制基础上增长绘制传入的step,此step必须是stepOver状态 
  63.      * 在远程同步绘制时,采用低频同步,仅在每一步绘制完成后同步时调用此方法 
  64.      * 不可与{@link #drawNextStep(DrawingStep)}同时使用 
  65.      * 
  66.      * @param step 将要绘制的step 
  67.      */  
  68.     public void drawNextOverStep(@NonNull DrawingStep step) {  
  69.         if (!step.isStepOver()) {  
  70.             return;  
  71.         }  
  72.   
  73.         getDrawingData().addDrawingStep(step);  
  74.   
  75.         if (step.isCanceled()) {  
  76.             return;  
  77.         }  
  78.   
  79.         internalUpdateCurrentStep(true);  
  80.     }  
  81. 那么接下来就是soeasy了:

     

     

    [java] view plain copy

     在CODE上查看代码片派生到个人代码片

  82.  private void initBroadCastReceiver() {  
  83.   
  84.         IntentFilter filter = new IntentFilter();  
  85.         filter.addAction("SOCKET_MESSAGE");  
  86.         if (receiver==null){  
  87.             receiver=new BroadcastReceiver() {  
  88.                 @Override  
  89.                 public void onReceive(Context context, Intent intent) {  
  90.   
  91.                     if (intent.getAction().equals("SOCKET_MESSAGE")) {  
  92.   
  93.   
  94.                         Bundle data = intent.getBundleExtra("data");  
  95.                         String msg = data.getString("message", "none");  
  96.                         Log.i("服务器返回信息::", msg);  
  97.   
  98.                         try {  
  99.                             ReceiveOrderBean receiveOrderBean = JSON.parseObject(msg, ReceiveOrderBean.class);  
  100.   
  101.                             switch (receiveOrderBean.getType()) {  
  102.   case "userSendPositionReceive":  
  103.                                     Toast.makeText(TestActivity.this,"获取到坐标数据",Toast.LENGTH_SHORT).show();  
  104.                                    // Logger.i("获取到坐标数据"+receiveOrderBean.getData());  
  105.                                     DrawingStep drawingStep = new Json<>(DrawingStep.class).modelFromJsonString(receiveOrderBean.getData());  
  106.   
  107.                                     Logger.i("获取到坐标数据"+drawingStep.toJson().toString());  
  108.   
  109.                                     dv.drawNextStep(drawingStep);  
  110.                                     dv.drawNextOverStep(drawingStep);  
  111. //                                    dv.getDrawingData().addDrawingStep(drawingStep);  
  112. //                                    dv.refreshWithDrawingData(dv.getDrawingData());  
  113.                                     break;  
  114.                             }  
  115.   
  116.                         } catch (com.alibaba.fastjson.JSONException ex) {  
  117.                             Log.i("命令解析出错", msg + "");  
  118.   
  119.                         }  
  120.   
  121.                     }  
  122.   
  123.                 }  
  124.             };  
  125.             App.localBroadcastManager.registerReceiver(receiver, filter);  
  126.         }  
  127.     }  

  128. 附页:学生端应该是看老师端操做,本身不能操做,因此要设置:

     

     

    [java] view plain copy

     在CODE上查看代码片派生到个人代码片

  129. dv.setDisableTouchDraw(true);//true是设置不能画,false反之  
  130. 问题:已丢包的形式传递一些命令数据好像是能够,好比开关机之类的,但若是要实现相似于直播,屏幕的彻底监控好像有点力不从心,可能与流媒体有关,这也是我须要不断学习的地方。
相关文章
相关标签/搜索