Using Property Inspectors within PdfFragment

The property inspector is a general purpose PSPDFKit UI component that allows editing of object properties. PdfActivity already integrates property inspectors for editing annotation and form properties out of the box. The annotation inspector is displayed when a user selects the annotation properties picker from the annotation creation or editing toolbars. The form inspector is displayed when a user starts editing choice form fields.

This article introduces the property inspector API and shows how to integrate existing property inspectors as standalone views and connect them with corresponding special modes in your custom activities built around PdfFragment.

ℹ️ Note: This article assumes you’re familiar with the concept of special modes.

Property Inspector

PropertyInspector is a ViewGroup that displays multiple PropertyInspectorViews in a vertical list. PSPDFKit ships with a comprehensive set of inspector views.

By default, PSPDFKit displays property inspectors in a bottom sheet, and a single instance of PropertyInspectorCoordinatorLayout is used in PdfActivity to coordinate the display of the inspectors. Each property inspector has its own controller that manages its lifecycle. These controllers are generally tied to PropertyInspectorCoordinatorLayout and wrap the complete lifecycle of a single property inspector. When a document enters a special mode, we wire up the required property inspector controller with the corresponding special mode controller inside PdfActivity. When using PdfFragment, you can implement these controllers to handle your own property inspector lifecycle or use the default inspector controllers provided by the framework.

Currently, PSPDFKit ships with the following inspector controllers:

Manual Integration of Property Inspectors

For adding property inspectors to your custom activity built around PdfFragment, you need to manually add PropertyInspectorCoordinatorLayout to a view wrapping the PdfFragment:

<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" />

    <com.pspdfkit.ui.inspector.PropertyInspectorCoordinatorLayout
        android:id="@+id/inspectorCoordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:elevation="16dp" />

</FrameLayout>

Here’s a simple layout containing one FrameLayout serving as a fragment placeholder, with a PropertyInspectorCoordinatorLayout on top of it.

Special mode controllers are retrieved from mode change listeners registered on the PdfFragment. In your activity, you can register a listener to a fragment and then bind the controller to the previously created property inspector controller:

class MyActivity : AppCompatActivity(), OnAnnotationCreationModeChangeListener {
    private lateinit var inspectorCoordinatorLayout: PropertyInspectorCoordinatorLayout
    private lateinit var annotationCreationInspectorController: AnnotationCreationInspectorController
    private lateinit var fragment: PdfFragment

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_annotation_toolbar_fragment)

        inspectorCoordinatorLayout = findViewById(R.id.inspectorCoordinatorLayout)
        annotationCreationInspectorController = DefaultAnnotationCreationInspectorController(this, inspectorCoordinatorLayout)

        // ... Init fragment here ...

        // Register a listener for special mode changes.
        fragment.addOnAnnotationCreationModeChangeListener(this)
    }

    override fun onEnterAnnotationCreationMode(controller: AnnotationCreationController) {
        // Bind the inspector controller to the annotation creation mode controller.
        annotationCreationInspectorController.bindAnnotationCreationController(controller)
    }

    override fun onChangeAnnotationCreationMode(controller: AnnotationCreationController) {
        // Nothing to be done here. The inspector controller will automatically pick annotation creation controller changes.
    }

    override fun onExitAnnotationCreationMode(controller: AnnotationCreationController) {
        // Unbind the annotation creation controller from the inspector controller.
        annotationCreationInspectorController.unbindAnnotationCreationController()
    }
}
class MyActivity extends AppCompatActivity implements OnAnnotationCreationModeChangeListener {
    private PropertyInspectorCoordinatorLayout inspectorCoordinatorLayout;
    private AnnotationCreationInspectorController annotationCreationInspectorController;
    private PdfFragment fragment;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_annotaton_toolbar_fragment);

        inspectorCoordinatorLayout = findViewById(R.id.inspectorCoordinatorLayout);
        annotationCreationInspectorController = new DefaultAnnotationCreationInspectorController(this, inspectorCoordinatorLayout);

        // ... Init fragment here ...

        // Register a listener for special mode changes.
        fragment.addOnAnnotationCreationModeChangeListener(this);
    }

    @Override
    public void onEnterAnnotationCreationMode(@NonNull AnnotationCreationController controller) {
        // Bind the inspector controller to the annotation creation mode controller.
        annotationCreationInspectorController.bindAnnotationCreationController(controller);
    }

    @Override
    public void onChangeAnnotationCreationMode(@NonNull AnnotationCreationController controller) {
        // Nothing to be done here. The inspector controller will automatically pick annotation creation controller changes.
    }

    @Override
    public void onExitAnnotationCreationMode(@NonNull AnnotationCreationController controller) {
        // Unbind the annotation creation controller from the inspector controller.
        annotationCreationInspectorController.unbindAnnotationCreationController();
    }
}

This implementation will only get you the annotation creation inspector without toolbars. See the entirety of ToolbarsInFragmentExample for information on how to integrate other inspectors and toolbars. For an example of how to integrate the form editing inspector, take a look at FormEditingInFragmentExample in our Catalog app.

ℹ️ Note: You can use AnnotationCreationController methods to control your annotation inspector in your custom UI, even without toolbars. Use toggleAnnotationInspector() to toggle the display of the annotation inspector and shouldDisplayPicker() to find out whether or not the annotation inspector is enabled for the active annotation tool.