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 实现手写板技术相关推荐

  1. 【错误记录】Android 编译时技术报错 ( 注解处理器 process 方法多次调用问题 )

    文章目录 一.报错信息 二.问题分析 三.解决方案 注解处理器 AbstractProcessor 中的 process 方法可能会调用多次 , 在生成代码时 , 一定要注意 , 检测到 注解节点 后 ...

  2. 【错误记录】Android 编译时技术版本警告 ( 注解处理器与主应用支持的 Java 版本不匹配 )

    文章目录 一.报错信息 二.问题分析 三.解决方案 一.报错信息 在使用 Android 编译时技术 , 涉及 编译时注解 , 注解处理器 ; 开发注解处理器后 , 编译报如下警告 ; 该警告不会影响 ...

  3. 深入解析阿里Android热修复技术原理

    前言:本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简 ...

  4. android 蓝牙传输分包,彻底掌握Android多分包技术(一)

    原标题:彻底掌握Android多分包技术MultiDex-用Ant和Gradle分别构建(一) Andrid多分包技术在大型项目编译方面起着至关重要的作用,作为一个高级开发者我们有必要掌握此技能,现在 ...

  5. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  6. 【Android应用保护技术探索之路系列】之一:Android应用保护技术开篇

    [Android应用保护技术探索之路系列]章节目录 [Android应用保护技术探索之路系列]之一:Android应用保护技术开篇  [Android应用保护技术探索之路系列]之二:对抗反编译  [A ...

  7. Android Art Hook 技术方案

    Android Art Hook 技术方案 by 低端码农 at 2015.4.13 www.im-boy.net 0x1 开始 Anddroid上的ART从5.0之后变成默认的选择,可见ART的重要 ...

  8. android平台应用技术特点,Android平台应用安全关键技术研究

    摘要: 最近几年来,随着智能手机的普及和移动互联网技术的发展,手机成了人们日常生活中不可缺少的一部分.在众多的智能手机操作系统里面,Android系统以其开源,自由,免费等特点占有着很大的市场占有率. ...

  9. 深入探索android热修复技术原理_打卡活动:技术书籍书单

    不知不觉,码个蛋打卡活动都已经60多天了,好多小伙伴都已经可以领取第一波奖励:技术书籍了,上周好多小伙伴私信码仔,问都有哪些技术书籍,码仔今天就给大家列了个书单供大家选择: 01 Android软件安 ...

最新文章

  1. Python与C语言基础对比(Python快速入门)
  2. php 获取所有下周1,用php获取本周,下周,本月,下月,本季度日期(摘)
  3. SpringBoot笔记:SpringBoot集成MinIO分布式文件系统
  4. VTK:可视化之AssignCellColorsFromLUT
  5. Matlab中plot函数绘图基本用法
  6. 【设计模式】单例模式 Singleton Pattern
  7. leetcode初级算法2.旋转数组
  8. ubuntu安装配置jdk
  9. C++工作笔记-WM_KEYFIRST和WM_KEYDOWN的用法
  10. 我如何使用Python帮助我选择了Google Summer of Code '19的组织
  11. 带着canvas去流浪系列之六 绘制雷达图
  12. java 判断值是否设置,获取Java中“-非法访问”设置的当前值
  13. RedHat Linux 9.0 操作系统测试题2
  14. 七月算法机器学习1 概率论
  15. 号称最为简明实用的Django上手教程
  16. Postman教程——发送第一个请求
  17. Mac在pycharm执行sh打包脚本报错
  18. 数据的探索性分析(EDA)
  19. JAVAWEB之JSTL标签
  20. 计算机硬盘无法启动怎么办,电脑硬盘不读盘无法开机怎么办

热门文章

  1. MySql 你知道事务隔离是怎么回事吗?
  2. JavaScript中的Math方法演示
  3. Spring Boot 面试题整理
  4. Java 多条件复杂排序小结
  5. .魔术方法、魔术常量
  6. NEU(Fst Network Embedding Enhancement via High Order Proximity Approximation)
  7. java对存放实体的list进行排序
  8. Codeforces Round #445 div.2 D. Restoration of string 乱搞
  9. 模仿网易新闻客户端的滚动菜单
  10. hdu 2188巴什博弈