Android实时绘制效果(二)
16lz
2022-05-16
Android实时绘制效果(一)
2 )绘制部分 修改的ApiDemos的FingerPaint例子。有ClientView和ServerView,而父类BaseView放置共用的东西,也保证绘制效果一致。 2.1)BaseView.java2.2)ClientView.java
- publicclassBaseViewextendsView{
- protectedOnExitedListenerlistener;
- publicinterfaceOnExitedListener{
- voidonExited(Viewv);
- }
- protectedPaintmPaint;
- protectedBitmapmBitmap;
- protectedCanvasmCanvas;
- protectedPathmPath;
- protectedPaintmBitmapPaint;
- protectedstaticfinalStringKEY_INFO="info";
- protectedfinalHandlermHandler=newHandler(){
- @Override
- publicvoidhandleMessage(Messagemsg){
- Stringinfo=msg.getData().getString(KEY_INFO);
- Toast.makeText(getContext(),info,Toast.LENGTH_SHORT).show();
- }
- };
- publicBaseView(Contextcontext,intwidth,intheight){
- super(context);
- mPaint=newPaint();//创建线条画笔
- mPaint.setAntiAlias(true);//设置抗锯齿
- mPaint.setDither(true);//设置递色
- mPaint.setColor(0xFFFF0000);//设置画笔颜色
- mPaint.setStyle(Paint.Style.STROKE);//设置画笔类型
- mPaint.setStrokeJoin(Paint.Join.ROUND);//默认MITER
- mPaint.setStrokeCap(Paint.Cap.ROUND);//默认BUTT
- mPaint.setStrokeWidth(12);//设置描边宽度
- mBitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);//创建bitmap对象
- mCanvas=newCanvas(mBitmap);//嵌入Canvas
- mPath=newPath();//创建画笔路径
- mBitmapPaint=newPaint(Paint.DITHER_FLAG);//创建图像画笔
- /*设置获得焦点,以触发onKeyDown*/
- requestFocus();
- setFocusableInTouchMode(true);
- }
- protectedvoidtoastMessage(Stringinfo){
- Messagemsg=mHandler.obtainMessage();
- Bundledata=newBundle();
- data.putString(KEY_INFO,info);
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
- publicvoidonBackPressed(){
- }
- @Override
- publicbooleanonKeyDown(intkeyCode,KeyEventevent){
- if(keyCode==KeyEvent.KEYCODE_BACK&&event.getRepeatCount()==0){
- onBackPressed();
- }
- returnsuper.onKeyDown(keyCode,event);
- }
- publicvoidsetOnExitedListener(OnExitedListenerlistener){
- this.listener=listener;
- }
- }
2.3)ServerView.java
- publicclassClientViewextendsBaseViewimplementsOnClientListener{
- privateEasyClientmEasyClient;
- privatebooleanhasStart=false;
- privateDisplaymDisplay;
- privatefloatwRatio=1f,hRatio=1f;//屏幕缩放比
- privateRunnablemRunnable=newRunnable(){
- @Override
- publicvoidrun(){
- Toast.makeText(getContext(),"已过5秒,网络不通畅?",Toast.LENGTH_LONG)
- .show();
- }
- };
- publicClientView(Contextcontext,Stringhost,intport,Displaydisplay){
- super(context,display.getWidth(),display.getHeight());
- mDisplay=display;
- mEasyClient=newEasyClient(host,port,10000);
- mEasyClient.setOnClientListener(this);
- mEasyClient.start();
- mHandler.postDelayed(mRunnable,5000);
- }
- @Override
- publicvoidonBackPressed(){
- mEasyClient.sendMessage(EasyServer.EXIT_COMMAND);
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- canvas.drawColor(0xFFAAAAAA);
- canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);
- canvas.drawPath(mPath,mPaint);
- }
- privatefloatmX,mY;
- privatevoidtouch_start(floatx,floaty){
- hasStart=true;
- mPath.reset();
- mPath.moveTo(x,y);
- mX=x;
- mY=y;
- }
- privatevoidtouch_move(floatx,floaty){
- if(hasStart){
- mPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
- mX=x;
- mY=y;
- }else{
- touch_start(x,y);
- }
- }
- privatevoidtouch_up(floatx,floaty){
- hasStart=false;
- //mPath.lineTo(mX,mY);
- mPath.lineTo(x,y);
- //committhepathtoouroffscreen
- mCanvas.drawPath(mPath,mPaint);
- //killthissowedon'tdoubledraw
- mPath.reset();
- }
- @Override
- publicvoidonConnectException(){
- mHandler.removeCallbacks(mRunnable);
- toastMessage("连接不到服务器!");
- if(null!=listener){
- listener.onExited(this);
- }
- }
- @Override
- publicvoidonTimeoutException(){
- mHandler.removeCallbacks(mRunnable);
- toastMessage("连接服务器超时!");
- if(null!=listener){
- listener.onExited(this);
- }
- }
- @Override
- publicvoidonSocketException(){
- mHandler.removeCallbacks(mRunnable);
- toastMessage("通信异常!");
- if(null!=listener){
- listener.onExited(this);
- }
- }
- @Override
- publicvoidonConnected(){
- mHandler.removeCallbacks(mRunnable);
- toastMessage("连接上了服务器!");
- }
- @Override
- publicvoidonReceive(Stringmsg){
- Objectobj=JsonUtil.jsonToObj(msg);
- if(objinstanceofScreenInfo){
- ScreenInfoinfo=(ScreenInfo)obj;
- wRatio=((float)mDisplay.getWidth())/info.getWidth();
- hRatio=((float)mDisplay.getHeight())/info.getHeight();
- }elseif(objinstanceofPonitInfo){
- PonitInfoinfo=(PonitInfo)obj;
- floatx=wRatio*info.getX();
- floaty=hRatio*info.getY();
- switch(info.getState()){
- case0:
- touch_start(x,y);
- postInvalidate();
- break;
- case1:
- touch_move(x,y);
- postInvalidate();
- break;
- case2:
- touch_up(x,y);
- postInvalidate();
- break;
- }
- }
- }
- @Override
- publicvoidonExited(){
- toastMessage("客户端退出了!");
- if(null!=listener){
- listener.onExited(this);
- }
- }
- }
四、后记 1、NIO Socket通信还不是很熟悉,所以还是Socket了。至于多线程和NIO效率在各情况下孰优孰劣不清楚。而长连接是为了实时。 2、客户端连接以Socket集合来记录,在n多时会有什么什么。算了,现Demo不面临这种风险~ 3、现在的通信消息太复杂了,没必要这样的。 可以多拿几个设备测试玩玩^^
- publicclassServerViewextendsBaseViewimplementsOnServerListener{
- privateEasyServermEasyServer;
- privateDisplaymDisplay;
- publicServerView(Contextcontext,intport,Displaydisplay){
- super(context,display.getWidth(),display.getHeight());
- mDisplay=display;
- /*开启服务*/
- mEasyServer=newEasyServer(port);
- mEasyServer.setOnServerListener(this);
- mEasyServer.start();
- }
- @Override
- publicvoidonBackPressed(){
- mEasyServer.sendMessage(EasyServer.EXIT_COMMAND);
- /*返回至前页面时,端口仍被占用。可以在这里杀死相关进程,以避免端口占用。*/
- if(null!=listener){
- listener.onExited(this);
- }
- }
- @Override
- protectedvoidonDraw(Canvascanvas){
- canvas.drawColor(0xFFAAAAAA);
- canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);
- canvas.drawPath(mPath,mPaint);
- }
- privatefloatmX,mY;
- privatestaticfinalfloatTOUCH_TOLERANCE=4;
- privatevoidtouch_start(floatx,floaty){
- mEasyServer.sendMessage(JsonUtil.objToJson(newPonitInfo(x,y,0)));
- mPath.reset();
- mPath.moveTo(x,y);
- mX=x;
- mY=y;
- }
- privatevoidtouch_move(floatx,floaty){
- floatdx=Math.abs(x-mX);
- floatdy=Math.abs(y-mY);
- if(dx>=TOUCH_TOLERANCE||dy>=TOUCH_TOLERANCE){
- mEasyServer.sendMessage(JsonUtil.objToJson(newPonitInfo(x,y,1)));
- mPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
- mX=x;
- mY=y;
- }
- }
- privatevoidtouch_up(){
- mEasyServer.sendMessage(JsonUtil.objToJson(newPonitInfo(mX,mY,2)));
- mPath.lineTo(mX,mY);
- //committhepathtoouroffscreen
- mCanvas.drawPath(mPath,mPaint);
- //killthissowedon'tdoubledraw
- mPath.reset();
- }
- @Override
- publicbooleanonTouchEvent(MotionEventevent){
- floatx=event.getX();
- floaty=event.getY();
- switch(event.getAction()){
- caseMotionEvent.ACTION_DOWN:
- touch_start(x,y);
- invalidate();
- break;
- caseMotionEvent.ACTION_MOVE:
- touch_move(x,y);
- invalidate();
- break;
- caseMotionEvent.ACTION_UP:
- touch_up();
- invalidate();
- break;
- }
- returntrue;
- }
- @Override
- publicvoidonBindException(){
- toastMessage("端口占用了,请关闭应用后重开!");
- }
- @Override
- publicvoidonSocketException(InetAddressip){
- toastMessage(ip+"异常退出!");
- }
- @Override
- publicvoidonClientConnected(InetAddressip){
- toastMessage(ip+"建立了连接!");
- /*发送ScreenInfo信息*/
- mEasyServer.sendMessage(JsonUtil.objToJson(newScreenInfo(mDisplay
- .getWidth(),mDisplay.getHeight())));
- }
- @Override
- publicvoidonReceive(InetAddressip,Stringmsg){
- /*接收客户端消息*/
- }
- @Override
- publicvoidonExited(InetAddressip){
- toastMessage(ip+"正常退出!");
- }
- }
更多相关文章
- Android实现为GridView添加边框效果
- Android中Dialog的使用
- Android(安卓)中文API (70) —— BluetoothDevice[蓝牙]
- Android(安卓)打开设置的各个页面
- Android权限设置android.permission完整列表
- 设备驱动-----Android关机流程总结
- Android(安卓)中文设置成粗体的方法
- 【Android學習專題】實用參考:android权限大全
- EditText属性描述