Android 自定義View手寫簽名并保存圖片功能
GIF壓縮有問題,運(yùn)行很順滑?。?!

1.自定義View——支持設(shè)置畫筆顏色,畫筆寬度,畫板顏色,清除畫板,檢查是否有簽名,保存畫板圖片(復(fù)制粘貼可直接使用)
/**
* Created by YyyyQ on 2020/3/5.
* 電子簽名
*/
public class SignatureView extends View {
private Context context;
//X軸起點(diǎn)
private float x;
//Y軸起點(diǎn)
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;
//是否已經(jīng)簽名
private boolean isTouched = false;
//簽名開始與結(jié)束
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);
//創(chuàng)建于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;
//手指移動(dòng)
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);
// 通過畫布繪制多點(diǎn)形成的圖形
canvas.drawPath(path, paint);
}
//手指按下的方法
private void touchDwon(MotionEvent event) {
//重置繪制路徑
path.reset();
float downX = event.getX();
float downY = event.getY();
x = downX;
y = downY;
//繪制起點(diǎn)
path.moveTo(downX, downY);
}
//手指滑動(dòng)的方法
private void touchMove(MotionEvent event) {
//當(dāng)前的x,y坐標(biāo)點(diǎn)
final float moveX = event.getX();
final float moveY = event.getY();
//之前的x,y坐標(biāo)點(diǎn)
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;
}
}
/**
* 設(shè)置畫筆顏色
*
* @param paintColor
*/
public void setPaintColor(int paintColor) {
this.paintColor = paintColor;
paint.setColor(paintColor);
}
/**
* 設(shè)置畫筆寬度
*
* @param paintWidth
*/
public void setPaintWidth(int paintWidth) {
this.paintWidth = paintWidth;
paint.setStrokeWidth(paintWidth);
}
/**
* 設(shè)置畫板顏色
*
* @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(注意包名)
<?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調(diào)用
/**
* 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);
//設(shè)置畫筆顏色(可以不設(shè)置--默認(rèn)畫筆寬度10,畫筆顏色黑,背景顏色白)
signatureView.setPaintColor(Color.BLACK);
signatureView.setPaintWidth(20);
signatureView.setCanvasColor(Color.WHITE);
//清除
Button clear = findViewById(R.id.clear);
clear.setOnClickListener(view -> {
signatureView.clear();
//設(shè)置畫筆顏色(可以不設(shè)置--默認(rèn)畫筆寬度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();
}
});
}
}
總結(jié)
到此這篇關(guān)于Android 自定義View手寫簽名并保存圖片的文章就介紹到這了,更多相關(guān)Android 自定義View手寫簽名并保存圖片 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android實(shí)現(xiàn)App活動(dòng)定時(shí)自動(dòng)跳轉(zhuǎn)效果
本篇文章主要介紹了android實(shí)現(xiàn)App活動(dòng)定時(shí)自動(dòng)跳轉(zhuǎn)效果,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
Android 調(diào)用notifyDataSetChanged方法失敗解決辦法
這篇文章主要介紹了Android 調(diào)用notifyDataSetChanged方法失敗解決辦法的相關(guān)資料,需要的朋友可以參考下2017-07-07
android開發(fā)環(huán)境遇到adt無法啟動(dòng)的問題分析及解決方法
開始研究android開發(fā),搭建開發(fā)環(huán)境的時(shí)候就出了問題,真是束手無策2013-02-02
Android自定義View實(shí)現(xiàn)標(biāo)簽流效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)標(biāo)簽流效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Android提高之藍(lán)牙傳感應(yīng)用實(shí)例
這篇文章主要介紹了Android的藍(lán)牙傳感應(yīng)用實(shí)例,對于Android項(xiàng)目開發(fā)來說非常實(shí)用,需要的朋友可以參考下2014-08-08
Android?Material組件庫日期選擇和時(shí)間選擇器的使用方法
這篇文章主要介紹了Android?Material組件庫(日期選擇和時(shí)間選擇器)基本使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11
Flutter 透明狀態(tài)欄及字體顏色的設(shè)置方法
這篇文章主要介紹了Flutter 透明狀態(tài)欄及字體顏色的設(shè)置方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04

