android 仿qq手写板涂鸦

简介: 以前博客的链接:点击打开链接 附上关键代码:MainView.java[java] view plaincopypackage com.tszy.views;    import java.io.File;  import java.io.FileNotFoundException;  import java.io.FileOutputStream;  impo


以前博客的链接:点击打开链接


 

附上关键代码:

MainView.java

[java] view plain copy
  1. package com.tszy.views;  
  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.content.Context;  
  9. import android.graphics.Bitmap;  
  10. import android.graphics.Bitmap.CompressFormat;  
  11. import android.graphics.Bitmap.Config;  
  12. import android.graphics.Canvas;  
  13. import android.graphics.Color;  
  14. import android.graphics.Paint;  
  15. import android.graphics.Path;  
  16. import android.util.AttributeSet;  
  17. import android.view.MotionEvent;  
  18. import android.view.View;  
  19.   
  20. public class MainView extends View {  
  21.     private Paint paint;  
  22.     private Canvas cacheCanvas;  
  23.     private Bitmap cachebBitmap;  
  24.     private Path path;  
  25.       
  26.     private int clr_bg, clr_fg;  
  27.   
  28.       
  29.     public MainView(Context context, AttributeSet attrs) {  
  30.         super(context, attrs);  
  31.           
  32.         clr_bg = Color.WHITE;  
  33.         clr_fg = Color.CYAN;  
  34.           
  35.         paint = new Paint();  
  36.         paint.setAntiAlias(true); // 抗锯齿  
  37.         paint.setStrokeWidth(3); // 线条宽度  
  38.         paint.setStyle(Paint.Style.STROKE); // 画轮廓  
  39.         paint.setColor(clr_fg); // 颜色  
  40.           
  41.         path = new Path();  
  42.         // 创建一张屏幕大小的位图,作为缓冲  
  43.         cachebBitmap = Bitmap.createBitmap(480800, Config.ARGB_8888);  
  44.         cacheCanvas = new Canvas(cachebBitmap);  
  45.         cacheCanvas.drawColor(clr_bg);  
  46.     }  
  47.   
  48.     public MainView(Context context) {  
  49.         super(context);  
  50.     }  
  51.       
  52.     @Override  
  53.     protected void onDraw(Canvas canvas) {  
  54.         canvas.drawColor(clr_bg);  
  55.   
  56.         // 绘制上一次的,否则不连贯  
  57.         canvas.drawBitmap(cachebBitmap, 00null);  
  58.         canvas.drawPath(path, paint);         
  59.     }  
  60.       
  61.     /** 
  62.      * 清空画布 
  63.      */  
  64.     public void clear() {  
  65.         path.reset();  
  66.         cacheCanvas.drawColor(clr_bg);  
  67.         invalidate();  
  68.     }  
  69.       
  70.     /** 
  71.      * 将画布的内容保存到文件 
  72.      * @param filename 
  73.      * @throws FileNotFoundException 
  74.      */  
  75.     public void saveToFile(String filename) throws FileNotFoundException {  
  76.         File f = new File(filename);  
  77.         if(f.exists())  
  78.             throw new RuntimeException("文件:" + filename + " 已存在!");  
  79.               
  80.         FileOutputStream fos = new FileOutputStream(new File(filename));  
  81.         //将 bitmap 压缩成其他格式的图片数据  
  82.         cachebBitmap.compress(CompressFormat.PNG, 50, fos);  
  83.         try {  
  84.             fos.close();  
  85.         } catch (IOException e) {  
  86.             // TODO Auto-generated catch block  
  87.             e.printStackTrace();  
  88.         }  
  89.     }  
  90.   
  91.     private float cur_x, cur_y;  
  92.     private boolean isMoving;  
  93.     @Override  
  94.     public boolean onTouchEvent(MotionEvent event) {  
  95.         // TODO Auto-generated method stub  
  96.         float x = event.getX();  
  97.         float y = event.getY();  
  98.   
  99.         switch (event.getAction()) {  
  100.             case MotionEvent.ACTION_DOWN : {  
  101.                 cur_x = x;  
  102.                 cur_y = y;  
  103.                 path.moveTo(cur_x, cur_y);  
  104.                 isMoving = true;  
  105.                 break;  
  106.             }  
  107.   
  108.             case MotionEvent.ACTION_MOVE : {  
  109.                 if (!isMoving)  
  110.                     break;  
  111.   
  112.                 // 二次曲线方式绘制  
  113.                 path.quadTo(cur_x, cur_y, x, y);  
  114.                 // 下面这个方法貌似跟上面一样  
  115.                 // path.lineTo(x, y);  
  116.                 cur_x = x;  
  117.                 cur_y = y;  
  118.                 break;  
  119.             }  
  120.   
  121.             case MotionEvent.ACTION_UP : {  
  122.                 // 鼠标弹起保存最后状态  
  123.                 cacheCanvas.drawPath(path, paint);  
  124.                 path.reset();  
  125.                 isMoving = false;  
  126.                 break;  
  127.             }  
  128.         }  
  129.   
  130.         // 通知刷新界面  
  131.         invalidate();  
  132.   
  133.         return true;  
  134.     }  
  135.   
  136. }  

 

Activity 代码:

[java] view plain copy
  1. @Override  
  2.     public void onClick(View v) {  
  3.         // TODO Auto-generated method stub  
  4.         switch (v.getId()) {  
  5.             case R.id.iv_btn_clear :  
  6.                 view.clear();  
  7.                 break;  
  8.   
  9.             case R.id.iv_btn_save : {  
  10.                 try {  
  11.                     String sdState = Environment.getExternalStorageState(); // 判断sd卡是否存在  
  12.   
  13.                     // 检查SD卡是否可用  
  14.                     if (!sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {  
  15.                         Toast.makeText(this"SD卡未准备好!", Toast.LENGTH_SHORT).show();  
  16.                         break;  
  17.                     }  
  18.   
  19.                     //获取系统图片存储路径  
  20.                     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  21.                     // Make sure the Pictures directory exists.  
  22.                     path.mkdirs();  
  23.                       
  24.                     //根据当前时间生成图片名称  
  25.                     Calendar c = Calendar.getInstance();  
  26.                     String name = ""   
  27.                             + c.get(Calendar.YEAR) + c.get(Calendar.MONTH) + c.get(Calendar.DAY_OF_MONTH)   
  28.                             + c.get(Calendar.HOUR_OF_DAY) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND)  
  29.                              + ".png";  
  30.                       
  31.                     //合成完整路径,注意 / 分隔符  
  32.                     String string = path.getPath() + "/" + name;  
  33.                     view.saveToFile(string);  
  34.                     Toast.makeText(this"保存成功!\n文件保存在:" + string, Toast.LENGTH_LONG).show();  
  35.                 } catch (FileNotFoundException e) {  
  36.                     Toast.makeText(this"保存失败!\n" + e, Toast.LENGTH_LONG).show();  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }  

没什么难度,主要是将Bitmap转PNG图片那里,找了一会发现 Canvas 没有直接或间接保存的方法,刚好这里我使用了双缓冲,另一块画布的内容位图自己创建的,很自然想到将这个画布的位图保存为文件即可。

再查看 Bitmap 有个 compress(CompressFormat format, int quality,OutputStream stream) 方法,很明显将文件输出流传给这个方法就OK


[java] view plain copy
  1. @Override  
  2.     public void onClick(View v) {  
  3.         // TODO Auto-generated method stub  
  4.         switch (v.getId()) {  
  5.             case R.id.iv_btn_clear :  
  6.                 view.clear();  
  7.                 break;  
  8.   
  9.             case R.id.iv_btn_save : {  
  10.                 try {  
  11.                     String sdState = Environment.getExternalStorageState(); // 判断sd卡是否存在  
  12.   
  13.                     // 检查SD卡是否可用  
  14.                     if (!sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {  
  15.                         Toast.makeText(this"SD卡未准备好!", Toast.LENGTH_SHORT).show();  
  16.                         break;  
  17.                     }  
  18.   
  19.                     //获取系统图片存储路径  
  20.                     File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);  
  21.                     // Make sure the Pictures directory exists.  
  22.                     path.mkdirs();  
  23.                       
  24.                     //根据当前时间生成图片名称  
  25.                     Calendar c = Calendar.getInstance();  
  26.                     String name = ""   
  27.                             + c.get(Calendar.YEAR) + c.get(Calendar.MONTH) + c.get(Calendar.DAY_OF_MONTH)   
  28.                             + c.get(Calendar.HOUR_OF_DAY) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND)  
  29.                              + ".png";  
  30.                       
  31.                     //合成完整路径,注意 / 分隔符  
  32.                     String string = path.getPath() + "/" + name;  
  33.                     view.saveToFile(string);  
  34.                     Toast.makeText(this"保存成功!\n文件保存在:" + string, Toast.LENGTH_LONG).show();  
  35.                 } catch (FileNotFoundException e) {  
  36.                     Toast.makeText(this"保存失败!\n" + e, Toast.LENGTH_LONG).show();  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }  

目录
相关文章
|
API Android开发 数据安全/隐私保护
Android 开发之 QQ变声功能实现
Android 开发之 QQ变声功能实现
697 0
Android 开发之 QQ变声功能实现
|
JavaScript API Android开发
Android,iOS打开手机QQ与指定用户聊天界面
Android,iOS打开手机QQ与指定用户聊天界面
175 0
|
开发工具 Android开发 计算机视觉
Android Service全解(三)之 Foreground Service(怎么让Android程序一直后台运行,像QQ一样不被杀死?)
Android Service全解(三)之 Foreground Service(怎么让Android程序一直后台运行,像QQ一样不被杀死?)
1262 0
|
XML 安全 JavaScript
如何在Android上快速集成微信和QQ的分享(Share)能力?
目前微信和QQ已经成为App分享的主要平台,大部分开发者都会首选集成这两个平台,除了可以选择直接继承官方的的SDK外,目前市面上有不少第三方的集成商,帮助开发者打包好了一键分享的SDK能力,如:极光,友盟,Mobtech等,这里主要以友盟集成为例,快速实现在Android上集成两个平台的分享能力。
|
XML 安全 Java
如何在Android上快速集成微信和QQ的分享(Share)能力?
目前微信和QQ已经成为App分享的主要平台,大部分开发者都会首选集成这两个平台,除了可以选择直接继承官方的的SDK外,目前市面上有不少第三方的集成商,帮助开发者打包好了一键分享的SDK能力,如:极光,友盟+,Mobtech等,这里主要以友盟+集成为例,快速实现在Android上集成两个平台的分享能力。
|
Android开发
Android 调用系统分享文字、图片、文件,可直达微信、朋友圈、QQ、QQ空间、微博
原文:Android 调用系统分享文字、图片、文件,可直达微信、朋友圈、QQ、QQ空间、微博 兼容SDK 18以上的系统,直接调用系统分享功能,分享文本、图片、文件到第三方APP,如:微信、QQ、微博等 因为偷懒,可直达微信、朋友圈、QQ、QQ空间、微博的分享仅写了图片分享的,其他的文本、文件分享不常用到,就不写了。
6276 0
|
Android开发
【Android视图效果】仿QQ空间滑动改变标题栏颜色
最近在倒腾公司之前的项目,发现之前的界面是个白色标题栏,不是很美观,所以做了些改进。 先看效果图 165815uykp80g8y3goo5vz.gif 简单说下思路,整个布局大体上是ScrollView里面包含了一个ImageView和RecyclerView,所以先得到ImageView的高度,当ScrollView向上滑动时,设置标题栏的背景色、文字颜色,当超过ImageView的高度时,设置其背景为白色,字体为黑色。
1132 0
|
Android开发
Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件
原文:Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件 大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: 1、QQ空间允许我们 点击 回复人和被回复人...
972 0
|
Android开发
Android项目实战(十七):QQ空间实现(二)—— 分享功能 / 弹出PopupWindow
原文:Android项目实战(十七):QQ空间实现(二)—— 分享功能 / 弹出PopupWindow 这是一张QQ空间说说详情的截图。 分析: 1、点击右上角三个点的图标,在界面底部弹出一个区域,这个区域有一些按钮提供给我们操作 2、当该区域出现的时候,详情界面便灰了,也说成透明度变...
886 0