Android上的第三方开源DrawableView支持手写,类似于写字板。DrawableView支持改变画笔颜色,画笔线条粗细,画布的手势缩放和拖曳显示部分区域。并最终支持将手绘的图保存到本地。
在github上的项目主页:https://github.com/PaNaVTEC/DrawableView
先把布局文件中写一个DrawableView:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:padding="5dp"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. tools:context="com.zzw.testdrawableview.MainActivity" >
  8.  
  9. <RelativeLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content" >
  12.  
  13. <Button
  14. android:id="@+id/subWidth"
  15. android:layout_width="36dp"
  16. android:layout_height="36dp"
  17. android:layout_alignParentRight="true"
  18. android:layout_alignParentTop="true"
  19. android:background="@drawable/sub" />
  20.  
  21. <Button
  22. android:id="@+id/addWidth"
  23. android:layout_width="36dp"
  24. android:layout_height="36dp"
  25. android:layout_alignParentLeft="true"
  26. android:layout_alignParentTop="true"
  27. android:background="@drawable/add" />
  28.  
  29. <Button
  30. android:id="@+id/sava"
  31. android:layout_width="36dp"
  32. android:layout_height="36dp"
  33. android:layout_alignParentTop="true"
  34. android:layout_centerHorizontal="true"
  35. android:background="@drawable/sava" />
  36.  
  37. <Button
  38. android:id="@+id/PaintColor"
  39. android:layout_width="36dp"
  40. android:layout_height="36dp"
  41. android:layout_alignParentTop="true"
  42. android:layout_marginRight="50dp"
  43. android:layout_toLeftOf="@+id/sava"
  44. android:background="@drawable/rand" />
  45.  
  46. <Button
  47. android:id="@+id/undo"
  48. android:layout_width="36dp"
  49. android:layout_height="36dp"
  50. android:layout_alignParentTop="true"
  51. android:layout_marginLeft="50dp"
  52. android:layout_toRightOf="@+id/sava"
  53. android:background="@drawable/ret" />
  54.  
  55. </RelativeLayout>
  56.  
  57. <me.panavtec.drawableview.DrawableView
  58. android:id="@+id/paintView"
  59. android:layout_width="match_parent"
  60. android:layout_height="wrap_content"
  61. android:layout_alignParentBottom="true"
  62. android:layout_weight="1" />
  63.  
  64. </LinearLayout>

JAVA代码:

  1. package com.zzw.testdrawableview;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6.  
  7. import android.app.Activity;
  8. import android.graphics.Bitmap;
  9. import android.graphics.Color;
  10. import android.os.Bundle;
  11. import android.os.Environment;
  12. import android.util.Log;
  13. import android.view.View;
  14. import android.view.View.OnClickListener;
  15. import android.widget.Button;
  16. import android.widget.Toast;
  17. import me.panavtec.drawableview.DrawableView;
  18. import me.panavtec.drawableview.DrawableViewConfig;
  19.  
  20. public class MainActivity extends Activity implements OnClickListener {
  21.  
  22. private DrawableView drawableView;
  23. private DrawableViewConfig config;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. config = new DrawableViewConfig();
  31.  
  32. drawableView = (DrawableView) findViewById(R.id.paintView);
  33.  
  34. Button addWidth = (Button) findViewById(R.id.addWidth);
  35. Button subWidth = (Button) findViewById(R.id.subWidth);
  36. Button PaintColor = (Button) findViewById(R.id.PaintColor);
  37. Button undo = (Button) findViewById(R.id.undo);
  38. Button sava = (Button) findViewById(R.id.sava);
  39.  
  40. addWidth.setOnClickListener(this);
  41. subWidth.setOnClickListener(this);
  42. PaintColor.setOnClickListener(this);
  43. undo.setOnClickListener(this);
  44. sava.setOnClickListener(this);
  45.  
  46. // 画笔颜色
  47. config.setStrokeColor(Color.RED);
  48.  
  49. // 画布边界
  50. config.setShowCanvasBounds(true);
  51.  
  52. // 设置画笔宽度
  53. config.setStrokeWidth(10.0f);
  54.  
  55. // 缩放
  56. config.setMinZoom(1.0f);
  57. config.setMaxZoom(3.0f);
  58.  
  59. // 画布宽和高
  60. config.setCanvasHeight(3000);
  61. config.setCanvasWidth(2000);
  62.  
  63. drawableView.setConfig(config);
  64. }
  65.  
  66. @Override
  67. public void onClick(View v) {
  68. switch (v.getId()) {
  69. case R.id.addWidth:
  70. // 设置每次增加10.0的宽度
  71. config.setStrokeWidth(config.getStrokeWidth() + 10);
  72. Toast.makeText(getApplicationContext(),
  73. "当前画笔宽度:" + config.getStrokeWidth(), 0).show();
  74. break;
  75.  
  76. case R.id.subWidth:
  77. // 设置每次减少10.0的宽度
  78. if (config.getStrokeWidth() > 10) {
  79. config.setStrokeWidth(config.getStrokeWidth() - 10);
  80. Toast.makeText(getApplicationContext(),
  81. "当前画笔宽度:" + config.getStrokeWidth(), 0).show();
  82. }
  83. break;
  84.  
  85. case R.id.PaintColor:
  86. // 测试期间,随机生成一种颜色
  87. int r1 = (int) (Math.random() * 256);
  88. int r2 = (int) (Math.random() * 256);
  89. int r3 = (int) (Math.random() * 256);
  90. config.setStrokeColor(Color.argb(255, r1, r2, r3));
  91. Toast.makeText(getApplicationContext(), "颜色生成成功", 0).show();
  92. break;
  93.  
  94. case R.id.undo:
  95. drawableView.undo();
  96. break;
  97.  
  98. case R.id.sava:
  99. try {
  100. savaBitmapToSDCard();
  101. } catch (IOException e) {
  102. e.printStackTrace();
  103. }
  104. break;
  105. }
  106. }
  107.  
  108. // 将用户手绘的DrawableView转化为图片保存到本地系统默认的图片库中。
  109. private void savaBitmapToSDCard() throws IOException {
  110.  
  111. // 从DrawableView获得Bitmap
  112. Bitmap bmp = drawableView.obtainBitmap();
  113.  
  114. // 获取保存的路径
  115. File parent_path = Environment
  116. .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
  117. File f = new File(parent_path.getAbsoluteFile(), "myDrawableView.png");
  118. f.createNewFile();
  119. Log.d("保存路径", f.getAbsolutePath());
  120.  
  121. FileOutputStream fos = new FileOutputStream(f);
  122. bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
  123. fos.flush();
  124. fos.close();
  125.  
  126. Toast.makeText(getApplicationContext(),
  127. "保存成功,保存路径" + f.getAbsolutePath(), 1).show();
  128. }
  129.  
  130. }

默认的,在未发布的debug阶段,DrawableView会在画布上添加一些log日志输出。如果不打算在画布中显示log,可以修改DrawableView的源代码去掉DrawableView默认的log日志。关键代码有两行,在CanvasDrawer的库文件源代码中:

  1. initLogger();
  2.  
  3. ...
  4.  
  5. canvasLogger.log(canvas, canvasRect, viewRect, scaleFactor);

将这两行注释掉即可,如图:

画画板--第三方开源--DrawableView的更多相关文章

  1. IOS-常用第三方开源框架介绍

    iOS开发-常用第三方开源框架介绍(你了解的ios只是冰山一角) 时间:2015-05-06 16:43:34      阅读:533      评论:0      收藏:0      [点我收藏+] ...

  2. iOS开发-常用第三方开源框架介绍

    iOS开发-常用第三方开源框架介绍 图像: 1.图片浏览控件MWPhotoBrowser        实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网 ...

  3. 第三方开源库和jar包的区别

    jar包和第三方开源库的根本区别在于,开源库的功能比jar包功能更强大,通过引入库项目可以访问java文件以及该开源库项目下的资源文件,例如图片,layout等文件 jar包中只能放class文件 引 ...

  4. iOS常用第三方开源框架和优秀开发者博客等

    博客收藏iOS开发过程好的开源框架.开源项目.Xcode工具插件.Mac软件.文章等,会不断更新维护,希望对你们有帮助.如果有推荐或者建议,请到此处提交推荐或者联系我. 该文档已提交GitHub,点击 ...

  5. python基础知识8——模块1——自定义模块和第三方开源模块

    模块的认识 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需 ...

  6. Android Studio 简介及导入 jar 包和第三方开源库方[转]

    原文:http://blog.sina.com.cn/s/blog_693301190102v6au.html Android Studio 简介 几天前的晚上突然又想使用 Android Studi ...

  7. Android 实现图片画画板

    本文主要讲述了Android 实现图片画画板 设计项目布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk ...

  8. 开源框架】Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发

    [原][开源框架]Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发,欢迎各位... 时间 2015-01-05 10:08:18 我是程序猿,我为自己代言 原文  http: ...

  9. 粉笔网iPhone端使用的第三方开源库

    粉笔网iPhone端使用的第三方开源库 前言 最近有朋友问我粉笔网 iPhone 端使用了哪些第三方的开源库.我在这儿整理了一下,分享给大家. ASIHttpRequest ASIHttpReques ...

随机推荐

  1. 如何在组件(Component中)模拟用户控件(UserControl)中FindForm()?

    using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentM ...

  2. C#中char[]与string之间的转换

    string 转换成 Char[] string ss = "abcdefg"; char[] cc = ss.ToCharArray(); Char[] 转换成string st ...

  3. jmeter随笔(2)--上传接口报错

    黑夜小怪(2016-8-24  23:45) 微信订阅号: 问题:今天同事遇到问题,一个图片上传接口,单独跑是ok的,但是放在和其他接口一起就跑不通,如图 分析:查看该接口fiddler的抓包,发现请 ...

  4. 使用eclipse上传项目到开源中国代码托管Git@osc教程

    创建项目 安装EGit插件 没有的话看下图 生成公钥 注册git账号 新建git项目 添加公钥 建立本地代码库 本文章版权归博主所有,如需转载请私信.

  5. Tile-Based Deferred Rendering

    目前所有的移动设备都使用的是 Tile-Based Deferred Rendering(TBDR) 的渲染架构.TBDR 的基本流程是这样的,当提交渲染命令的时候,GPU 不会立刻进行渲染,而是一帧 ...

  6. 图之BFS和DFS遍历的实现并解决一次旅游中发现的问题

    这篇文章用来复习使用BFS(Breadth First Search)和DFS(Depth First Search) 并解决一个在旅游时遇到的问题. 关于图的邻接表存储与邻接矩阵的存储,各有优缺点. ...

  7. java中List Set Map使用

    @Test         public void run()        {                              ArrayList<String> list= ...

  8. iOS 根据字符串来定位地址

    - (void)viewDidLoad { [super viewDidLoad]; self.geocoder = [[CLGeocoder alloc]init]; // 设置地图可缩放 self ...

  9. PAT1075. PAT Judge

    //终于A了,不难却觉着坑多的的题,注意-1的处理,感觉我是受memset置0的束缚了,可以把初试成绩置-1.就不用debug怎么久,注意对于-1的处理,不然漏洞百出 #include<cstd ...

  10. openstack4j

    Identity // V2 authentication OSClientV2 os = OSFactory.builderV2() .endpoint("http://127.0.0.1 ...