Introduction
You may have noticed that many online retailers, including Amazon, provide a digital signature option. Utilizing a library called SignatureView will make it simple for you to add that functionality to your app.
So, here we learn about how to create a signature pad in Android Studio
Create a signature pad in Android
Step 1
Create a new project in the Android Studio and select an empty activity.
Step 2
Give the project a name, select the save location folder, and click on the finish button.
Step 3
Add the following dependency in the build.gradle app level file.
implementation 'com.kyanogen.signatureview:signature-view:1.2'
implementation 'com.github.mrudultora:Colorpicker:1.2.0'
The first dependency is used for a signature pad and another dependency is used for the color picker dialog to change the pen color.
Step 4
Add the buildFeatures and make viewBinding true in the build.gradle app level file.
buildFeatures{
viewBinding = true
}
Step 5
Add the following code in repositories in the settings.gradle file.
repositories {
google()
mavenCentral()
jcenter()
maven { url 'https://jitpack.io' }
}
Step 6
Create a layout_border.xml file using a shape under the drawable folder to give a border on the Signature Pad and ImageView.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="5dp" />
<!-- This is the border color -->
<stroke android:width="2dp" android:color="#000" />
<!--- This is the background color -->
<solid android:color="#FFF" />
</shape>
Step 7
Create the activity_main.xml file as shown below.
<?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:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="5dp"
android:textSize="25dp"
android:textColor="#000"
android:text="Signature Pad"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_margin="5dp"
android:orientation="horizontal"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:textSize="15dp"
android:layout_gravity="center"
android:text="Current Pen Color :"
android:textColor="#000"/>
<View
android:id="@+id/preview_selected_color"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:background="#000" />
<Button
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_gravity="center"
android:text="Change Pen Color"
android:textColor="#FFF"
android:backgroundTint="#298B28 "
android:layout_margin="10dp"
android:id="@+id/btnChangePenColor"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_margin="5dp"
android:background="@drawable/layout_border">
<com.kyanogen.signatureview.SignatureView
xmlns:sign="http://schemas.android.com/apk/res-auto"
android:id="@+id/signature_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
sign:penSize="5dp"
sign:backgroundColor="#ffffff"
sign:penColor="#000"
sign:enableSignature="true"
android:layout_margin="4dp"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="5dp"
android:orientation="horizontal"
android:gravity="center" >
<Button
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:text="Save"
android:textColor="#FFF"
android:backgroundTint="#298B28 "
android:layout_margin="10dp"
android:id="@+id/btnSave"/>
<Button
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:text="Clear"
android:textColor="#FFF"
android:backgroundTint="#FF0000"
android:layout_margin="10dp"
android:id="@+id/btnClear"/>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginBottom="2dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="5dp"
android:textSize="15dp"
android:text="Saved Image Display In Following ImageView"
android:textColor="#000"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="220dp"
android:background="@drawable/layout_border"
android:id="@+id/imgSignature"
android:padding="5dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="55dp"
android:layout_gravity="center"
android:text="Download Image In Gallery"
android:textColor="#FFF"
android:backgroundTint="#298B28"
android:layout_margin="10dp"
android:id="@+id/btnDownload"/>
</LinearLayout>
</LinearLayout>
Step 8
Declare objects in the MainActivity.java class.
ActivityMainBinding mainBinding;
private int mDefaultColor;
private static final int REQUEST_CODE = 1;
Step 9
Initialize ActivityMainBinding object and setContentView with ActivityMainBinding object. and also set default color colorpicker dialog.
//Initialize ActivityMainBinding Object Set ContentView As GetRoot()
mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mainBinding.getRoot());
mDefaultColor = Color.BLACK;
Step 10
Implement the Save button code to set the signature in imageview.
//Implement the Save Button Code
mainBinding.btnSave.setOnClickListener(view -> {
Bitmap bitmap = mainBinding.signatureView.getSignatureBitmap();
if(bitmap != null)
{
mainBinding.imgSignature.setImageBitmap(bitmap);
}
});
Step 11
Implement the Clear button code to clear the signature pad.
//Implement the Clear Button Code
mainBinding.btnClear.setOnClickListener(view -> {
mainBinding.signatureView.clearCanvas();
});
Step 12
Implement the Download Image In Gallery button code to download an image in the gallery. Here, we must obtain the uses-permission, WRITE_EXTERNAL_STORAGE.
//Implement the Download Image In Gallery Button Code
mainBinding.btnDownload.setOnClickListener(view -> {
mainBinding.imgSignature.buildDrawingCache();
if(ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
{
saveImage();
}
else
{
ActivityCompat.requestPermissions(MainActivity.this,new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_CODE);
}
});
Step 13
Implement the onRequestPermissionsResult code as follows.
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
if(requestCode == REQUEST_CODE)
{
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
saveImage();
}
else
{
Toast.makeText(MainActivity.this,"Please provide required permission",Toast.LENGTH_SHORT).show();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
Step 14
Include write permission for external storage and read permission for external storage in the manifests file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Step 15
Now write the following code for the saveImage() function.
public void saveImage()
{
Uri images;
ContentResolver contentResolver = getContentResolver();
BitmapDrawable bitmapDrawable = (BitmapDrawable)mainBinding.imgSignature.getDrawable();
try {
Bitmap bmp = bitmapDrawable.getBitmap();
if(bmp != null)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
images = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
}
else
{
images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME,"Digital_Sign_" + System.currentTimeMillis() + ".jpg");
contentValues.put(MediaStore.Images.Media.MIME_TYPE,"images/*");
Uri uri = contentResolver.insert(images,contentValues);
try {
OutputStream outputStream = contentResolver.openOutputStream(Objects.requireNonNull(uri));
bmp.compress(Bitmap.CompressFormat.JPEG,80,outputStream);
Objects.requireNonNull(outputStream);
Toast.makeText(MainActivity.this,"Digital Signature Save Successfully",Toast.LENGTH_SHORT).show();
}catch(Exception e){
Toast.makeText(MainActivity.this,"Error : " + e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(MainActivity.this,"Please Generate Digital Signature To Save",Toast.LENGTH_SHORT).show();
}
}catch(Exception e)
{
Toast.makeText(MainActivity.this,"Please Generate Digital Signature To Save",Toast.LENGTH_SHORT).show();
}
}
Step 16
Implement the Change Pen Color button code to set the pen colour of the signature pad.
//Implement the Change Pen Color Code to pen color of signature pad.
mainBinding.btnChangePenColor.setOnClickListener(view->{
ColorPickerPopUp colorPickerPopUp = new ColorPickerPopUp(MainActivity.this);
colorPickerPopUp.setShowAlpha(true)
.setDefaultColor(mDefaultColor)
.setDialogTitle("Pick a Color")
.setOnPickColorListener(new ColorPickerPopUp.OnPickColorListener() {
@Override
public void onColorPicked(int color) {
mainBinding.previewSelectedColor.setBackgroundColor(color); // Set color in view
mainBinding.signatureView.setPenColor(color); // Set color in pen
mDefaultColor = color;
}
@Override
public void onCancel() {
colorPickerPopUp.dismissDialog();
}
})
.show();
});
Final MainActivity.Java File
package com.uday.signaturepaddemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.Toast;
import com.mrudultora.colorpicker.ColorPickerPopUp;
import com.uday.signaturepaddemo.databinding.ActivityMainBinding;
import java.io.OutputStream;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding mainBinding;
private int mDefaultColor;
private static final int REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Initialize ActivityMainBinding Object Set ContentView As GetRoot()
mainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mainBinding.getRoot());
mDefaultColor = Color.BLACK;
//Implement the Save Button Code
mainBinding.btnSave.setOnClickListener(view -> {
Bitmap bitmap = mainBinding.signatureView.getSignatureBitmap();
if(bitmap != null)
{
mainBinding.imgSignature.setImageBitmap(bitmap);
}
});
//Implement the Clear Button Code
mainBinding.btnClear.setOnClickListener(view -> {
mainBinding.signatureView.clearCanvas();
});
//Implement the Download Image In Gallery Button Code
mainBinding.btnDownload.setOnClickListener(view -> {
mainBinding.imgSignature.buildDrawingCache();
if(ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
{
saveImage();
}
else
{
ActivityCompat.requestPermissions(MainActivity.this,new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE
},REQUEST_CODE);
}
});
//Implement the Change Pen Color Code to pen color of signature pad.
mainBinding.btnChangePenColor.setOnClickListener(view->{
ColorPickerPopUp colorPickerPopUp = new ColorPickerPopUp(MainActivity.this);
colorPickerPopUp.setShowAlpha(true)
.setDefaultColor(mDefaultColor)
.setDialogTitle("Pick a Color")
.setOnPickColorListener(new ColorPickerPopUp.OnPickColorListener() {
@Override
public void onColorPicked(int color) {
mainBinding.previewSelectedColor.setBackgroundColor(color); // Set color in view
mainBinding.signatureView.setPenColor(color); // Set color in pen
mDefaultColor = color;
}
@Override
public void onCancel() {
colorPickerPopUp.dismissDialog();
}
})
.show();
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == REQUEST_CODE)
{
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
saveImage();
}
else
{
Toast.makeText(MainActivity.this,"Please provide required permission",Toast.LENGTH_SHORT).show();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void saveImage(){
Uri images;
ContentResolver contentResolver = getContentResolver();
BitmapDrawable bitmapDrawable = (BitmapDrawable)mainBinding.imgSignature.getDrawable();
try {
Bitmap bmp = bitmapDrawable.getBitmap();
if(bmp != null)
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
images = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
}
else
{
images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME,"Digital_Sign_" + System.currentTimeMillis() + ".jpg");
contentValues.put(MediaStore.Images.Media.MIME_TYPE,"images/*");
Uri uri = contentResolver.insert(images,contentValues);
try {
OutputStream outputStream = contentResolver.openOutputStream(Objects.requireNonNull(uri));
bmp.compress(Bitmap.CompressFormat.JPEG,80,outputStream);
Objects.requireNonNull(outputStream);
Toast.makeText(MainActivity.this,"Digital Signature Save Successfully",Toast.LENGTH_SHORT).show();
}catch(Exception e){
Toast.makeText(MainActivity.this,"Error : " + e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(MainActivity.this,"Please Generate Digital Signature To Save",Toast.LENGTH_SHORT).show();
}
}catch(Exception e)
{
Toast.makeText(MainActivity.this,"Please Generate Digital Signature To Save",Toast.LENGTH_SHORT).show();
}
}
}
Step 17
Now run your app.
Step 18
After that, write anything in the signature pad, click the save button, and the image will appear in imageview; click the Download Image in Gallery button to save the image in gallery.
Step 19
To change the colour of your pen, click the Change Pen Color button and choose a color. and type whatever you want, then click the save button, then click the Download Image In Gallery button to save the image in the gallery.
Step 20
You check your gallery, and you see our saved images.
Summary
As you can see, creating a signature pad on Android is very simple.
In this article, we learned how to create an Android signature pad.
And here I have also uploaded a demo project, so you can download it and try it for yourself.
Thank you for reading my article. Please leave your comments in the comment box below.
Enjoy Coding.