我是靠谱客的博主 怕黑羽毛,这篇文章主要介绍Android 自定义View手写签名并保存图片功能,现在分享给大家,希望可以做个参考。

GIF压缩有问题,运行很顺滑!!!

 1.自定义View——支持设置画笔颜色,画笔宽度,画板颜色,清除画板,检查是否有签名,保存画板图片(复制粘贴可直接使用)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/** * Created by YyyyQ on 2020/3/5. * 电子签名 */ public class SignatureView extends View { private Context context; //X轴起点 private float x; //Y轴起点 private float y; //画笔 private final Paint paint = new Paint(); //路径 private final Path path = new Path(); //画布 private Canvas canvas; //生成的图片 private Bitmap bitmap; //画笔的宽度 private int paintWidth = 10; //签名颜色 private int paintColor = Color.BLACK; //背景颜色 private int backgroundColor = Color.WHITE; //是否已经签名 private boolean isTouched = false; //签名开始与结束 public interface Touch { void OnTouch(boolean isTouch); } private Touch touch; public SignatureView(Context context) { super(context); init(context); } public SignatureView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); } public SignatureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { this.context = context; //抗锯齿 paint.setAntiAlias(true); //样式 paint.setStyle(Paint.Style.STROKE); //画笔颜色 paint.setColor(paintColor); //画笔宽度 paint.setStrokeWidth(paintWidth); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //创建于view大小一致的bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); canvas = new Canvas(bitmap); canvas.drawColor(backgroundColor); isTouched = false; } @Override public boolean onTouchEvent(MotionEvent event) { if (touch != null) touch.OnTouch(true); switch (event.getAction()) { //手指按下 case MotionEvent.ACTION_DOWN: touchDwon(event); break; //手指移动 case MotionEvent.ACTION_MOVE: isTouched = true; if (touch != null) touch.OnTouch(false); touchMove(event); break; //手指抬起 case MotionEvent.ACTION_UP: canvas.drawPath(path, paint); path.reset(); break; } // 更新绘制 invalidate(); return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画此次笔画之前的签名 canvas.drawBitmap(bitmap, 0, 0, paint); // 通过画布绘制多点形成的图形 canvas.drawPath(path, paint); } //手指按下的方法 private void touchDwon(MotionEvent event) { //重置绘制路径 path.reset(); float downX = event.getX(); float downY = event.getY(); x = downX; y = downY; //绘制起点 path.moveTo(downX, downY); } //手指滑动的方法 private void touchMove(MotionEvent event) { //当前的x,y坐标点 final float moveX = event.getX(); final float moveY = event.getY(); //之前的x,y坐标点 final float previousX = x; final float previousY = y; //获取绝对值 final float dx = Math.abs(moveX - previousX); final float dy = Math.abs(moveY - previousY); if (dx >= 3 || dy >= 3) { float cX = (moveX + previousX) / 2; float cY = (moveY + previousY) / 2; path.quadTo(previousX, previousY, cX, cY); x = moveX; y = moveY; } } /** * 设置画笔颜色 * * @param paintColor */ public void setPaintColor(int paintColor) { this.paintColor = paintColor; paint.setColor(paintColor); } /** * 设置画笔宽度 * * @param paintWidth */ public void setPaintWidth(int paintWidth) { this.paintWidth = paintWidth; paint.setStrokeWidth(paintWidth); } /** * 设置画板颜色 * * @param canvasColor */ public void setCanvasColor(int canvasColor) { this.backgroundColor = canvasColor; } /** * 清除画板 */ public void clear() { if (canvas != null) { isTouched = false; //更新画板 paint.setColor(paintColor); paint.setStrokeWidth(paintWidth); canvas.drawColor(backgroundColor, PorterDuff.Mode.CLEAR); invalidate(); } } /** * 获取画板的Bitmap * * @return */ public Bitmap getBitmap() { setDrawingCacheEnabled(true); buildDrawingCache(); Bitmap bitmap = getDrawingCache(); setDrawingCacheEnabled(false); return bitmap; } /** * 是否有签名 * * @return */ public Boolean getSigstatus() { return isTouched; } /** * 保存画板 * * @param path 保存到路径 */ @SuppressLint("WrongThread") public Boolean save(String path) throws IOException { Bitmap bitmap = this.bitmap; ByteArrayOutputStream bos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); byte[] buffer = bos.toByteArray(); if (buffer != null) { File file = new File(path); if (file.exists()) { file.delete(); } OutputStream outputStream = new FileOutputStream(file); outputStream.write(buffer); outputStream.close(); return true; } else { return false; } } }

 2.xml布局引用自定义View(注意包名)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!--自定义view的绝对路径--> <com.example.customviewdemo.view.SignatureView android:id="@+id/signature" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:background="#fff" /> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_margin="20dp" android:orientation="horizontal"> <Button android:id="@+id/clear" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="清除" /> <Button android:id="@+id/isSignature" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_weight="1" android:gravity="center" android:text="是否签名" /> <Button android:id="@+id/save" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_weight="1" android:gravity="center" android:text="保存" /> </LinearLayout> </LinearLayout>

 3.Activity调用

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/** * Created by YyyyQ on 2020/3/9. */ public class SignatureActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_signature); SignatureView signatureView = findViewById(R.id.signature); //设置画笔颜色(可以不设置--默认画笔宽度10,画笔颜色黑,背景颜色白) signatureView.setPaintColor(Color.BLACK); signatureView.setPaintWidth(20); signatureView.setCanvasColor(Color.WHITE); //清除 Button clear = findViewById(R.id.clear); clear.setOnClickListener(view -> { signatureView.clear(); //设置画笔颜色(可以不设置--默认画笔宽度10,画笔颜色黑,背景颜色白) signatureView.setPaintColor(Color.BLACK); signatureView.setPaintWidth(20); signatureView.setCanvasColor(Color.WHITE); }); //是否含有签名 Button isSignature = findViewById(R.id.isSignature); isSignature.setOnClickListener(view -> { if (signatureView.getSigstatus()) { Toast.makeText(SignatureActivity.this, "有签名", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(SignatureActivity.this, "无签名", Toast.LENGTH_SHORT).show(); } }); //保存 Button save = findViewById(R.id.save); save.setOnClickListener(view -> { try { if (signatureView.save("/sdcard/YyyyQ.png")) { Toast.makeText(SignatureActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(SignatureActivity.this, "保存失败", Toast.LENGTH_SHORT).show(); } } catch (IOException e) { e.printStackTrace(); } }); } }

总结

到此这篇关于Android 自定义View手写签名并保存图片的文章就介绍到这了,更多相关Android 自定义View手写签名并保存图片 内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!

最后

以上就是怕黑羽毛最近收集整理的关于Android 自定义View手写签名并保存图片功能的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(90)

评论列表共有 0 条评论

立即
投稿
返回
顶部