Using contextual toolbars within PdfFragment
PdfActivity
provides contextual toolbars out of the box for so-called special modes, which include text selection, annotation creation, annotation editing, and document editing. Since Nutrient Android SDK 2.4, you have been able to use these toolbars as standalone views and connect them with corresponding special modes.
Special modes
When a document is in a special mode, it means that some kind of specific interaction is taking place, and as a result, the UI could behave in a slightly different way.
For example, if you’re in annotation creation mode with ink as a selected annotation type, sliding your finger across the page will not cause the page to move. Instead, it will draw the ink path beneath your finger. In such a state, we consider a document (or PdfFragment
) to be in a special mode.
Each special mode has its own controller. What PdfActivity
implements is the wiring of those controllers to their corresponding UI representations, which are contextual toolbars. When using PdfFragment
, you can either use the controllers to create a custom UI for special modes or use ContextualToolbar
s provided by the framework.
Here is a list of the current special modes and their controllers:
-
Annotation creation mode —
AnnotationCreationController
-
Annotation editing mode —
AnnotationEditingController
-
Text selection mode —
TextSelectionController
-
Document editing mode —
DocumentEditingController
(part of thePdfThumbnailGrid
) -
Form editing mode —
FormEditingController
Contextual toolbars
Contextual toolbars extend the ContextualToolbar
class and, as already mentioned, are one possible UI representation of special modes.
Nutrient currently provides these toolbars:
Additionally, each of the toolbars has a method for binding (and unbinding) the special mode controller:
-
AnnotationCreationToolbar#bindAnnotationCreationController(AnnotationCreationController)
-
AnnotationEditingToolbar#bindController(AnnotationEditingController)
-
TextSelectionToolbar#bindTextSelectionController(TextSelectionController)
-
DocumentEditingToolbar#bindDocumentEditingController(DocumentEditingController)
Calling this method will automatically provide all the necessary logic — for example, changing selected buttons depending upon the selected annotation type, or changing the color of the color picker icon.
Manually adding toolbars
Finally, for adding a toolbar to PdfFragment
in a custom implementation, we need to manually add contextual toolbars to a view wrapping the PdfFragment
. We’ll use a Catalog example named ToolbarsInFragmentExample
for the code snippets:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".examples.activities.ToolbarsInFragmentActivity" tools:ignore="UnusedAttribute"> <FrameLayout android:id="@+id/fragmentContainer" android:layout_width="match_parent" android:layout_height="match_parent" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <com.pspdfkit.ui.toolbar.ToolbarCoordinatorLayout android:id="@+id/toolbarCoordinatorLayout" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout> </FrameLayout>
Here’s a simple layout containing one FrameLayout
serving as a fragment placeholder, and a second one above it containing the ToolbarCoordinatorLayout
.
ToolbarCoordinatorLayout
is a ViewGroup
for laying out child ContextualToolbar
s and allowing the user to drag them to different positions. It is a strongly recommended to wrap toolbars in the ToolbarCoordinatorLayout
, since it also provides the correct size for the toolbars, along with many little details such as the submenu indicator position, depending on the toolbar position on the screen.
Controllers are retrieved from mode change listeners registered on the PdfFragment
. In your activity, you can register a listener to a fragment, bind a controller to the previously created toolbar, and add that toolbar to the coordinator:
class MyActivity: AppCompatActivity(), OnAnnotationCreationModeChangeListener { private val annotationCreationToolbar: AnnotationCreationToolbar private val toolbarCoordinatorLayout: ToolbarCoordinatorLayout private val fragment: PdfFragment protected fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_annotation_toolbar_fragment) toolbarCoordinatorLayout = findViewById(R.id.toolbarCoordinatorLayout) as ToolbarCoordinatorLayout annotationCreationToolbar = AnnotationCreationToolbar(this) /// ... Init fragment here ... // Register a listener for special mode changes. fragment.addOnAnnotationCreationModeChangeListener(this) } /** * Called when the annotation creation mode has been entered. * @param controller Provided controller for managing annotation creation mode. */ fun onEnterAnnotationCreationMode(controller: AnnotationCreationController) { // Bind the toolbar to the controller. annotationCreationToolbar.bindController(controller) // Now display the toolbar in the `toolbarCoordinatorLayout`. toolbarCoordinatorLayout.displayContextualToolbar(annotationCreationToolbar, true) } }
class MyActivity extends AppCompatActivity implements OnAnnotationCreationModeChangeListener { private AnnotationCreationToolbar annotationCreationToolbar; private ToolbarCoordinatorLayout toolbarCoordinatorLayout; private PdfFragment fragment; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_annotaton_toolbar_fragment); toolbarCoordinatorLayout = (ToolbarCoordinatorLayout) findViewById(R.id.toolbarCoordinatorLayout); annotationCreationToolbar = new AnnotationCreationToolbar(this); // ... Init fragment here ... // Register a listener for special mode changes. fragment.addOnAnnotationCreationModeChangeListener(this); } /** * Called when the annotation creation mode has been entered. * @param controller Provided controller for managing annotation creation mode. */ @Override public void onEnterAnnotationCreationMode(@NonNull AnnotationCreationController controller) { // Bind the toolbar to the controller. annotationCreationToolbar.bindController(controller); // Now display the toolbar in the `toolbarCoordinatorLayout`. toolbarCoordinatorLayout.displayContextualToolbar(annotationCreationToolbar, true); } }
This implementation will only result in the annotation creation toolbar. See the entirety of ToolbarsInFragmentExample
for other toolbars.
Integrating annotation inspectors
If you wish to use our default annotation inspectors with toolbars, follow the using property inspectors within fragment guide.