直接上代码,里面有注释:
首先,绘画板,就说明有自由绘画的功能,那么就需要自定义一个类,该类继承View,然后重写onDraw方法来实现自定义绘画;
本实例实现一个画图板,当用户在触摸屏上移动时,即可在屏幕上绘制任意图像,表面上看起来可以随用户在触摸屏上自由
的画曲线,实际上依然利用你的是Canvas的drawLine()方法画直线,如果程序每次都只是从上次拖动事件的发生点
绘制直线到本次拖动事件的发生点,那么用户前面绘制的就会丢失,为了保留用户之前绘制的内容,程序要借助于双缓冲技术:
当程序在指定View上绘制时,程序并不直接绘制到该View上,而是先绘制到内存中的一个Bitmap图片(缓冲区上),等到内
存中的Bitmap绘制好后再一次性的将Bitmap绘制到View上。
/** * Created by home on 2016/04/17. */ /* */ public class DrawView extends View { //定义记录前一个事件发生点的坐标 float preX; float preY; private Path path; public Paint paint=null; //定义内存中的一个图片,该图片将作为缓冲区 Bitmap cacheBitmap=null; //定义cacheBitmap的Canvas对象 Canvas cacheCanvas=null; public DrawView(Context context, int width, int height) { super(context); //创建一个与该View具有相同大小的缓冲区 cacheBitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888); cacheCanvas=new Canvas(); path=new Path(); //设置cacheCanvas将绘制到内存中的cacheBitmap上 cacheCanvas.setBitmap(cacheBitmap); //设置画笔颜色 paint=new Paint(Paint.DITHER_FLAG); paint.setColor(Color.RED); //设置画笔风格 paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); //反锯齿 paint.setAntiAlias(true); paint.setDither(true); } @Override public boolean onTouchEvent(MotionEvent event) { //获取拖动事件的发生位置 float x=event.getX(); float y=event.getY(); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //从前一个点绘制到当前点之后,把当前点定义成下次绘制的前一个点 path.moveTo(x,y); preX=x; preY=y;break; case MotionEvent.ACTION_MOVE: //从前一个点绘制到当前点之后。把当前点定义成下次绘制的前一个点 path.quadTo(preX,preY,x,y); preX=x; preY=y; break; case MotionEvent.ACTION_UP: cacheCanvas.drawPath(path,paint);//1 path.reset(); break; } invalidate(); //返回true表明处理方法已经处理该事件 return true; } @Override protected void onDraw(Canvas canvas) { Paint bmpPaint=new Paint(); //将cacheBitmap绘制到View上 canvas.drawBitmap(cacheBitmap,0,0,bmpPaint); //沿着path绘制 canvas.drawPath(path,paint); } } /* 提供了上面的DrawView后,接下来把该组件添加到主界面中,本程序无需使用界面布局文件 本程序直接在Activity中使用代码创建程序界面 本程序还提供了菜单来设置画笔的颜色和大小 */
菜单界面布局文件如下:
主Activity代码如下:<?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/colorRed"></item> <item android:id="@+id/green" android:title="@string/colorGreen"></item> <item android:id="@+id/blue" android:title="@string/colorBlue"></item> </group> </menu> </item> <item android:title="@string/width"> <menu> <!--定义一组菜单项--> <group > <!--定义三个菜单项--> <item android:id="@+id/width1" android:title="@string/width1"></item> <item android:id="@+id/width2" android:title="@string/width2"></item> <item android:id="@+id/width3" android:title="@string/width3"></item> </group> </menu> </item> <item android:id="@+id/blur" android:title="@string/blur"></item> <item android:id="@+id/emboss" android:title="@string/emboss"></item> </menu>
public class MainActivity extends AppCompatActivity { EmbossMaskFilter emboss; BlurMaskFilter blur; DrawView drawView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout line=new LinearLayout(this); DisplayMetrics displayMetrics=new DisplayMetrics(); //获取创建的高度和宽度 getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics); //创建一个DrawView,该DrawView的宽度高度与该Activity相同 drawView=new DrawView(this,displayMetrics.widthPixels,displayMetrics.heightPixels); line.addView(drawView); setContentView(line); emboss=new EmbossMaskFilter(new float[]{1.5f,1.5f,1.5f},0.6f,6,4.2f); blur=new BlurMaskFilter(8,BlurMaskFilter.Blur.NORMAL); } //负责创建选项菜单 @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater=new MenuInflater(this); //加载R.menu.menu对应的菜单,并添加到menu中 inflater.inflate(R.menu.menu,menu); return super.onCreateOptionsMenu(menu); } //菜单被单击后的回调方法 @Override public boolean onOptionsItemSelected(MenuItem item) { //判断单击的是哪菜单项,并有针对性的作出响应 switch (item.getItemId()){ case R.id.red: drawView.paint.setColor(Color.RED); item.setChecked(true); break; case R.id.green: drawView.paint.setColor(Color.GREEN); item.setChecked(true); break; case R.id.blue: drawView.paint.setColor(Color.BLUE); item.setChecked(true); break; case R.id.width1: drawView.paint.setStrokeWidth(1); break; case R.id.width2: drawView.paint.setStrokeWidth(3); break; case R.id.width3: drawView.paint.setStrokeWidth(5); break; case R.id.blur: drawView.paint.setMaskFilter(blur); break; case R.id.emboss: drawView.paint.setMaskFilter(emboss); break; } return true; } }以上,仅供参考。