实现简单的写字板

最近在做一个项目,有一个要求就是在手机客户端上记录用户的笔迹,然后发往服务端进行笔记认证。于是就写了一个简单的绘图板,记录用户的笔迹及笔记经过的坐标值。网络连接代码暂时还没加上去。以下是代码:注释很详细的,相信大家能看懂,并希望能提出改进,谢谢!
主来,即要运行的Activity
  1. package snowfox.android;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.PrintStream;
  7. import android.app.Activity;
  8. import android.graphics.Bitmap;
  9. import android.os.Bundle;
  10. import android.view.View;
  11. import android.view.View.OnClickListener;
  12. import android.widget.Button;
  13. public class SimpleWrite extends Activity implements OnClickListener{
  14.     /** Called when the activity is first created. */
  15.         Button ok,cancer;
  16.         MyView mv;
  17.         Bitmap bitmap;
  18.         
  19.     @Override
  20.     public void onCreate(Bundle savedInstanceState) {
  21.         super.onCreate(savedInstanceState);
  22.         setContentView(R.layout.simple_write);
  23.         mv = (MyView)findViewById(R.id.MyView);
  24.         mv.setDrawingCacheEnabled(true);
  25.         ok = (Button)findViewById(R.id.buttonOk);
  26.         cancer = (Button)findViewById(R.id.buttonCancer);
  27.         ok.setOnClickListener(this);
  28.         cancer.setOnClickListener(this);
  29.     }
  30.    
  31.         public void onClick(View v) {
  32.                 // TODO Auto-generated method stub
  33.                 switch(v.getId())
  34.                 {
  35.                         case R.id.buttonOk:
  36.                         {
  37.                                 /*
  38.                                  * 将Android的Bitmap对象保存成为一个文件,该类只有compress(Bitmap.CompressFormat format, int quality, OutputStream stream),
  39.                                  * 可以存为png和jpg,png可能还好说,但是jpg是有损压缩会降低图片的质量,其实Google还提供了一个API在Bitmap类,通过
  40.                                  * copyPixelsToBuffer(Buffer dst)这个方法来解决
  41.                                  */
  42.                                 //此处对图片质量要求不高,可以直接用前一种方法.
  43.                                 bitmap = mv.getDrawingCache();        //获得绘图板上的bitmap资源
  44.                                 
  45.                                 //新建文件以保存图片,文件名为系统当前时间
  46.                                 File imageFile = new File("/sdcard",System.currentTimeMillis() + ".png");        //若把文件保存到sdcard,须在配置文件中添加sd卡读写权限
  47.                                 try
  48.                                 {
  49.                                         FileOutputStream fos = new FileOutputStream(imageFile);                //获取文件的输出流
  50.                                         bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);                //将bitmap的内容输出到文件输出流
  51.                                         fos.flush();        //刷新输出流,将输出流中数据输入文件
  52.                                         fos.close();        
  53.                                 }
  54.                                 catch (FileNotFoundException e)
  55.                                 {
  56.                                         // TODO Auto-generated catch block
  57.                                         e.printStackTrace();
  58.                                 }
  59.                                 catch (IOException e)
  60.                                 {
  61.                                         // TODO Auto-generated catch block
  62.                                         e.printStackTrace();
  63.                                 }
  64.                                 mv.destroyDrawingCache();        //关掉缓冲区,以使相关无用的对象内存能被回收
  65.                                 
  66.                                 //以下为轨迹记录代码
  67.                                 int array[][][] = mv.cordinate;
  68.                                 //清空画板,并回收内存,在此处清空画板是因为上面已经把坐标信息记录下来了,因此之前画板的相关信息已不需要,可以清除
  69.                                 mv.initBiamap();
  70.                                 System.gc();
  71.                                 File cordinateFile = new File("/sdcard",System.currentTimeMillis() + ".txt");
  72.                                 try
  73.                                 {
  74.                                         PrintStream fps = new PrintStream(cordinateFile);
  75.                                        
  76.                                         for(int i = 0; i < 15; i++)
  77.                                         {
  78.                                                 for(int j = 0; j < 30; j++)
  79.                                                 {
  80.                                                         fps.print(array[i][j][0]+" ");
  81.                                                         fps.print(array[i][j][1]+" ");
  82.                                                         fps.print("\t\t");
  83.                                                         fps.flush();
  84.                                                 }
  85.                                                 fps.print("\r\n");
  86.                                                 fps.flush();
  87.                                         }
  88.                                         fps.close();
  89.                                 }
  90.                                 catch (FileNotFoundException e) {
  91.                                         // TODO Auto-generated catch block
  92.                                         e.printStackTrace();
  93.                                 }
  94.                                 break;
  95.                         }
  96.                         case R.id.buttonCancer:
  97.                         {
  98.                                 //此处将界面返回为初始状
  99.                                 mv.initBiamap();        //重新初始化mv组件,使其成为空白画板
  100.                                 System.gc();
  101.                                 break;
  102.                         }
  103.                         default:
  104.                                 break;
  105.                 }
  106.         }
  107. }
复制代码
定制组件:MyView:
  1. package snowfox.android;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.CornerPathEffect;
  7. import android.graphics.Paint;
  8. import android.graphics.Path;
  9. import android.graphics.PathEffect;
  10. import android.util.AttributeSet;
  11. import android.util.Log;
  12. import android.view.GestureDetector;
  13. import android.view.MotionEvent;
  14. import android.view.View;
  15. import android.view.GestureDetector.OnGestureListener;
  16. import android.view.View.OnTouchListener;
  17. import android.widget.Toast;
  18. public class MyView extends View implements OnTouchListener,OnGestureListener
  19. {
  20.         int touchNum, pressNum;                                        //笔画坐标数, 笔画数
  21.         int[][][] cordinate;                                        //存储坐标的数组
  22.         public Paint paint;
  23.         public Path path;
  24.         private PathEffect effect;
  25.         Bitmap myBitmap;
  26.         GestureDetector testGestureDetector;
  27.         Canvas canvas;
  28.         public MyView(Context context, AttributeSet attrs)
  29.         {
  30.                 super(context, attrs);
  31.                 // TODO Auto-generated constructor stub
  32.                 this.initBiamap();
  33.                 this.setOnTouchListener(this);
  34.                 this.setLongClickable(true);                //只有设置了此项,才能监听手势
  35.         }
  36.         public void initBiamap()
  37.         {
  38.                 touchNum = 0;
  39.                 pressNum = 0;
  40.                 cordinate = new int[20][100][2];        //最大笔画数20, 最大笔画坐标数100
  41.                 canvas = new Canvas();
  42.                 paint = new Paint();
  43.                 path = new Path();
  44.                 paint.setColor(Color.BLUE);                        
  45.                 paint.setStyle(Paint.Style.STROKE);               
  46.                 paint.setStrokeWidth(3);
  47.                 paint.setAntiAlias(true);                        //打开抗锯齿
  48.                 effect = new CornerPathEffect(10);                //打开圆角效果
  49.                 testGestureDetector = new GestureDetector(this);
  50.         }
  51.         @Override
  52.         protected void onDraw(Canvas canvas)
  53.         {
  54.                 super.onDraw(canvas);
  55.                 paint.setAntiAlias(true);
  56.                
  57.                 paint.setPathEffect(effect);
  58.                 canvas.drawPath(path, paint);
  59.                 invalidate();                                        //刷新组件,以显示当前效果
  60.                 return;
  61.         }
  62.         public boolean onTouch(View v, MotionEvent event)
  63.         {
  64.                
  65.                 // TODO Auto-generated method stub
  66.                 //获取笔画坐标
  67.                 float x= event.getX();
  68.                 float y = event.getY();
  69.                 Log.i("xy===========", x + " " + y+ "==================");
  70.                 cordinate[pressNum][touchNum][0] = (int)x;
  71.                 cordinate[pressNum][touchNum][1] = (int)y;
  72.                
  73.                 if(touchNum == 0)                        //当touchNum = 0时,则为一个笔画的起点,因此将path起点移动到此点
  74.                         path.moveTo(x,y);
  75.                 else
  76.                         path.lineTo(x,y);
  77.                 touchNum++;
  78.                 //Log.i("touchNum=====", touchNum + " ");
  79.                 //Log.i("PressNum++++++++++++", pressNum + " ");
  80.                 if(touchNum == 99)                        //笔画过长时,停止输入,并要求重新输入
  81.                 {
  82.                         Toast.makeText(this.getContext(), "笔画过于复杂,请重新输入", Toast.LENGTH_LONG).show();
  83.                         this.initBiamap();
  84.                 }
  85.                 if(pressNum == 19)                        //笔画过多时,停止输入,并要求重新输入
  86.                 {
  87.                         Toast.makeText(this.getContext(), "笔画过于复杂,请重新输入", Toast.LENGTH_LONG).show();
  88.                         this.initBiamap();
  89.                 }
  90.                 if((event.getAction()) == (MotionEvent.ACTION_UP))                //手指离开屏幕时,则下一笔为新笔画起点,因此相关数据置0
  91.                 {
  92.                         touchNum = 0;
  93.                         pressNum ++;
  94.                 }
  95.         
  96.                 return testGestureDetector.onTouchEvent(event);
  97.         }
  98.         public boolean onDown(MotionEvent e) {
  99.                 // TODO Auto-generated method stub
  100.                 return false;
  101.         }
  102.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)
  103.         {
  104.                 // TODO Auto-generated method stub
  105.                 //n++;
  106.                 //touchNum = 0;
  107.                 //onDraw(canvas)
  108.                 return false;
  109.         }
  110.         public void onLongPress(MotionEvent e) {
  111.                 // TODO Auto-generated method stub
  112.                
  113.         }
  114.         public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
  115.                         float distanceY) {
  116.                 // TODO Auto-generated method stub
  117.                 return false;
  118.         }
  119.         public void onShowPress(MotionEvent e) {
  120.                 // TODO Auto-generated method stub
  121.         }
  122.         public boolean onSingleTapUp(MotionEvent e) {
  123.                 // TODO Auto-generated method stub
  124.                 return false;
  125.         }
  126. }
复制代码
布局文件:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:orientation="vertical"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="fill_parent"
  6.     android:background = "#c0c0c0"
  7.     >
  8.         <snowfox.android.MyView
  9.             android:layout_width = "wrap_content"
  10.             android:layout_height = "wrap_content"
  11.             android:id = "@+id/MyView"
  12.             android:layout_weight = "12"
  13.             android:background = "#ffffff"
  14.         />
  15.         <RelativeLayout
  16.             android:layout_width = "fill_parent"
  17.             android:layout_height = "wrap_content"
  18.             android:layout_gravity="bottom"
  19.             android:layout_weight = "1">
  20.             <Button
  21.             android:id = "@+id/buttonOk"
  22.             android:layout_width = "wrap_content"
  23.             android:layout_height = "wrap_content"
  24.             android:text = "确定"
  25.             android:layout_alignParentLeft = "true"
  26.             />
  27.             <Button
  28.             android:id = "@+id/buttonCancer"
  29.             android:layout_width = "wrap_content"
  30.             android:layout_height = "wrap_content"
  31.             android:text = "取消"
  32.             android:layout_alignParentRight = "true"
  33.             />
  34.         </RelativeLayout>
  35. </LinearLayout>
复制代码
原文地址:https://www.cnblogs.com/shuiyun/p/2730149.html