该程序实现画画板的功能,可以调节画笔的大小以及颜色,png图片可以保存到本地或者相册中,同时带有清除画板以及橡皮檫等基本功能。
DrawActivity的CODE:
package com.example.drawfreedom;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
public class DrawActivity extends Activity {
static int i=0,j=0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.getFilesDir();
PermisionUtils.verifyStoragePermissions(this); //获取手机SD卡读取权限
}
// 创建选项菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflator = new MenuInflater(this);//实例化一个MenuInflater对象
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(5); //初始化画笔的宽度
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(5); //设置笔触的宽度为1像素
break;
case R.id.width_2:
dv.paint.setStrokeWidth(10); //设置笔触的宽度为5像素
break;
case R.id.width_3:
dv.paint.setStrokeWidth(15);//设置笔触的宽度为10像素
break;
case R.id.clear:
dv.clear(); //橡皮檫
break;
case R.id.back:
dv.back(); //返回上一步
break;
case R.id.nothing:
dv.nothing(); //清屏
//DrawView dv1 = (DrawView) findViewById(R.id.drawView1);
break;
case R.id.save:
{
j=0;
dv.save(i,j);i++; //保存绘画到APP目录
break;
}
case R.id.save_camera:
{
j=1;
dv.save(i,j);i++;
if(!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))//若是获取权限失败,提示手动获取
Toast.makeText(DrawActivity.this, "获取权限失败,请手动授权", Toast.LENGTH_SHORT).show();
break;
}//保存绘画到相册
}
return true;
}
}
DrawView继承自View,CODE:
package com.example.drawfreedom;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
@SuppressLint("DrawAllocation")
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; //路径
public Paint paint = null; //画笔
Bitmap cacheBitmap = null;// 定义一个内存中的图片,该图片将作为缓冲区
Canvas cacheCanvas = null;// 定义cacheBitmap上的Canvas对象
public DrawView(Context context, AttributeSet set) {
super(context, set);
view_width = context.getResources().getDisplayMetrics().widthPixels; // 获取屏幕的宽度
view_height = context.getResources().getDisplayMetrics().heightPixels; // 获取屏幕的高度
System.out.println(view_width + "*" + view_height);
// 创建一个与该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.GREEN); // 设置默认的画笔颜色
// 设置画笔风格
paint.setStyle(Paint.Style.STROKE); //设置填充方式为描边
paint.setStrokeJoin(Paint.Join.ROUND); //设置笔刷的图形样式
paint.setStrokeCap(Paint.Cap.ROUND); //设置画笔转弯处的连接风格
paint.setStrokeWidth(5); // 设置默认笔触的宽度为5像素
paint.setAntiAlias(true); // 使用抗锯齿功能
paint.setDither(true); // 使用抖动效果
}
@Override
public void onDraw(Canvas canvas) {
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执行的操作对后续的绘制有影响
}
@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); // 将绘图的起始点移到(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.setColor(Color.BLUE);
paint.setStrokeWidth(50); //设置笔触的宽度
//invalidate();
}
public void back() {
Canvas canvas=new Canvas();
canvas.restore();
}
public void nothing() {
cacheBitmap=null;
// 创建一个与该View相同大小的缓存区
cacheBitmap = Bitmap.createBitmap(view_width, view_height,
Config.ARGB_8888);
cacheCanvas = new Canvas();
cacheCanvas.setBitmap(cacheBitmap);// 在cacheCanvas上绘制cacheBitmap
invalidate();
}
public void save(int i,int j) {
//int i=0;
try {
saveBitmap("DrawingPicture","DrawingPicture_"+i,j);
} catch (IOException e) {
e.printStackTrace();
}
}
// 保存绘制好的位图到APP目录下
public void saveBitmap(String filesize,String fileName,int j) throws IOException {
String directoryPath;
directoryPath=getFilePath(getContext(),filesize,fileName,j);
//directoryPath=getFilePath(getContext(),filesize,fileName,j);
File file = new File(directoryPath ); //创建文件对象
try {
file.createNewFile(); //创建一个新文件
FileOutputStream fileOS = new FileOutputStream(file); //创建一个文件输出流对象
cacheBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOS); //将绘图内容压缩为PNG格式输出到输出流对象中
fileOS.flush(); //将缓冲区中的数据全部写出到输出流中
fileOS.close(); //关闭文件输出流对象
Toast.makeText(getContext(), "成功保存到"+directoryPath, Toast.LENGTH_SHORT).show();//垴村成功,提示保存的路径
}catch (Exception e) {
Toast.makeText(getContext(), e.toString(), Toast.LENGTH_LONG).show();//保存失败,提示原因
}
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(file);
intent.setData(uri);
getContext().sendBroadcast(intent);//这个广播的目的就是更新图库,发了这个广播进入相册就可以找到你保存的图片了!,记得要传你更新的file哦
}
public static String getFilePath(Context context,String filesize,String dir,int j) { //获取APP当前目录并且设置图片保存路径
String directoryPath="";
if(j==0) {
//判断SD卡是否可用
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {
directoryPath =context.getExternalFilesDir(filesize).getAbsolutePath()+File.separator+ dir + ".png";
// directoryPath =context.getExternalCacheDir().getAbsolutePath() ;
}else{
//没内存卡就存机身内存
directoryPath=context.getFilesDir().getAbsolutePath()
+File.separator
+filesize+File.separator
+ dir + ".png";
// directoryPath=context.getCacheDir()+File.separator+dir;
}}
else
{
directoryPath =Environment.getExternalStorageDirectory()
+ File.separator +
Environment.DIRECTORY_DCIM
+File.separator+"Camera"+File.separator+dir + ".png";
// File file = new File(directoryPath);
//if(!file.exists()){//判断文件目录是否存在
// file.mkdirs();
//directoryPath=directoryPath+File.separator+dir + ".png";
}
//LogUtil.i("filePath====>"+directoryPath);
//}
return directoryPath;
}
}
toolsmenu.xml文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/back" android:title="@string/back"/>
<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 android:checkableBehavior="single">
<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/nothing" android:title="@string/nothing"/>
<item android:id="@+id/clear" android:title="@string/clear"
android:icon="@drawable/cha"/>
<item android:id="@+id/save" android:title="@string/save"/>
<item android:id="@+id/save_camera" android:title="@string/save_camera"/>
</menu>
main.xml的CODE,main记得链接DrawView视图:
<?xml version="1.0" encoding="utf-8"?>
<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.drawfreedom.DrawView
android:id="@+id/drawView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
获取SD卡权限:
在MainActivityfest中:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>