用户每触摸一次屏幕。都会触发onTouchEvent方法。设置cacheCanvas把用户触摸时绘制的路径放到画纸cacheBitmap上。通过invalidate();方法的调用再次onDraw方法,Canvas把画纸cacheBitmap放到DrawView这个我们自己定义的View上。
用户每触摸一次屏幕都会运行一次这个操作。
(2)因为每次运行invalidate()方法。都会触发onDraw方法。因此初始化的工作应通通放在自己定义View的构造方法中以节省内存,这个问题在《【Android】利用自己定义View的重绘实现拖动移动,获取组件的尺寸》(点击打开链接)已经讲过了,这里不再赘述。构造方法,完毕画家(画布)Canvas与画笔Paint,画图路径Path的初始化。
关键是要把初始化之后的画纸cacheBitmap放到画家cacheCanvas手上,同一时候命令画家cacheCanvas把这张画纸cacheBitmap所有涂白,也就是说把绘图的背景颜色设置为白色。否则一会儿你保存出来的图像的背景色默认是黑色的。尽管你看到的自己定义View是白色的。
在画笔Paint初始化的事情,注意要把画笔设置为paint.setStyle(Paint.Style.STROKE);不过画边的方法,这样才干做到涂鸦的效果,否则画笔默认是,附件绘图画矩形那种拖泥带水的效果。
(3)触摸事件onTouchEvent里的作图方法这里反而没什么好说的。计算机图形学中最主要的内容。不懂就照复制就是了。
(4)最后的保存图像的方法saveBitmap()也没什么好说的。
就是安卓对sdcard卡的操作,详细见《【Android】读取sdcard上的图片》(点击打开链接),与Java对文件的操作的综合,详细见《【Java】输入与输出与JDK1.5之后的新型字符串StringBuilder》(点击打开链接)。
5、通过自己定义的View,能让res\layout\activity_main.xml这个MainActivity的布局xml。与MainActivity.java的代码变得简洁。
res\layout\activity_main.xml将变得例如以下的简短。就放一个DrawView,该实现的东西都在这个自己定义View中完毕。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.painter.DrawView android:id="@+id/drawView1" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>6、最后在MainActivity.java中实现指明各个菜单的实现方法就能完毕整个app,OnCreate方法根本就是什么都没有,不过载入布局文件。 package com.painter; import android.os.Bundle; import android.app.Activity; import android.graphics.Color; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } // 处理菜单事件 @Override public boolean onOptionsItemSelected(MenuItem item) { DrawView drawView = (DrawView) findViewById(R.id.drawView1); switch (item.getItemId()) { // 设置id为menu_exit的菜单子项所要运行的方法。case R.id.menu1_sub1: drawView.paint.setStrokeWidth(1); break; case R.id.menu1_sub2: drawView.paint.setStrokeWidth(5); break; case R.id.menu1_sub3: drawView.paint.setStrokeWidth(10); break; case R.id.menu1_sub4: drawView.paint.setStrokeWidth(50); break; case R.id.menu2: drawView.paint.setColor(Color.BLACK); break; case R.id.menu3: drawView.paint.setColor(Color.WHITE); break; case R.id.menu4: try { drawView.saveBitmap(); } catch (Exception e) { e.printStackTrace(); } break; case R.id.menu5: System.exit(0);// 结束程序 break; } return true; } }
最后。我上传了一份源代码给大家: