Android使用SurfaceView实现签名板
SurfaceView使用
首先创建一个SurfaceViewSign类,继承SurfaceView类,继承 SurfaceHolder.Callback和Runnable接口,代码如下:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfaceViewSign extends SurfaceView implements SurfaceHolder.Callback,Runnable {
//SurfaceHolder
private SurfaceHolder holder;
//用于绘图的Canvas
private Canvas canvas;
//子线程标志位
private boolean isDrawing;
//画笔
private Paint paint;
//路径
private Path path;
private Bitmap bitmap;
private Canvas getCanvas;
/**
* 获取mCanvas里的bitmap
* */
public Bitmap getBitmap() {
getCanvas.drawColor(Color.WHITE);//画布背景色
getCanvas.drawPath(path, paint);
getCanvas.save();
getCanvas.restore();
return bitmap;
//region bitmap压缩到文件
// File file = new File(Environment.getExternalStorageDirectory().getPath() + "/share_pic.png");// 保存到sdcard根目录下,文件名为share_pic.png
// FileOutputStream fos = null;
// try {
// fos = new FileOutputStream(file);
// bitmap.compress(Bitmap.CompressFormat.PNG, 50, fos);
//
// } catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// try {
// fos.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//endregion
}
public SurfaceViewSign(Context context) {
super(context);
initView();
}
public SurfaceViewSign(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public SurfaceViewSign(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
bitmap = Bitmap.createBitmap(1000,1000, Bitmap.Config.ARGB_8888);
getCanvas = new Canvas(bitmap);
holder = getHolder();
//添加回调
holder.addCallback(this);
path =new Path();
//初始化画笔
paint =new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(6);
paint.setAntiAlias(true);
paint.setColor(Color.RED);//画笔颜色
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
}
//Surface的生命周期
@Override
public void surfaceCreated(SurfaceHolder holder) {
isDrawing =true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isDrawing =false;
}
@Override
public void run() {
long start =System.currentTimeMillis();
while(isDrawing){
draw();
long end = System.currentTimeMillis();
if(end-start<100){
try{
Thread.sleep(100-end+start);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void draw() {
try{
//锁定画布并返回画布对象
canvas = holder.lockCanvas();
canvas.drawColor(Color.WHITE);//设置画布背景色
canvas.drawPath(path, paint); //画线
}catch (Exception e){
}finally {
if(canvas !=null)
holder.unlockCanvasAndPost(canvas);//解锁
}
}
/**
* 绘制触摸滑动路径
* @param event MotionEvent
* @return true
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
int x=(int) event.getX();
int y= (int) event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
path.moveTo(x,y);
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(x,y);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
/**
* 清屏
* @return true
*/
public boolean reDraw(){
path.reset();
return true;
}
}
然后创建一个测试Activity,然后编写他的页面代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:background="@color/white"
tools:ignore="MissingClass">
<com.kiba.test.control.surfaceview.SurfaceViewSign
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/red"></View>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
></ImageView> </LinearLayout>
然后在activity里编写点击事件如下:
@SingleClick
@OnClick(R.id.imageView)
public void ImageClick()
{
Bitmap bitmap =sv.getBitmap();
imageView.setImageBitmap(bitmap);
imageView2.setImageBitmap(bitmap);
}
这样就实现了简单的签名,并且获取到了签名的图片,类型是bitmap。
效果图如下:

----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

Android使用SurfaceView实现签名板的更多相关文章
- Android 之surfaceView (画动态圆圈)
通过之前介绍的如何自定义View, 我们知道使用它可以做一些简单的动画效果.它通过不断循环的执行View.onDraw方法,每次执行都对内部显示的图形做一些调整,我们假设 onDraw方法每秒执行 ...
- Android 利用SurfaceView进行图形绘制
SurfaceView使用介绍 SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作. 要使用SurfaceView进行绘制,步骤如下: 1.用SurfaceView ...
- Android使用SurfaceView实现墨迹天气的风车效果
SurfaceView也是继承自View,它和我们以前接触到的View(Button.TextView等)最大的不同是,SurfaceView可以有一个单独的线程进行绘制,这个线程区别于UI线程(主线 ...
- Android之SurfaceView
SurfaceView也是继承了View,但是我们并不需要去实现它的draw方法来绘制自己,为什么呢? 因为它和View有一个很大的区别,View在UI线程去更新自己:而SurfaceView则在一个 ...
- Android之SurfaceView学习(一)
对应的中文翻译SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface.你可以控制这个Surface的格式和尺寸.Surfaceview控制这个Surface ...
- Android中SurfaceView的使用详解
Android中SurfaceView的使用详解 http://blog.csdn.net/listening_music/article/details/6860786 Android NDK开发 ...
- Android之SurfaceView学习
首先我们先来看下官方API对SurfaceView的介绍 SurfaceView的API介绍 Provides a dedicated drawing surface embedded inside ...
- Android之SurfaceView学习(一)转转
Android之SurfaceView学习(一) 首先我们先来看下官方API对SurfaceView的介绍 SurfaceView的API介绍 Provides a dedicated drawing ...
- Android中SurfaceView用法示例
SurfaceView在游戏开发中有着举足轻重的地位,它对于画面的控制有着更大的自由度(不像View要用handler来更新,关于View的),但这方面的参考资料并不是太多,能找到的例子都有点喧宾夺主 ...
- Android视图SurfaceView的实现原理分析(示例,出错代码)
在Android系统中,有一种特殊的视图,称为SurfaceView,它拥有独立的绘图表面,即它不与其宿主窗口共享同一个绘图表面.由于拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独 ...
随机推荐
- [转帖]【linux命令学习】— sar 命令学习
https://blog.csdn.net/u013332124/article/details/101075521 一.命令使用介绍 sar命令全称 System Activity Report,它 ...
- [转帖]使用S3F3在Linux实例上挂载Bucket
https://docs.jdcloud.com/cn/object-storage-service/s3fs S3F3是基于FUSE的文件系统,允许Linux 挂载Bucket在本地文件系统,S3f ...
- [转帖]FIO 存储性能压测
一. FIO简介 FIO 是一个多线程IO生成工具,可以生成多种IO模式(随机.顺序.读.写四大类),用来测试磁盘设备的性能.GFIO是FIO的图形监测工具,它提供了图形界面的参数配置,和性能监测图像 ...
- 虚拟化平台IO劣化分析
虚拟化平台IO劣化分析 背景 最近同事让帮忙做几个虚拟机进行性能测试. 本来应该搭建CentOS/Winodws平台进行相关的测试工作. 但是为了环境一致性, 使用了ESXi6.7 进行虚拟化 然后这 ...
- [转帖]Linux—CPU核数、上下文切换介绍及pidstat等命令详解
https://www.jianshu.com/p/0ae0c1153c34 关注:CodingTechWork,一起学习进步. 引言 并发编程 并发编程的目的是为了改善串行程序执行慢问题,但是, ...
- React类组件中事件绑定this指向的三种方式
有状态组件和无状态组件 函数组件又叫做无状态组件,类组件又叫做有状态组件. 状态又叫做数据 函数组件没有自己的状态,只负责静态页面的展示. 我们可以理解为纯ui展示.() 类组件有自己的状态,扶着更新 ...
- js赋值的两种方式
第一种 let obj=[ { value:undefined } ] obj[0].value.value='zahngsan' obj[0].value.label='张三' 机智的小伙伴,可能已 ...
- 手写promise异步状态修改then方法返回来的结果
看看下面这一段代码返回来的是什么??? <body> <script type="text/javascript"> let p = new Promise ...
- Fabric网络升级(四)
原文来自这里. 用户从v1.4.x升级到v2.x后,必须编辑通道配置来启用新的lifecycle功能.这个过程涉及到相关用户必须执行的一系列通道配置更新. 要启用新的chaincode lifecyc ...
- 【OpenIM原创】简单轻松入门 一文讲解WebRTC实现1对1音视频通信原理
什么是 WebRTC ? WebRTC(Web Real-Time Communication)是 Google于2010以6829万美元从 Global IP Solutions 公司购买,并于20 ...