---
title: "Custom Electronic Signature"
canonical_url: "https://www.nutrient.io/guides/android/samples/custom-electronic-signature-java/"
md_url: "https://www.nutrient.io/guides/android/samples/custom-electronic-signature-java.md"
last_updated: "2026-05-15T19:10:04.916Z"
description: "Build a custom ink signature flow with ElectronicSignatureFragment in a PdfFragment activity."
---

# Custom Electronic Signature

Build a custom ink signature flow with ElectronicSignatureFragment in a PdfFragment activity.

[Get Started](https://www.nutrient.io/sdk/android/getting-started.md)

[All Samples](https://www.nutrient.io/guides/android/samples.md)

[Download](https://www.nutrient.io/guides/android/downloads.md)

[Launch Demo](https://www.nutrient.io/demo/)

---

```java

/*
 *   Copyright © 2017-2026 PSPDFKit GmbH. All rights reserved.
 *
 *   The PSPDFKit Sample applications are licensed with a modified BSD license.
 *   Please see License for details. This notice may not be removed from this file.
 */

package com.pspdfkit.catalog.examples.java;

import static com.pspdfkit.catalog.tasks.ExtractAssetTask.extract;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PointF;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Button;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.pspdfkit.annotations.Annotation;
import com.pspdfkit.catalog.R;
import com.pspdfkit.catalog.SdkExample;
import com.pspdfkit.configuration.PdfConfiguration;
import com.pspdfkit.configuration.activity.PdfActivityConfiguration;
import com.pspdfkit.configuration.signatures.SignatureColorOptions;
import com.pspdfkit.configuration.signatures.SignatureCreationMode;
import com.pspdfkit.configuration.signatures.SignatureSavingStrategy;
import com.pspdfkit.document.PdfDocument;
import com.pspdfkit.forms.FormElement;
import com.pspdfkit.forms.FormType;
import com.pspdfkit.listeners.DocumentListener;
import com.pspdfkit.signatures.Signature;
import com.pspdfkit.signatures.listeners.OnSignaturePickedListener;
import com.pspdfkit.signatures.storage.DatabaseSignatureStorage;
import com.pspdfkit.ui.PdfFragment;
import com.pspdfkit.ui.signatures.ElectronicSignatureFragment;
import com.pspdfkit.ui.signatures.ElectronicSignatureOptions;
import com.pspdfkit.ui.special_mode.manager.FormManager;
import java.util.Arrays;

/**
 * Showcases how to use {@link ElectronicSignatureFragment} to implement custom ink signature flow.
 *
 * This example adds a button to enable and disable signature creation when interacting with a
 * signature form element.
 */
public class CustomElectronicSignatureExample extends SdkExample {
    public CustomElectronicSignatureExample(@NonNull final Context context) {
        super(
                context,
                R.string.customElectronicSignatureExampleTitle,
                R.string.customElectronicSignatureExampleDescription);
    }

    @Override
    public void launchExample(
            @NonNull final Context context, @NonNull final PdfActivityConfiguration.Builder configuration) {
        extract(WELCOME_DOC, getTitle(), context, documentFile -> {
            final Intent intent = new Intent(context, CustomElectronicSignatureActivity.class);
            intent.putExtra(CustomElectronicSignatureActivity.EXTRA_URI, Uri.fromFile(documentFile));
            context.startActivity(intent);
        });
    }

    /**
     * Showcases how to use {@link ElectronicSignatureFragment} to implement custom ink signature flow
     * in custom activities using {@link PdfFragment}.
     *
     * Uses a button to enable and disable signature creation when interacting with a signature form
     * element.
     */
    public static class CustomElectronicSignatureActivity extends AppCompatActivity
            implements OnSignaturePickedListener {

        public static final String EXTRA_URI = "CustomElectronicSignatureActivity.DocumentUri";

        private static final String STATE_TOUCHED_PAGE_INDEX = "STATE_TOUCHED_PAGE_INDEX";
        private static final String STATE_TOUCHED_POINT = "STATE_TOUCHED_POINT";

        private PdfFragment fragment;
        private Button annotationCreationButton;

        private DocumentListener documentListener;

        private boolean annotationSignatureCreationActive;
        private PointF touchedPoint;
        private int touchedPageIndex;

        // Here we are also showing how to configure the customizable signature colors and available
        // signing tabs (`signatureCreationModes`).
        @NonNull
        private final ElectronicSignatureOptions signatureOptions = new ElectronicSignatureOptions(
                SignatureSavingStrategy.SAVE_IF_SELECTED,
                SignatureColorOptions.fromColorInt(Color.BLACK, Color.GRAY, Color.RED),
                Arrays.asList(SignatureCreationMode.DRAW, SignatureCreationMode.TYPE));

        @Override
        protected void onCreate(@Nullable final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_custom_ink_signature);
            setSupportActionBar(null);

            // The actual document Uri is provided with the launching intent. You can simply change that
            // inside the CustomSearchUiExample class.
            // This is a check that the example is not accidentally launched without a document Uri.
            final Uri uri = getIntent().getParcelableExtra(EXTRA_URI);
            if (uri == null) {
                new AlertDialog.Builder(this).setTitle("Could not start example.").setMessage("No document Uri was provided with the launching intent.").setNegativeButton("Leave example", (dialog, which) -> dialog.dismiss()).setOnDismissListener(dialog -> finish()).show();

                return;
            }

            fragment = (PdfFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainer);
            if (fragment == null) {
                fragment = PdfFragment.newInstance(uri, new PdfConfiguration.Builder().build());
                // Signature field is on page index 16.
                fragment.setPageIndex(16);
                getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, fragment).commit();
            }

            // In this example we show how to create ink signatures by tapping on the page.
            // For this to work we need to handle page clicks in document listener.
            documentListener = new DocumentListener() {
                @Override
                public boolean onPageClick(
                        @NonNull PdfDocument document,
                        @IntRange(from = 0) final int pageIndex,
                        @Nullable MotionEvent event,
                        @Nullable final PointF pagePosition,
                        @Nullable Annotation clickedAnnotation) {
                    if (annotationSignatureCreationActive && pagePosition!= null) {

                        // Store touched page index and touch point.
                        touchedPageIndex = pageIndex;
                        touchedPoint = pagePosition;

                        // Show signature picker. This will add the signature picker
                        // fragment (if not added yet).
                        // Note that if you set SignatureSavingStrategy.SAVE_IF_SELECTED, you
                        // must provide a SignatureStorage.
                        ElectronicSignatureFragment.show(
                                getSupportFragmentManager(),
                                CustomElectronicSignatureActivity.this,
                                signatureOptions,
                                DatabaseSignatureStorage.withName(
                                        getBaseContext(), DatabaseSignatureStorage.SIGNATURE_DB_NAME));
                        return true;
                    }
                    return false;
                }
            };
            fragment.addDocumentListener(documentListener);

            // For the sake of this example we toggle ink signature creation via simple button.
            annotationCreationButton = findViewById(R.id.createInkSignature);
            annotationCreationButton.setOnClickListener(
                    v -> setSignatureCreationModeActive(!annotationSignatureCreationActive));
            updateButtonText();

            // Restore touched page index and touch point after configuration change.
            if (savedInstanceState!= null) {
                touchedPageIndex = savedInstanceState.getInt(STATE_TOUCHED_PAGE_INDEX);
                touchedPoint = savedInstanceState.getParcelable(STATE_TOUCHED_POINT);
            }

            // Restore existing signature picker dialog fragment.
            ElectronicSignatureFragment.restore(getSupportFragmentManager(), this);

            fragment.addOnFormElementClickedListener(new FormManager.OnFormElementClickedListener() {
                @Override
                public boolean isFormElementClickable(@NonNull FormElement formElement) {
                    // Returning false for signature fields prevents showing signature dialog
                    // when clicking on the signature field.
                    return formElement.getType()!= FormType.SIGNATURE;
                }

                @Override
                public boolean onFormElementClicked(@NonNull FormElement formElement) {
                    // This click event is not interesting to us. Return false to let Nutrient
                    // handle this event.
                    return false;
                }
            });
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (documentListener!= null) {
                fragment.removeDocumentListener(documentListener);
            }
        }

        @Override
        protected void onSaveInstanceState(@NonNull Bundle outState) {
            super.onSaveInstanceState(outState);
            // Save touched page index and touch point here.
            outState.putInt(STATE_TOUCHED_PAGE_INDEX, touchedPageIndex);
            outState.putParcelable(STATE_TOUCHED_POINT, touchedPoint);
        }

        private void setSignatureCreationModeActive(boolean isActive) {
            if (annotationSignatureCreationActive == isActive) return;
            annotationSignatureCreationActive = isActive;

            if (isActive) {
                // Leave editing mode when entering signature creation mode.
                fragment.exitCurrentlyActiveMode();
            } else {
                // Finish signature picker fragment when leaving signature creation mode.
                ElectronicSignatureFragment.dismiss(getSupportFragmentManager());
            }

            updateButtonText();
        }

        @Override
        public void onSignaturePicked(@NonNull final Signature signature) {
            // Leave signature creation mode after signature has been picked.
            setSignatureCreationModeActive(false);
            if (fragment.getDocument() == null || touchedPoint == null) return;

            // Create signature annotation from returned signature data.
            final Annotation signatureAnnotation =
                    signature.toAnnotation(fragment.getDocument(), touchedPageIndex, touchedPoint);
            // Set annotation's creator as set in annotation preferences.
            if (fragment.getAnnotationPreferences().isAnnotationCreatorSet()) {
                signatureAnnotation.setCreator(
                        fragment.getAnnotationPreferences().getAnnotationCreator());
            }
            // Add annotation to page and select it immediately for editing.
            fragment.addAnnotationToPage(signatureAnnotation, true);
        }

        @Override
        public void onDismiss() {
            // In this example we leave signature creation mode when dismissing signature picker.
            setSignatureCreationModeActive(false);
        }

        private void updateButtonText() {
            annotationCreationButton.setText(
                    annotationSignatureCreationActive? R.string.signature_creation_enabled
                            : R.string.signature_creation_disabled);
        }
    }
}

```

This code sample is an example that illustrates how to use our SDK. Please adapt it to your specific use case.

---

## Related pages

- [Application Policy](/guides/android/samples/application-policy-kotlin.md)
- [Custom Form Highlight Color](/guides/android/samples/custom-form-highlight-color-java.md)
- [Custom Page Templates](/guides/android/samples/custom-page-templates-java.md)
- [Digital Signature (Basic)](/guides/android/samples/digital-signature-basic-kotlin.md)
- [Disabled Annotation Property](/guides/android/samples/disabled-annotation-property-java.md)
- [Image Document](/guides/android/samples/image-document-kotlin.md)
- [Compose Image Document](/guides/android/samples/compose-image-document-kotlin.md)
- [Inline Multimedia](/guides/android/samples/inline-multimedia-kotlin.md)
- [JavaScript Form Filling](/guides/android/samples/javascript-form-filling-kotlin.md)
- [Overlay Visibility](/guides/android/samples/overlay-visibility-kotlin.md)
- [PdfFragment](/guides/android/samples/pdffragment-kotlin.md)
- [Reader View](/guides/android/samples/reader-view-kotlin.md)
- [Playground](/guides/android/samples/playground-kotlin.md)
- [JavaScript Calculator](/guides/android/samples/javascript-calculator-kotlin.md)
- [Text Field Suggestions](/guides/android/samples/text-field-suggestions-kotlin.md)
- [Thumbnail Bar Modes](/guides/android/samples/thumbnail-bar-modes-kotlin.md)
- [Signature Storage Database](/guides/android/samples/signature-storage-database-kotlin.md)
- [Selection Customization](/guides/android/samples/selection-customization-java.md)
- [Password Protected PDF](/guides/android/samples/password-protected-pdf-kotlin.md)
- [Scientific Paper](/guides/android/samples/scientific-paper-kotlin.md)
- [Try Instant](/guides/android/samples/try-instant-kotlin.md)
- [Merge Documents](/guides/android/samples/merge-documents-kotlin.md)
- [Annotation Rendering](/guides/android/samples/annotation-rendering-kotlin.md)
- [Custom Data Provider](/guides/android/samples/custom-data-provider-kotlin.md)
- [Annotations with Transparency](/guides/android/samples/annotations-with-transparency-kotlin.md)
- [Annotation Flags](/guides/android/samples/annotation-flags-kotlin.md)
- [AI Assistant (Multiple Documents, ViewPager)](/guides/android/samples/ai-assistant-multiple-documents-viewpager-kotlin.md)
- [Custom Sharing Menu](/guides/android/samples/custom-sharing-menu-java.md)
- [Add LTV to Existing Signature](/guides/android/samples/add-ltv-to-existing-signature-kotlin.md)
- [Custom Toolbar Grouping](/guides/android/samples/custom-toolbar-grouping-java.md)
- [Custom Layout](/guides/android/samples/custom-layout-kotlin.md)
- [Custom ActionBar Actions](/guides/android/samples/custom-actionbar-actions-kotlin.md)
- [Custom Activity Toolbars](/guides/android/samples/custom-activity-toolbars-java.md)
- [Custom Note Hinter](/guides/android/samples/custom-note-hinter-kotlin.md)
- [Custom Main Toolbar](/guides/android/samples/custom-main-toolbar-kotlin.md)
- [Annotation Configuration](/guides/android/samples/annotation-configuration-kotlin.md)
- [Annotation Selection Styling](/guides/android/samples/annotation-selection-styling-kotlin.md)
- [Custom Search UI (Compose)](/guides/android/samples/custom-search-ui-compose-kotlin.md)
- [Document Switcher](/guides/android/samples/document-switcher-java.md)
- [File Annotation Creation](/guides/android/samples/file-annotation-creation-kotlin.md)
- [Dynamic Pages on Scroll](/guides/android/samples/dynamic-pages-on-scroll-kotlin.md)
- [Custom Activity Form Editing](/guides/android/samples/custom-activity-form-editing-java.md)
- [Custom Stamp Annotations](/guides/android/samples/custom-stamp-annotations-java.md)
- [Custom Outline Provider](/guides/android/samples/custom-outline-provider-kotlin.md)
- [Compose Navigation](/guides/android/samples/compose-navigation-kotlin.md)
- [Fragment Runtime Configuration](/guides/android/samples/fragment-runtime-configuration-kotlin.md)
- [Annotation Overlay](/guides/android/samples/annotation-overlay-java.md)
- [Instant Document JSON](/guides/android/samples/instant-document-json-kotlin.md)
- [DocumentView Composable](/guides/android/samples/documentview-composable-kotlin.md)
- [Form Creation](/guides/android/samples/form-creation-kotlin.md)
- [Document Download](/guides/android/samples/document-download-kotlin.md)
- [JavaScript Actions](/guides/android/samples/javascript-actions-kotlin.md)
- [Instant JSON Attachment](/guides/android/samples/instant-json-attachment-kotlin.md)
- [Digital Signature (Manual)](/guides/android/samples/digital-signature-manual-kotlin.md)
- [Digital Signature (Third-Party)](/guides/android/samples/digital-signature-third-party-kotlin.md)
- [Inline Search](/guides/android/samples/inline-search-java.md)
- [Form Filling](/guides/android/samples/form-filling-kotlin.md)
- [Form Click Intercept (Compose)](/guides/android/samples/form-click-intercept-compose-kotlin.md)
- [Document Sharing](/guides/android/samples/document-sharing-java.md)
- [Custom Download Dialog](/guides/android/samples/custom-download-dialog-java.md)
- [Download Progress](/guides/android/samples/download-progress-kotlin.md)
- [Popup Toolbar Customization](/guides/android/samples/popup-toolbar-customization-kotlin.md)
- [Custom Sharing Dialog](/guides/android/samples/custom-sharing-dialog-java.md)
- [PDF from Image](/guides/android/samples/pdf-from-image-kotlin.md)
- [Digital Signature (Two-Step)](/guides/android/samples/digital-signature-two-step-kotlin.md)
- [Remote URL](/guides/android/samples/remote-url-kotlin.md)
- [PdfUiFragment](/guides/android/samples/pdfuifragment-kotlin.md)
- [Runtime Configuration](/guides/android/samples/runtime-configuration-kotlin.md)
- [Sound Extraction](/guides/android/samples/sound-extraction-kotlin.md)
- [Document from Canvas](/guides/android/samples/document-from-canvas-kotlin.md)
- [Tabbed Documents](/guides/android/samples/tabbed-documents-kotlin.md)
- [Watermarks](/guides/android/samples/watermarks-kotlin.md)
- [Programmatic Zoom](/guides/android/samples/programmatic-zoom-kotlin.md)
- [Signature Parcelize](/guides/android/samples/signature-parcelize-kotlin.md)
- [OCR](/guides/android/samples/ocr-kotlin.md)
- [Vertical Scrollbar](/guides/android/samples/vertical-scrollbar-java.md)
- [Split View](/guides/android/samples/split-view-java.md)
- [XFDF Import/Export](/guides/android/samples/xfdf-import-export-kotlin.md)
- [UI View Modes](/guides/android/samples/ui-view-modes-kotlin.md)
- [LTV Signature](/guides/android/samples/ltv-signature-kotlin.md)
- [Bookmark Highlighting](/guides/android/samples/bookmark-highlighting-kotlin.md)
- [Custom Annotation Inspector](/guides/android/samples/custom-annotation-inspector-java.md)
- [Annotation Sidebar](/guides/android/samples/annotation-sidebar-kotlin.md)
- [AI Assistant (Single Document)](/guides/android/samples/ai-assistant-single-document-kotlin.md)
- [AI Assistant (Multiple Documents, Compose)](/guides/android/samples/ai-assistant-multiple-documents-compose-kotlin.md)
- [Document Comparison](/guides/android/samples/document-comparison-kotlin.md)
- [Document Processing](/guides/android/samples/document-processing-kotlin.md)
- [Custom Annotation Creation Toolbar](/guides/android/samples/custom-annotation-creation-toolbar-java.md)
- [E-Learning](/guides/android/samples/e-learning-kotlin.md)
- [Electronic + Digital Signing](/guides/android/samples/electronic-digital-signing-kotlin.md)
- [Generate PDF Report](/guides/android/samples/generate-pdf-report-kotlin.md)
- [Multimedia Annotations](/guides/android/samples/multimedia-annotations-kotlin.md)
- [Forms with JavaScript](/guides/android/samples/forms-with-javascript-kotlin.md)
- [External Document](/guides/android/samples/external-document-kotlin.md)
- [Overlay Views](/guides/android/samples/overlay-views-kotlin.md)
- [Kiosk Grid](/guides/android/samples/kiosk-grid-kotlin.md)
- [Search Indexing](/guides/android/samples/search-indexing-kotlin.md)
- [Annotation Creation](/guides/android/samples/annotation-creation-kotlin.md)
- [Filterable Thumbnail Grid](/guides/android/samples/filterable-thumbnail-grid-kotlin.md)
- [Tabbed Documents (Persistent)](/guides/android/samples/tabbed-documents-persistent-kotlin.md)
- [Measurement Tools](/guides/android/samples/measurement-tools-kotlin.md)
- [HTML-to-PDF Conversion](/guides/android/samples/html-to-pdf-conversion-kotlin.md)
- [AES Encrypted File](/guides/android/samples/aes-encrypted-file-java.md)
- [Construction Floor Plan](/guides/android/samples/construction-floor-plan-kotlin.md)
- [Hide and Reveal Areas](/guides/android/samples/hide-and-reveal-areas-kotlin.md)
- [Multiple Documents (Compose Pager)](/guides/android/samples/multiple-documents-compose-pager-kotlin.md)
- [Screen Reader](/guides/android/samples/screen-reader-java.md)
- [Custom Search UI (Views)](/guides/android/samples/custom-search-ui-views-java.md)

