Android实时绘制效果(一)

2 )绘制部分 修改的ApiDemos的FingerPaint例子。有ClientView和ServerView,而父类BaseView放置共用的东西,也保证绘制效果一致。 2.1)BaseView.java
        
  1. publicclassBaseViewextendsView{
  2. protectedOnExitedListenerlistener;
  3. publicinterfaceOnExitedListener{
  4. voidonExited(Viewv);
  5. }
  6. protectedPaintmPaint;
  7. protectedBitmapmBitmap;
  8. protectedCanvasmCanvas;
  9. protectedPathmPath;
  10. protectedPaintmBitmapPaint;
  11. protectedstaticfinalStringKEY_INFO="info";
  12. protectedfinalHandlermHandler=newHandler(){
  13. @Override
  14. publicvoidhandleMessage(Messagemsg){
  15. Stringinfo=msg.getData().getString(KEY_INFO);
  16. Toast.makeText(getContext(),info,Toast.LENGTH_SHORT).show();
  17. }
  18. };
  19. publicBaseView(Contextcontext,intwidth,intheight){
  20. super(context);
  21. mPaint=newPaint();//创建线条画笔
  22. mPaint.setAntiAlias(true);//设置抗锯齿
  23. mPaint.setDither(true);//设置递色
  24. mPaint.setColor(0xFFFF0000);//设置画笔颜色
  25. mPaint.setStyle(Paint.Style.STROKE);//设置画笔类型
  26. mPaint.setStrokeJoin(Paint.Join.ROUND);//默认MITER
  27. mPaint.setStrokeCap(Paint.Cap.ROUND);//默认BUTT
  28. mPaint.setStrokeWidth(12);//设置描边宽度
  29. mBitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);//创建bitmap对象
  30. mCanvas=newCanvas(mBitmap);//嵌入Canvas
  31. mPath=newPath();//创建画笔路径
  32. mBitmapPaint=newPaint(Paint.DITHER_FLAG);//创建图像画笔
  33. /*设置获得焦点,以触发onKeyDown*/
  34. requestFocus();
  35. setFocusableInTouchMode(true);
  36. }
  37. protectedvoidtoastMessage(Stringinfo){
  38. Messagemsg=mHandler.obtainMessage();
  39. Bundledata=newBundle();
  40. data.putString(KEY_INFO,info);
  41. msg.setData(data);
  42. mHandler.sendMessage(msg);
  43. }
  44. publicvoidonBackPressed(){
  45. }
  46. @Override
  47. publicbooleanonKeyDown(intkeyCode,KeyEventevent){
  48. if(keyCode==KeyEvent.KEYCODE_BACK&&event.getRepeatCount()==0){
  49. onBackPressed();
  50. }
  51. returnsuper.onKeyDown(keyCode,event);
  52. }
  53. publicvoidsetOnExitedListener(OnExitedListenerlistener){
  54. this.listener=listener;
  55. }
  56. }
2.2)ClientView.java
        
  1. publicclassClientViewextendsBaseViewimplementsOnClientListener{
  2. privateEasyClientmEasyClient;
  3. privatebooleanhasStart=false;
  4. privateDisplaymDisplay;
  5. privatefloatwRatio=1f,hRatio=1f;//屏幕缩放比
  6. privateRunnablemRunnable=newRunnable(){
  7. @Override
  8. publicvoidrun(){
  9. Toast.makeText(getContext(),"已过5秒,网络不通畅?",Toast.LENGTH_LONG)
  10. .show();
  11. }
  12. };
  13. publicClientView(Contextcontext,Stringhost,intport,Displaydisplay){
  14. super(context,display.getWidth(),display.getHeight());
  15. mDisplay=display;
  16. mEasyClient=newEasyClient(host,port,10000);
  17. mEasyClient.setOnClientListener(this);
  18. mEasyClient.start();
  19. mHandler.postDelayed(mRunnable,5000);
  20. }
  21. @Override
  22. publicvoidonBackPressed(){
  23. mEasyClient.sendMessage(EasyServer.EXIT_COMMAND);
  24. }
  25. @Override
  26. protectedvoidonDraw(Canvascanvas){
  27. canvas.drawColor(0xFFAAAAAA);
  28. canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);
  29. canvas.drawPath(mPath,mPaint);
  30. }
  31. privatefloatmX,mY;
  32. privatevoidtouch_start(floatx,floaty){
  33. hasStart=true;
  34. mPath.reset();
  35. mPath.moveTo(x,y);
  36. mX=x;
  37. mY=y;
  38. }
  39. privatevoidtouch_move(floatx,floaty){
  40. if(hasStart){
  41. mPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
  42. mX=x;
  43. mY=y;
  44. }else{
  45. touch_start(x,y);
  46. }
  47. }
  48. privatevoidtouch_up(floatx,floaty){
  49. hasStart=false;
  50. //mPath.lineTo(mX,mY);
  51. mPath.lineTo(x,y);
  52. //committhepathtoouroffscreen
  53. mCanvas.drawPath(mPath,mPaint);
  54. //killthissowedon'tdoubledraw
  55. mPath.reset();
  56. }
  57. @Override
  58. publicvoidonConnectException(){
  59. mHandler.removeCallbacks(mRunnable);
  60. toastMessage("连接不到服务器!");
  61. if(null!=listener){
  62. listener.onExited(this);
  63. }
  64. }
  65. @Override
  66. publicvoidonTimeoutException(){
  67. mHandler.removeCallbacks(mRunnable);
  68. toastMessage("连接服务器超时!");
  69. if(null!=listener){
  70. listener.onExited(this);
  71. }
  72. }
  73. @Override
  74. publicvoidonSocketException(){
  75. mHandler.removeCallbacks(mRunnable);
  76. toastMessage("通信异常!");
  77. if(null!=listener){
  78. listener.onExited(this);
  79. }
  80. }
  81. @Override
  82. publicvoidonConnected(){
  83. mHandler.removeCallbacks(mRunnable);
  84. toastMessage("连接上了服务器!");
  85. }
  86. @Override
  87. publicvoidonReceive(Stringmsg){
  88. Objectobj=JsonUtil.jsonToObj(msg);
  89. if(objinstanceofScreenInfo){
  90. ScreenInfoinfo=(ScreenInfo)obj;
  91. wRatio=((float)mDisplay.getWidth())/info.getWidth();
  92. hRatio=((float)mDisplay.getHeight())/info.getHeight();
  93. }elseif(objinstanceofPonitInfo){
  94. PonitInfoinfo=(PonitInfo)obj;
  95. floatx=wRatio*info.getX();
  96. floaty=hRatio*info.getY();
  97. switch(info.getState()){
  98. case0:
  99. touch_start(x,y);
  100. postInvalidate();
  101. break;
  102. case1:
  103. touch_move(x,y);
  104. postInvalidate();
  105. break;
  106. case2:
  107. touch_up(x,y);
  108. postInvalidate();
  109. break;
  110. }
  111. }
  112. }
  113. @Override
  114. publicvoidonExited(){
  115. toastMessage("客户端退出了!");
  116. if(null!=listener){
  117. listener.onExited(this);
  118. }
  119. }
  120. }
2.3)ServerView.java
        
  1. publicclassServerViewextendsBaseViewimplementsOnServerListener{
  2. privateEasyServermEasyServer;
  3. privateDisplaymDisplay;
  4. publicServerView(Contextcontext,intport,Displaydisplay){
  5. super(context,display.getWidth(),display.getHeight());
  6. mDisplay=display;
  7. /*开启服务*/
  8. mEasyServer=newEasyServer(port);
  9. mEasyServer.setOnServerListener(this);
  10. mEasyServer.start();
  11. }
  12. @Override
  13. publicvoidonBackPressed(){
  14. mEasyServer.sendMessage(EasyServer.EXIT_COMMAND);
  15. /*返回至前页面时,端口仍被占用。可以在这里杀死相关进程,以避免端口占用。*/
  16. if(null!=listener){
  17. listener.onExited(this);
  18. }
  19. }
  20. @Override
  21. protectedvoidonDraw(Canvascanvas){
  22. canvas.drawColor(0xFFAAAAAA);
  23. canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);
  24. canvas.drawPath(mPath,mPaint);
  25. }
  26. privatefloatmX,mY;
  27. privatestaticfinalfloatTOUCH_TOLERANCE=4;
  28. privatevoidtouch_start(floatx,floaty){
  29. mEasyServer.sendMessage(JsonUtil.objToJson(newPonitInfo(x,y,0)));
  30. mPath.reset();
  31. mPath.moveTo(x,y);
  32. mX=x;
  33. mY=y;
  34. }
  35. privatevoidtouch_move(floatx,floaty){
  36. floatdx=Math.abs(x-mX);
  37. floatdy=Math.abs(y-mY);
  38. if(dx>=TOUCH_TOLERANCE||dy>=TOUCH_TOLERANCE){
  39. mEasyServer.sendMessage(JsonUtil.objToJson(newPonitInfo(x,y,1)));
  40. mPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
  41. mX=x;
  42. mY=y;
  43. }
  44. }
  45. privatevoidtouch_up(){
  46. mEasyServer.sendMessage(JsonUtil.objToJson(newPonitInfo(mX,mY,2)));
  47. mPath.lineTo(mX,mY);
  48. //committhepathtoouroffscreen
  49. mCanvas.drawPath(mPath,mPaint);
  50. //killthissowedon'tdoubledraw
  51. mPath.reset();
  52. }
  53. @Override
  54. publicbooleanonTouchEvent(MotionEventevent){
  55. floatx=event.getX();
  56. floaty=event.getY();
  57. switch(event.getAction()){
  58. caseMotionEvent.ACTION_DOWN:
  59. touch_start(x,y);
  60. invalidate();
  61. break;
  62. caseMotionEvent.ACTION_MOVE:
  63. touch_move(x,y);
  64. invalidate();
  65. break;
  66. caseMotionEvent.ACTION_UP:
  67. touch_up();
  68. invalidate();
  69. break;
  70. }
  71. returntrue;
  72. }
  73. @Override
  74. publicvoidonBindException(){
  75. toastMessage("端口占用了,请关闭应用后重开!");
  76. }
  77. @Override
  78. publicvoidonSocketException(InetAddressip){
  79. toastMessage(ip+"异常退出!");
  80. }
  81. @Override
  82. publicvoidonClientConnected(InetAddressip){
  83. toastMessage(ip+"建立了连接!");
  84. /*发送ScreenInfo信息*/
  85. mEasyServer.sendMessage(JsonUtil.objToJson(newScreenInfo(mDisplay
  86. .getWidth(),mDisplay.getHeight())));
  87. }
  88. @Override
  89. publicvoidonReceive(InetAddressip,Stringmsg){
  90. /*接收客户端消息*/
  91. }
  92. @Override
  93. publicvoidonExited(InetAddressip){
  94. toastMessage(ip+"正常退出!");
  95. }
  96. }
四、后记 1、NIO Socket通信还不是很熟悉,所以还是Socket了。至于多线程和NIO效率在各情况下孰优孰劣不清楚。而长连接是为了实时。 2、客户端连接以Socket集合来记录,在n多时会有什么什么。算了,现Demo不面临这种风险~ 3、现在的通信消息太复杂了,没必要这样的。 可以多拿几个设备测试玩玩^^

更多相关文章

  1. Android实现为GridView添加边框效果
  2. Android中Dialog的使用
  3. Android(安卓)中文API (70) —— BluetoothDevice[蓝牙]
  4. Android(安卓)打开设置的各个页面
  5. Android权限设置android.permission完整列表
  6. 设备驱动-----Android关机流程总结
  7. Android(安卓)中文设置成粗体的方法
  8. 【Android學習專題】實用參考:android权限大全
  9. EditText属性描述

随机推荐

  1. 阅读《Android(安卓)从入门到精通》(14)—
  2. Android(安卓)/ iOS 招聘
  3. Android:电话拨号器、呼叫记录、结束通话
  4. android字体闪烁动画(线程)
  5. android保存图片到图库
  6. Android(安卓)硬编码
  7. Android手机开发:SQLite数据库
  8. android application级别的图片缓存
  9. 在android 只取vold相关的log信息
  10. android 获取系统和SD卡音乐