该程序实现画画板的功能,可以调节画笔的大小以及颜色,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;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);this.getFilesDir();PermisionUtils.verifyStoragePermissions(this);   //获取手机SD卡读取权限}// 创建选项菜单@Overridepublic boolean onCreateOptionsMenu(Menu menu) {MenuInflater inflator = new MenuInflater(this);//实例化一个MenuInflater对象inflator.inflate(R.menu.toolsmenu, menu); //解析菜单文件return super.onCreateOptionsMenu(menu);}// 当菜单项被选择时,作出相应的处理@Overridepublic 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上绘制cacheBitmappaint = 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); // 使用抖动效果}@Overridepublic void onDraw(Canvas canvas) {canvas.drawColor(0xFFFFFFFF);  //设置背景颜色Paint bmpPaint = new Paint();  //采用默认设置创建一个画笔canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); //绘制cacheBitmapcanvas.drawPath(path, paint);  //绘制路径canvas.save(Canvas.ALL_SAVE_FLAG);    //保存canvas的状态//canvas.restore();    //恢复canvas之前保存的状态,防止保存后对canvas执行的操作对后续的绘制有影响 }@Overridepublic 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上绘制cacheBitmapinvalidate();}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.DrawViewandroid: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"/>

安卓开发之画画板的实现相关推荐

  1. 安卓开发笔记(十一)—— 方向传感器,实现摇一摇动画音效,GPS定位

    中山大学数据科学与计算机学院本科生实验报告 (2018年秋季学期) 项目源码:Github传送门 一.实验题目 第十六周任务 传感器 第十六周实验目的 学会使用加速度传感器 学会使用地磁传感器 学会获 ...

  2. 安卓开发笔记——自定义广告轮播Banner(实现无限循环)

    关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户& ...

  3. 学习android 画板源代码,Android实现画画板案例

    郑州app开发画画板案例.布局代码是三个button和一个imagesview下面是图片. 布局代码就不展示了.下面是java代码. package cn.xhhkj.image; import an ...

  4. 安卓开发实现俄罗斯方块游戏

    1.实现方式 *使用安卓开发实现 *使用开发工具:AndroidStudio 2.样例展示 1.游戏开始样例 2.游戏进行中 3.游戏暂停 4.游戏结束 3.代码展示 * 1.结构说明:控制显示的xm ...

  5. 【大疆DJI】安卓开发实习历程- 0.前期准备到面试(HR电话初面+技术一面+技术二面/终面+OC)

    目录 前言 实习选择 0. 腾讯云 1. 面试复盘 2. 海投简历 大疆HR电话初面 大疆技术一面 0. 面试形式 1. 问题准备 2. 面试经过(70 mins) 大疆技术二面(终面) 0. 面试形 ...

  6. 我是如何学习安卓开发的

    我的安卓学习之路 我的安卓之路主要有四个阶段: 入门 实践 准备面试 工作 1.入门 2014 年,学习 MFC 中途放弃的我,偶然间看到 Mars 前辈的安卓视频,看了几天写了个简单的应用,觉得安卓 ...

  7. 大学android五子棋课程目的,基于安卓开发的五子棋课程设计报告..docx

    大庆师范学院 <ANDROID开发基础> 题目:基于安卓开发的五 子棋游戏 专业班级: 计算机科学与技术一班 设计者: KKKKKKKKKKKKKKKKKKK 指导老师:2016-2017 ...

  8. 安卓开发中非常炫的效果集合

    安卓开发中非常炫的效果集合 这几天开发的时候,想做一些好看而且酷炫的特效,于是又开始从网上收集各种特效资源.下面给大家一些我喜欢的把,附代码,喜欢的看源代码,然后加到自己项目去把!! 一个开源项目网站 ...

  9. android五子棋设计报告,基于安卓开发的五子棋课程设计报告精选.doc

    基于安卓开发的五子棋课程设计报告精选 大庆师范学院 <Android开发基础> 题目:基于安卓开发的五子棋游戏 专业班级: 计算机科学与技术一班 设 计 者: kkkkkkkkkkkkkk ...

最新文章

  1. 美国新桥投资集团(Newbridge Capital) [from baike]
  2. cvs update 的输出标志/update常用几个参
  3. 数组作为方法参数_传递地址
  4. Window 转Linux 后感
  5. 华为阅读下载的文件在哪里找_华为手机还要天天清理内存?1键关闭这2个设置,手机用到2035年...
  6. 查看、关闭当前服务器上启动服务 / 进程
  7. php 模板继承原理,模板继承体会
  8. 从化工技术员到微软最有价值专家(MVP)--我的IT从业路
  9. bbs小项目整理(五)(登录模块的完成)
  10. 携程分销联盟-旅游度假接口实现1
  11. 斯坦福大学深度学习公开课cs231n学习笔记(2)线性分类器及最优化
  12. 设计模式-Decorator装饰模式
  13. db9针232接口波特率标准_9针RS232-422-485接口定义
  14. IOCP完成端口模拟线程池
  15. express搭建的nodejs项目使用webpack进行打包
  16. scrum敏捷开发项目管理工具必备
  17. Discuz!论坛教程之去掉帖子列表页的附件图标的方法
  18. PS2无线遥控手柄的通讯协议以及c语言代码分析
  19. maven docker 部署到多台机器上。。_TensorFlow Serving + Docker + Tornado机器学习模型生产级快速部署
  20. 第3章 结构之法——电话号码对应英语单词

热门文章

  1. 华为OD机试真题 JS 实现【检测热点字符】【2023 Q1 | 100分】
  2. 华为od机试真题 Python 实现【热点网站统计】
  3. jQuery学习周记
  4. matlab里real,matlab中real和imag
  5. ArcGIS教程 - 6 空间数据获取
  6. 输入一行字符统计英文字母,空格,数字和其他字符的个数
  7. android中监听软键盘的弹出与隐藏,并获取软键盘的高度
  8. POCO C++库学习和分析 -- 字符编码
  9. Google搜索引擎原理
  10. SEO新手站长说说之网站更新频率多少才合适