Some test text!

Hamburger Icon

Android / Guides / Custom tool

Creating a custom PDF viewer tool in Android

The sample code for this guide can be found at our GitHub repository.


The tools package provides several base classes that can be extended to create and add custom tools to the viewer. Click here for a complete list of tools .

In this guide, we will create a custom rectangular cloudy annotation tool for either PDFViewCtrl or PdfViewCtrlTabHostFragment2 . It is recommended to read the following articles before continuing this guide:

Step 1: Pick a base tool class to inherit

From this tool hiearchy list , find a base tool class to extend. For example, here are some of the more commonly used base tool classes:

TextMarkupCreateCreates a text markup annotation. Derive from this class to create annotation on text. Override createMarkup to create an Annot object.
RectCreateDraws and creates a rectangle annotation. Derive from this class to draw rectangles, for example, checkbox form field. Override createMarkup to create an Annot object.
OvalCreateDraws and creates an ellipse annotation. Derive from this class if draw ellipses. Override createMarkup to create an Annot object.
SimpleShapeCreateCreates various shape annotations such as rectangle, ellipse, ink line and more . Use this class if none of the above works for you. Override createMarkup to create an Annot object.

For our custom rectangular cloudy annotation tool, we'll be creating a class called CustomTool that inherits from RectCreate.

Step 2: Override the base class methods

  1. In the CustomTool class, override the getToolMode() method. This method must return a custom tool mode, which can be created by calling ToolManager.ToolMode.addNewMode(int) and specifying the custom tool's annotation type.

  2. Afterwards, override the feature specific methods and implement the desired custom behavior. Add @Keep so the tool can work properly in release mode. For example here is a custom tool that handles creating rectangular cloudy annotations:

    import com.pdftron.pdf.utils.Utils;
    import com.pdftron.pdf.Point;
    import com.pdftron.pdf.Rect;
    // ...
    * This class is to create a rectangular cloudy annotation.
    public class CustomTool extends RectCreate {
        // Since this tool creates polygon annotation, use Annot.e_Polygon as parameter.
        public static ToolManager.ToolModeBase MODE = 
        public CustomTool(@NonNull PDFViewCtrl ctrl) {
        public ToolManager.ToolModeBase getToolMode() {
            return MODE;
        protected Annot createMarkup(PDFDoc doc, Rect bbox) throws PDFNetException {
            Polygon poly = new Polygon(Polygon.create(doc, Annot.e_Polygon, bbox));
            ColorPt color = Utils.color2ColorPt(Color.RED);
            poly.setColor(color, 3);
            poly.setVertex(0, new Point(bbox.getX1(), bbox.getY1()));
            poly.setVertex(1, new Point(bbox.getX1(), bbox.getY2()));
            poly.setVertex(2, new Point(bbox.getX2(), bbox.getY2()));
            poly.setVertex(3, new Point(bbox.getX2(), bbox.getY1()));
            return poly;

Step 3: Register the custom tool in ToolManager

All tools are controlled by an instance of ToolManager and it will need to know about the new custom tool before the tool can be used in the viewer.

  • Option 1: Register using PdfViewCtrlTabHostFragment2

    A PdfViewCtrlTabHostFragment2 contains an internal reference to ToolManager. A custom tool can be added to this internal ToolManager by using the ToolManagerBuilder class. A ToolManagerBuilder object is passed to an instance of ViewerConfig and used to initialize the viewer with the custom tool. The following method can be called in an activity to add a custom tool to a PdfViewCtrlTabHostFragment2:

    // Add a custom tool to ViewerConfig and use it to initialize a PdfViewCtrlTabHostFragment2
    public PdfViewCtrlTabHostFragment2 addCustomTool(@NonNull Context context, @NonNull Uri fileUri) {
        // Create the ToolManagerBuilder builder and add our custom tool
        ToolManagerBuilder toolManagerBuilder = ToolManagerBuilder
                .addCustomizedTool(CustomTool.MODE, CustomTool.class);
        // Add the ToolManagerBuilder builder to a ViewerConfig, that will
        // be used to initialize PdfViewCtrlTabHostFragment2
        ViewerConfig config = new ViewerConfig.Builder()
        // Create the custom PdfViewCtrlTabHostFragment2 using the custom ViewerConfig object
        return ViewerBuilder2.withUri(fileUri)
  • Option 2: Register using PDFViewCtrl

    Alternatively if PDFViewCtrl is used and set up with a ToolManager, you can simply add the custom tool directly to ToolManager by calling:

    // Add a custom tool to ToolManager using PDFViewCtrl
    public void addCustomTool(@NonNull ToolManager toolManager, @NonNull PDFViewCtrl pdfViewCtrl) {
        // Create our custom tool
        Tool customTool = new CustomTool(pdfViewCtrl);
        // Then add it to ToolManager
    You can learn more about setting up PDFViewCtrl with ToolManager in the ToolManager customization guide .

Step 4: Use the custom tool

To use the custom tool, set it to an instance of ToolManager as follows:

  • Option 1: Using PdfViewCtrlTabHostFragment2

    public void useCustomTool(@NonNull PdfViewCtrlTabHostFragment2 fragment) {
        // Create our custom tool
        ToolManager toolManager = fragment.getCurrentPdfViewCtrlFragment().getToolManager();
        ToolManager.Tool customTool = toolManager.createTool(CustomTool.MODE, toolManager.getTool());
        // Then set it in ToolManager
  • Option 2: Using PDFViewCtrl

    public void useCustomTool(@NonNull ToolManager toolManager, @NonNull PDFViewCtrl pdfViewCtrl) {
        // Create our custom tool
        Tool customTool = new CustomTool(pdfViewCtrl);
        // Then add it to ToolManager

Now, when using the custom tool you will see the following:

quick menu image

Step 5: Switch to another tool during motion events

You will be able to switch tool modes within the same tool class in response to a motion event, such as onDown(MotionEvent), onDoubleTap(MotionEvent) and so on.

In gesture event functions, if one tool switches to another tool, that motion event will continue to be executed in the next tool (see tools overview for more information ). So if the custom tool wants to switch to another tool during a motion event, you can set the next tool mode by calling Tool.safeSetNextToolMode(ToolMode).

For example, let's override onSingleTapConfirmed in, and set the next tool to be TextHighlightCreate:

public boolean onSingleTapConfirmed(MotionEvent e) {
    mNextToolMode = safeSetNextToolMode(ToolManager.ToolMode.TEXT_HIGHLIGHT);
    return false;

Now in response to a single tap while using your custom tool, it will switch to the TextHighlightCreate tool.

If you need to save the ToolMode and retrieve it at a later time, you can call toString() on the ToolMode object and retrieve the instance later by calling ToolMode.valueOf(String).

Get the answers you need: Chat with us