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就可以在一个独 ...
随机推荐
- [转帖]Titan 配置
https://www.bookstack.cn/read/TiDB-4.0/storage-engine-titan-configuration.md 开启 Titan Titan 对 RocksD ...
- [转帖]JVM 参数
https://www.cnblogs.com/xiaojiesir/p/15636100.html 我们可以在启动 Java 命令时指定不同的 JVM 参数,让 JVM 调整自己的运行状态和行为,内 ...
- Harbor简单搭建以及异常排查的过程与思路
Harbor简单搭建以及异常排查的过程与思路 前言 我发现我总是能够遇到别人遇不到的问题. 本来搭建十分钟就可以搭建完成 结果我硬生生的搭建了四十分钟. 为了保证下次不再浪费时间. 这里加单总结一下遇 ...
- AI五子棋 C++ 借助图形库raylib和raygui 设计模式思考过程和实现思路总结
转载请注明 原文链接 :https://www.cnblogs.com/Multya/p/17988499 repo: https://github.com/Satar07/AI_GoBang_Pub ...
- Vue3中readonly 和 shallowReadonly和toRaw
1.readonly 深度只读 被readonly包裹的数据只能够读取. 是一个深度只读,不能够修改. 我们看一下面的代码. 我们想修改值,但是修改后视图无响应. 并且控制台警告目标为只读 reado ...
- RC4加密技术探究:优缺点与实战应用
引言 在网络安全领域,加密技术一直是保障数据安全的重要手段.Rivest Cipher 4(简称RC4)作为一种对称加密算法,自20世纪80年代以来广泛应用于各种网络安全协议中.本文将详细分析RC4加 ...
- ABP .net Core 将日志打印在控制台
上效果图 来看一下操作流程: 一.分为.net Core 2.2 和 .net Core 3.0及以上 (一)..net Core 2.2 1.在 EntityFrameworkCore中安装Nuge ...
- 驱动开发:内核读取SSDT表基址
在前面的章节<X86驱动:挂接SSDT内核钩子>我们通过代码的方式直接读取 KeServiceDescriptorTable 这个被导出的表结构从而可以直接读取到SSDT表的基址,而在Wi ...
- requests模块的高级应用
requests抓取数据报错 - HttpConnectinPool: - 原因: - 1.短时间内发起了高频的请求导致ip被禁 - 2.http连接池中的连接资源被耗尽 - 解决: - 1.代理 - ...
- Delphi中 调试 指针
p1.Free; 释放堆中数据,最终无内存泄漏,只是加深记忆: 有些时候 灵活应对: