Android 实现手写板技术
Android手写板和涂鸦的功能,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:greendroid="http://schemas.android.com/apk/res/com.cyrilmottier.android.gdcatalog" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:id="@+id/tablet_view" android:layout_width="fill_parent" android:layout_height="300dp" > </FrameLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:drawable/bottom_bar" android:paddingTop="4dp" > <Button android:id="@+id/write_pad_ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="确定" /> <Button android:id="@+id/write_pad_clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="清除" /> <Button android:id="@+id/write_pad_cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="取消" /> </LinearLayout> </LinearLayout>
public class MainActivity extends Activity { private ImageView mIVSign; private TextView mTVSign; private Bitmap mSignBitmap; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIVSign = (ImageView) findViewById(R.id.iv_sign); mTVSign = (TextView) findViewById(R.id.tv_sign); mTVSign.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { WritePadDialog mWritePadDialog = new WritePadDialog( MainActivity.this, new WriteDialogListener() { @Override public void onPaintDone(Object object) { mSignBitmap = (Bitmap) object; createSignFile(); mIVSign.setImageBitmap(mSignBitmap); mTVSign.setVisibility(View.GONE); } }); mWritePadDialog.show(); } }); } //创建签名文件 private void createSignFile() { ByteArrayOutputStream baos = null; FileOutputStream fos = null; String path = null; File file = null; try { path = Environment.getExternalStorageDirectory() + File.separator + System.currentTimeMillis() + ".jpg"; file = new File(path); fos = new FileOutputStream(file); baos = new ByteArrayOutputStream(); //如果设置成Bitmap.compress(CompressFormat.JPEG, 100, fos) 图片的背景都是黑色的 mSignBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] b = baos.toByteArray(); if (b != null) { fos.write(b); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fos != null) { fos.close(); } if (baos != null) { baos.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
public class PaintView extends View { private Paint mPaint; private Path mPath; private Bitmap mBitmap; private Canvas mCanvas; private int screenWidth, screenHeight; private float currentX, currentY; public PaintView(Context context, int screenWidth, int screenHeight) { super(context); this.screenWidth = screenWidth; this.screenHeight = screenHeight; init(); } private void init() { mPaint = new Paint(); mPaint.setAntiAlias(true); // 去除锯齿 mPaint.setStrokeWidth(5); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.BLACK); mPath = new Path(); mBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888); mCanvas = new Canvas(mBitmap); // mCanvas.drawColor(Color.WHITE); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, 0, null); canvas.drawPath(mPath, mPaint); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: currentX = x; currentY = y; mPath.moveTo(currentX, currentY); break; case MotionEvent.ACTION_MOVE: currentX = x; currentY = y; mPath.quadTo(currentX, currentY, x, y); // 画线 break; case MotionEvent.ACTION_UP: mCanvas.drawPath(mPath, mPaint); break; } invalidate(); return true; } public Bitmap getPaintBitmap() { return resizeImage(mBitmap, 320, 480); } public Path getPath() { return mPath; } // 缩放 public static Bitmap resizeImage(Bitmap bitmap, int width, int height) { int originWidth = bitmap.getWidth(); int originHeight = bitmap.getHeight(); float scaleWidth = ((float) width) / originWidth; float scaleHeight = ((float) height) / originHeight; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, originWidth, originHeight, matrix, true); return resizedBitmap; } //清除画板 public void clear() { if (mCanvas != null) { mPath.reset(); mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); invalidate(); } } }
public class WritePadDialog extends Dialog { private Context mContext; private WriteDialogListener mWriteDialogListener; private PaintView mPaintView; private FrameLayout mFrameLayout; private Button mBtnOK, mBtnClear, mBtnCancel; public WritePadDialog(Context context, WriteDialogListener writeDialogListener) { super(context); this.mContext = context; this.mWriteDialogListener = writeDialogListener; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); //无标题 setContentView(R.layout.write_pad); mFrameLayout = (FrameLayout) findViewById(R.id.tablet_view); // 获取屏幕尺寸 DisplayMetrics mDisplayMetrics = new DisplayMetrics(); getWindow().getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics); int screenWidth = mDisplayMetrics.widthPixels; int screenHeight = mDisplayMetrics.heightPixels; mPaintView = new PaintView(mContext, screenWidth, screenHeight); mFrameLayout.addView(mPaintView); mPaintView.requestFocus(); mBtnOK = (Button) findViewById(R.id.write_pad_ok); mBtnOK.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mPaintView.getPath().isEmpty()) { Toast.makeText(mContext, "请写下你的大名", Toast.LENGTH_SHORT).show(); return; } mWriteDialogListener.onPaintDone(mPaintView.getPaintBitmap()); dismiss(); } }); mBtnClear = (Button) findViewById(R.id.write_pad_clear); mBtnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPaintView.clear(); } }); mBtnCancel = (Button) findViewById(R.id.write_pad_cancel); mBtnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cancel(); } }); } }
/** * 监听手写板对话框* @author chengcj1 * */ public interface WriteDialogListener { public void onPaintDone(Object object); }
转载于:https://www.cnblogs.com/renhui/p/7691133.html
Android 实现手写板技术相关推荐
- 【错误记录】Android 编译时技术报错 ( 注解处理器 process 方法多次调用问题 )
文章目录 一.报错信息 二.问题分析 三.解决方案 注解处理器 AbstractProcessor 中的 process 方法可能会调用多次 , 在生成代码时 , 一定要注意 , 检测到 注解节点 后 ...
- 【错误记录】Android 编译时技术版本警告 ( 注解处理器与主应用支持的 Java 版本不匹配 )
文章目录 一.报错信息 二.问题分析 三.解决方案 一.报错信息 在使用 Android 编译时技术 , 涉及 编译时注解 , 注解处理器 ; 开发注解处理器后 , 编译报如下警告 ; 该警告不会影响 ...
- 深入解析阿里Android热修复技术原理
前言:本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简 ...
- android 蓝牙传输分包,彻底掌握Android多分包技术(一)
原标题:彻底掌握Android多分包技术MultiDex-用Ant和Gradle分别构建(一) Andrid多分包技术在大型项目编译方面起着至关重要的作用,作为一个高级开发者我们有必要掌握此技能,现在 ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- 【Android应用保护技术探索之路系列】之一:Android应用保护技术开篇
[Android应用保护技术探索之路系列]章节目录 [Android应用保护技术探索之路系列]之一:Android应用保护技术开篇 [Android应用保护技术探索之路系列]之二:对抗反编译 [A ...
- Android Art Hook 技术方案
Android Art Hook 技术方案 by 低端码农 at 2015.4.13 www.im-boy.net 0x1 开始 Anddroid上的ART从5.0之后变成默认的选择,可见ART的重要 ...
- android平台应用技术特点,Android平台应用安全关键技术研究
摘要: 最近几年来,随着智能手机的普及和移动互联网技术的发展,手机成了人们日常生活中不可缺少的一部分.在众多的智能手机操作系统里面,Android系统以其开源,自由,免费等特点占有着很大的市场占有率. ...
- 深入探索android热修复技术原理_打卡活动:技术书籍书单
不知不觉,码个蛋打卡活动都已经60多天了,好多小伙伴都已经可以领取第一波奖励:技术书籍了,上周好多小伙伴私信码仔,问都有哪些技术书籍,码仔今天就给大家列了个书单供大家选择: 01 Android软件安 ...
最新文章
- Python与C语言基础对比(Python快速入门)
- php 获取所有下周1,用php获取本周,下周,本月,下月,本季度日期(摘)
- SpringBoot笔记:SpringBoot集成MinIO分布式文件系统
- VTK:可视化之AssignCellColorsFromLUT
- Matlab中plot函数绘图基本用法
- 【设计模式】单例模式 Singleton Pattern
- leetcode初级算法2.旋转数组
- ubuntu安装配置jdk
- C++工作笔记-WM_KEYFIRST和WM_KEYDOWN的用法
- 我如何使用Python帮助我选择了Google Summer of Code '19的组织
- 带着canvas去流浪系列之六 绘制雷达图
- java 判断值是否设置,获取Java中“-非法访问”设置的当前值
- RedHat Linux 9.0 操作系统测试题2
- 七月算法机器学习1 概率论
- 号称最为简明实用的Django上手教程
- Postman教程——发送第一个请求
- Mac在pycharm执行sh打包脚本报错
- 数据的探索性分析(EDA)
- JAVAWEB之JSTL标签
- 计算机硬盘无法启动怎么办,电脑硬盘不读盘无法开机怎么办
热门文章
- MySql 你知道事务隔离是怎么回事吗?
- JavaScript中的Math方法演示
- Spring Boot 面试题整理
- Java 多条件复杂排序小结
- .魔术方法、魔术常量
- NEU(Fst Network Embedding Enhancement via High Order Proximity Approximation)
- java对存放实体的list进行排序
- Codeforces Round #445 div.2 D. Restoration of string 乱搞
- 模仿网易新闻客户端的滚动菜单
- hdu 2188巴什博弈