1、创建一个名称为DrawView的类,继承android.view.View类
public class DrawView extends View{ private int view_width = 0; //屏幕的宽度 private int view_height = 0;//屏幕的高度 private float preX;//起始点的X坐标值 private float preY;//起始点的Y坐标值 private Path path;//路径 private Paint paint = null;//画笔 Bitmap cacheBitmap = null;//定义一个内存中的图片,该图片强作为缓冲区 Canvas cacheCanvas = null;//定义cacheBitmap上的Canvas对象 /** * 构造方法 * @param context */ public DrawView(Context context) { super(context); } /** * 重写onDraw()方法 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } }
2、布局文件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <com.example.android9_8.DrawView android:id="@+id/drawView1" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
view_width = context.getResources().getDisplayMetrics().widthPixels;//获取屏幕的宽度 view_height = context.getResources().getDisplayMetrics().heightPixels;//获取屏幕的高度 //创建一个与该View相同大小的缓存区 cacheBitmap = Bitmap.createBitmap(view_width, view_height, Config.ARGB_8888); cacheCanvas = new Canvas();//创建一个新的画布 path = new Path(); cacheCanvas.setBitmap(cacheBitmap);//在cacheCanvas上绘制cacheBitmap paint = new Paint(Paint.DITHER_FLAG); paint.setColor(Color.RED);//设置默认的画笔颜色 //设置画笔风格 paint.setStyle(Paint.Style.STROKE);//设置填充方式为描边 paint.setStrokeCap(Paint.Cap.ROUND);//设置笔刷的图形样式 paint.setStrokeCap(Paint.Cap.ROUND);//设置画笔转弯处的链接风格 paint.setStrokeWidth(1);//设置默认笔触的宽度为1像素 paint.setAntiAlias(true);//使用抗锯齿功能 paint.setDither(true);//使用抖动效果
canvas.drawColor(0xFFFFFFFF);//设置背景颜色 Paint bmpPaint = new Paint();//采用默认设置创建一个画笔 canvas.drawBitmap(cacheBitmap, 0, 0,bmpPaint);//绘制cacheBitmap canvas.drawPath(path, paint);//绘制路径 canvas.save(Canvas.ALL_SAVE_FLAG);//保存canvas的状态 canvas.restore();//恢复canvas之前保存的状态,防止保存后对canvas执行的操作对后续的绘制有影响
public boolean onTouchEvent(MotionEvent event) { //获取触摸事件发生的位置 float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: path.moveTo(x, y);//将绘图的起始点移到(x,y)坐标点的位置 preX = x; preY = y; break; case MotionEvent.ACTION_MOVE: float dx = Math.abs(x-preX); float dy = Math.abs(y-preY); if(dx>=5||dy>=5){//判断是否在允许的范围内 path.quadTo(preX, preY, (x+preX)/2, (y+preY)/2); preX = x; preY = y; } break; case MotionEvent.ACTION_UP: cacheCanvas.drawPath(path, paint);//绘制路径 path.reset(); break; } invalidate(); return true;//返回true,表明处理方法已经处理该事件 }
public void clear(){ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));//设置图形重叠时的处理方式 paint.setStrokeWidth(50);//设置笔触的宽度 }
public void save(){ try { saveBitmap("myPicture"); } catch (IOException e) { e.printStackTrace(); } }
//保存绘制好的位图 public void saveBitmap(String fileName) throws IOException{ File file = new File("/sdcard/pictures/"+fileName+".png");//创建文件对象 file.createNewFile();//创建一个新文件 FileOutputStream fileOS = new FileOutputStream(file);//创建一个文件输出流对象 //将绘图内容压缩为PNG格式输出到输出流对象中 cacheBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOS); fileOS.flush();//将缓冲区中的数据全部写出到输出流 fileOS.close();//关闭文件输出流对象 }
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:title="@string/color"> <menu > <!-- 定义一组单选菜单项 --> <group android:checkableBehavior="single" > <!-- 定义子菜单 --> <item android:id="@+id/red" android:title="@string/color_red"/> <item android:id="@+id/green" android:title="@string/color_green"/> <item android:id="@+id/blue" android:title="@string/color_blue"/> </group> </menu> </item> <item android:title="@string/width"> <menu > <!-- 定义子菜单 --> <group> <item android:id="@+id/width_1" android:title="@string/width_1"/> <item android:id="@+id/width_2" android:title="@string/width_2"/> <item android:id="@+id/width_3" android:title="@string/width_3"/> </group> </menu> </item> <item android:id="@+id/clear" android:title="@string/clear"/> <item android:id="@+id/save" android:title="@string/save"/> </menu>
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">简易涂鸭板</string> <string name="width_1">1像素</string> <string name="width_2">5像素</string> <string name="width_3">10像素</string> <string name="color_red">红色</string> <string name="color_green">绿色</string> <string name="color_blue">蓝色</string> <string name="color">画笔颜色</string> <string name="width">画笔宽度</string> <string name="clear">擦除绘画</string> <string name="save">保存绘画</string> </resources>
//创建选项菜单 @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflator = new MenuInflater(this);//实例化一个MenuInf inflator.inflate(R.menu.toolsmenu, menu);//解析菜单文件 return super.onCreateOptionsMenu(menu); }
// 当菜单项被选择时,作出相应的处理 @Override public boolean onOptionsItemSelected(MenuItem item) { DrawView dv = (DrawView) findViewById(R.id.drawView1); //获取自定义的绘图视图 dv.paint.setXfermode(null); //取消擦除效果 dv.paint.setStrokeWidth(1); //初始化画笔的宽度 switch (item.getItemId()) { case R.id.red: dv.paint.setColor(Color.RED); //设置画笔的颜色为红色 item.setChecked(true); break; case R.id.green: dv.paint.setColor(Color.GREEN); //设置画笔的颜色为绿色 item.setChecked(true); break; case R.id.blue: dv.paint.setColor(Color.BLUE); //设置画笔的颜色为蓝色 item.setChecked(true); break; case R.id.width_1: dv.paint.setStrokeWidth(1); //设置笔触的宽度为1像素 break; case R.id.width_2: dv.paint.setStrokeWidth(5); //设置笔触的宽度为5像素 break; case R.id.width_3: dv.paint.setStrokeWidth(10);//设置笔触的宽度为10像素 break; case R.id.clear: dv.clear(); //擦除绘画 break; case R.id.save: dv.save(); //保存绘画 break; } return true; }