Android开发画画板要考虑得几个问题如下:
1 屏幕画板、画笔如何绘制问题
2 用户手指触摸屏幕画板监听事件,以及对应的几种状态处理问题
3 保存图片到SD卡,以及在系统相册打开时自动加载刚才的图片问题
解决方法
1 使用了BitmapFactor和Bitmap的相关的方法来解析一张背景图,并复制一份副本,再在Canvas来绘制画板,画笔。
2 使用系统的OnTouchLister来监听用户的触摸屏幕画板事件,以及相应的状态进行不同的处理
3 系统每次收到SD卡就绪广播时,都会去遍历sd卡的所有文件和文件夹,把遍历到的所有多媒体文件都在MediaStore数据库保存一个索引,这个索引包含多媒体文件的文件 名、 路径、大小。图库每次打开时,并不会去遍历sd卡获取图片,而是通过内容提供者从MediaStore数据库中获取图片的信息,然后读取该图片。系统开机或者点击加载sd卡按钮时,系统会发送sd卡就绪广播,我们也可以手动发送就绪广播来加载我们保存在sd卡中图片。
代码如下
1 package com.scywxx.paint; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 8 import android.net.Uri; 9 import android.os.Bundle; 10 import android.os.Environment; 11 import android.app.Activity; 12 import android.content.Intent; 13 import android.graphics.Bitmap; 14 import android.graphics.Bitmap.CompressFormat; 15 import android.graphics.BitmapFactory; 16 import android.graphics.Canvas; 17 import android.graphics.Color; 18 import android.graphics.Matrix; 19 import android.graphics.Paint; 20 import android.view.Menu; 21 import android.view.MotionEvent; 22 import android.view.View; 23 import android.view.View.OnTouchListener; 24 import android.widget.ImageView; 25 26 public class MainActivity extends Activity { 27 private ImageView iv; 28 private Bitmap bmCopy; 29 private Paint paint; 30 private Canvas canvas; 31 private int startX,startY; 32 @Override 33 protected void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.activity_main); 36 //1 加载画画板的背景图 37 Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.bg); 38 //2 把源位图对象复制一份 39 bmCopy = Bitmap.createBitmap(bmSrc.getWidth(),bmSrc.getHeight(),bmSrc.getConfig()); 40 //3 创建画笔对象 41 paint = new Paint(); 42 canvas = new Canvas(bmCopy); 43 //4 开始绘制 44 canvas.drawBitmap(bmSrc, new Matrix(), paint); 45 //5 获取界面上ImageView对象得资源id 46 iv = (ImageView) findViewById(R.id.iv); 47 iv.setImageBitmap(bmCopy); 48 //6 给画画板得背景设置触摸监听 49 iv.setOnTouchListener(new OnTouchListener() { 50 //触摸屏幕时,触摸事件产生时,此方法调用 51 @Override 52 public boolean onTouch(View v, MotionEvent event) { 53 int action = event.getAction();//获取该事件得动作 54 switch(action){ 55 //用户手指触摸到屏幕 56 case MotionEvent.ACTION_DOWN: 57 //记录开始的x和开始的y 58 startX = (int) event.getX(); 59 startY = (int) event.getY(); 60 break; 61 //用户手指正在划动 62 case MotionEvent.ACTION_MOVE: 63 int x=(int) event.getX(); 64 int y=(int) event.getY(); 65 //两点连成一条线 66 canvas.drawLine(startX, startY, x, y, paint); 67 //下次得起始点 68 startX=x; 69 startY=y; 70 iv.setImageBitmap(bmCopy); 71 break; 72 //用户手指离开屏幕 73 case MotionEvent.ACTION_UP: 74 break; 75 76 77 } 78 //true:告诉系统,这个触摸事件由我来处理 79 //false:告诉系统,这个触摸事件我不处理,这时系统会把触摸事件传递给imageview的父节点 80 return true; 81 } 82 }); 83 84 85 86 87 88 } 89 //设置画笔颜色为红色 90 public void red(View v){ 91 paint.setColor(Color.RED); 92 } 93 //设置画笔颜色为红色 94 public void green(View v){ 95 paint.setColor(Color.GREEN); 96 } 97 //设置画笔的粗细 98 public void change(View v){ 99 paint.setStrokeWidth(7); 100 } 101 //保存图片到sd卡中 102 public void save(View v){ 103 File file = new File("sdcard/huahua.png"); 104 FileOutputStream fos=null; 105 try { 106 fos = new FileOutputStream(file); 107 } catch (FileNotFoundException e) { 108 e.printStackTrace(); 109 } 110 //将图片压缩保存 111 bmCopy.compress(CompressFormat.PNG, 100, fos); 112 //系统每次收到SD卡就绪广播时,都会去遍历sd卡的所有文件和文件夹,把遍历到的所有多媒体文件都在MediaStore数据库保存一个索引,这个索引包含多媒体文件的文件名、路径、大小 113 // 图库每次打开时,并不会去遍历sd卡获取图片,而是通过内容提供者从MediaStore数据库中获取图片的信息,然后读取该图片 114 // 系统开机或者点击加载sd卡按钮时,系统会发送sd卡就绪广播,我们也可以手动发送就绪广播 115 Intent intent = new Intent(); 116 intent.setAction(Intent.ACTION_MEDIA_MOUNTED); 117 intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); 118 sendBroadcast(intent); 119 } 120 121 }
界面布局如下
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context=".MainActivity" > 10 <ImageView 11 android:id="@+id/iv" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 /> 15 <LinearLayout 16 android:layout_width="match_parent" 17 android:layout_height="wrap_content" 18 android:orientation="horizontal" 19 android:layout_alignParentBottom="true" 20 > 21 <Button 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content" 24 android:text="红色" 25 android:onClick="red"/> 26 <Button 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:text="绿色" 30 android:onClick="green"/> 31 <Button 32 android:layout_width="wrap_content" 33 android:layout_height="wrap_content" 34 android:text="粗细" 35 android:onClick="change"/> 36 <Button 37 android:layout_width="wrap_content" 38 android:layout_height="wrap_content" 39 android:text="保存" 40 android:onClick="save"/> 41 </LinearLayout> 42 43 </RelativeLayout>
效果如下