COMING SOON: Spring 2025 Release

Customize the UI in Android Document Collaboration App

By Branden Fung | 2019 May 01

Sanity Image

In a separate blog post, we created a real-time document collaboration app using Firebase and PDFTron's Android PDF SDK. This lets many users view the same document at the same time and communicate via comments, highlights, signatures, and other annotations.

In this article, we cover how to customize the collaboration app UI to match your desired look, and also dive into some advanced interface customization using PDFTron's open-source UI components.

You can find the code referenced in this article in our GitHub repository.

Change the Color Theme

Copied to clipboard

By default, the annotation reply UI in the PDFTron library uses PDFTron's standard app styles, which could clash with the look of your app if it has a completely different theme.

With Native Android’s powerful styling and theming capabilities, however, developers can easily customize the appearance of their apps using style XML resource files. PDFTron’s Android PDF SDK leverages this capability to provide Android developers with a familiar and easy way to style PDFTron’s document viewer components.

The following steps will demonstrate how to create a unique dark-colored theme for our Firebase sample app.

Step 1. Define Custom Colors

Copied to clipboard

Define some custom colors in res/colors.xml. These colors will be used by both the document viewer and the reply UI.

<resources>
    <!-- Our custom app theme colors -->
    <color name="colorPrimary">#202D3D</color>
    <color name="colorPrimaryDark">#151e29</color>
    <color name="colorAccent">#ff5722</color>
    <color name="iconPrimary">#9dd8ff</color>
    <color name="backgroundPrimary">@color/colorPrimary</color>
    <color name="backgroundSecondary">@color/colorPrimaryDark</color>
</resources>

Step 2. Create a Custom Style

Copied to clipboard

Create a new style that extends ReplyBaseTheme.DayNight in res/styles.xml, and specify the attributes in ReplyBaseTheme.DayNight that you want to customize.

<resources>
    <!-- Custom theme used by the reply UI components -->
    <style name="MyCustomReplyTheme" parent="ReplyBaseTheme.DayNight">
        <!-- Component wide attributes used by the reply UI -->
        <item name="replyColorBackgroundPrimary">@color/backgroundPrimary</item>
        <item name="replyColorBackgroundSecondary">@color/backgroundSecondary</item>
        <item name="replyIconColor">@color/iconPrimary</item>
        <item name="replyDividerColor">@color/backgroundSecondary</item>
        <item name="replyEditorSendButtonColor">@color/iconPrimary</item>
        <item name="replyEditorCancelButtonColor">@color/colorAccent</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:textColorSecondary">#C9C9C9</item>
    </style>
    ...
</resources>

Step 3. Specify the Custom Style in Your Activity's Theme

Copied to clipboard

Finally, add the custom reply UI style to your activity by defining the replyTheme attribute in your activity's theme.

<resources>
    <!-- Style used by the activity containing the document viewer Fragment-->
    <style name="AppTheme" parent="CustomAppThemeBase">
        <!-- Colors used by the document viewer -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- Specify your custom annotation reply theme with the replyTheme attribute -->
        <item name="replyTheme">@style/MyCustomReplyTheme</item>
    </style>
    <!-- We'll also customize the viewer Fragment to use the sample color palette
        by defining CustomAppTheme and extending AppTheme -->
    <style name="CustomAppTheme" parent="AppTheme"/>
    ...
</resources>

The app should now look something like this:

Blog image

Customize the UI Layout

The new color palette for our sample app looks great, but we can take things even further by changing the viewer layout directly. The UI components in PDFTron's Android PDF SDK are fully open-source, making it easy to reference and modify UI components.

Let’s make a custom viewer layout for tablet devices that makes use of the extra space on tablet screens to display our reply UI.

Step 1. Create a New Layout XML

Copied to clipboard

Define a new layout XML file that we'll use for our custom viewer fragment. It'll simply add a container for our reply UI next to our document viewer.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- Reference the viewer layout XML from the open-source viewer fragment -->
    <include
        layout="@layout/controls_collab_fragment_tabbed_pdfviewctrl_tab_content"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="5" />
    <!-- The container that will hold the reply UI -->
    <FrameLayout
        android:id="@+id/reply_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2" />
</LinearLayout>

Step 2. Create a Custom Viewer Fragment

Copied to clipboard

Create a new Fragment class and extend CollabViewerTabFragment. In this new class, we'll override the following methods in order to tell the viewer to use our custom layout from step 1, and where the reply UI components will be inflated.

class CustomTabFragment : CollabViewerTabFragment() {
    // Define the layout XML file to use for this viewer fragment
    override fun getContentLayout(): Int {
        return R.layout.fragment_custom_reply_viewer
    }
    // Instantiate and display the reply UI in the reply container
    override fun showReplyFragment(selectedAnnotId: String, authorId: String, selectedAnnotPageNum: Int) {
        // Create our reply fragment
        val fragment = ReplyFragmentBuilder
            .withAnnot(mDocumentId, selectedAnnotId, authorId)
            .usingTheme(mReplyTheme)
            .build(activity!!, ReplyFragment::class.java)
        // Add the fragment to the container
        activity!!.supportFragmentManager.beginTransaction()
            .add(R.id.reply_container, fragment)
            .commit()
    }
}

Step 3. Use the Custom Viewer

Copied to clipboard

We can then create the viewer Fragment by specifying the custom class in the Fragment builder, and use it like any other Android Fragment:

// Use the viewer Fragment returned from this method 
// like any other Android Fragment 
private fun createTabletViewerFragment(
    activity: AppCompatActivity,
    fileUri: Uri,
    config: ViewerConfig
): CollabViewerTabHostFragment {
    return CollabViewerBuilder.withUri(fileUri)
        .usingConfig(config)
        .usingTabClass(CustomTabFragment::class.java)
        .build(activity)
}

Using this custom viewer on landscape-oriented tablet devices, the annotation reply UI is now displayed alongside the document viewer.

Blog image

Conclusion

The real-time collaboration library from PDFTron's Android SDK brings a new collaborative document viewing experience to Android, making use of PDFTron's powerful document viewing and editing features. Combining this new library with the flexibility of PDFTron's UI components allows developers to easily create beautiful custom apps with full-featured document viewing capabilities.

If you have any questions about PDFTron's Android PDF SDK, please feel free to get in touch!

The complete source code for the sample app in this blog post series is available at our GitHub repository.

Sanity Image

Branden Fung

Share this post

email
linkedIn
twitter