This tutorial only applies to Xamarin.Android.
All actions related to the PDF viewer are handled through the PdfViewCtrlTabHostFragment2
. This fragment extends androidx.fragment.app.Fragment
and is responsible for showing documents in tabs.
- Integrated Apryse into your project and added the
PDFTron.Android.Tools
NuGet package into your project. - Minimum API: 16 (using AndroidX)
- Compile API: 34
- Recommended target API: 34
No trial license key required.
The trial of Apryse Mobile SDK does not require a trial key. A commercial license key is required for use in a production environment. Please contact sales to purchase a commercial key or if you need any other license key assistance.
Keep your license keys confidential.
License keys are uniquely generated. Please make sure that it is not publicly available (e.g. in your public GitHub).
- In order to support all the features in
PdfViewCtrlTabHostFragment2
, we will need to add the Android permissions listed in this table. However if you would like to disable certain features and customize your document viewer, you should leave out unnecessary permissions.
Storage permission
Please note that from Android 6.0 (API 23) and up, applications need to request storage permission at runtime before accessing any files on device.
- Enable
largeHeap
and usesClearTextTraffic
:
XML
1<application ... android:largeHeap="true" android:usesCleartextTraffic="true">
2</application>
If your app is targeting Android SDK version 28 or higher, you will need to add the android:usesCleartextTraffic="true" attribute in your application tag to open HTTP files in the viewer. If you are only working with HTTPS files, this is not required.
- Define your Activity to extend
AppCompatActivity
and use an AppCompat theme:
C#
1[Activity(Label = "MyReaderActivity", ConfigurationChanges = Android.Content.PM.ConfigChanges.ScreenSize | Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.KeyboardHidden, Theme = "@style/PDFTronAppTheme", WindowSoftInputMode = SoftInput.AdjustPan)]
2public class MyReaderActivity : AppCompatActivity
3{
4 ...
5}
- If you have not done so already, add your license in the
AndroidManifest.xml
file. The final AndroidManifest.xml
file should look something like this:
XML
1<manifest ...>
2 <!-- Required permissions are added here -->
3 <uses-permission android:name="android.permission.INTERNET"/>
4 <uses-permission android:name="android.permission.RECORD_AUDIO" />
5
6 <!-- Add enable largeHeap and usesCleartextTraffic -->
7 <application ... android:largeHeap="true" android:usesCleartextTraffic="true">
8
9 <!-- Add license key in meta-data tag here. This should be inside the application tag. -->
10 <meta-data android:name="pdftron_license_key" android:value="your_license_key_goes_here"/>
11
12 </application>
13</manifest>
Use ViewerBuilder2
to create an instance of PdfViewCtrlTabHostFragment2
, and add it to your activity layout. To add a document viewer fragment for a given password-protected file, call the following method in your activity:
C#
1// Add a viewer fragment to the layout container in the specified activity,
2// and returns the added fragment
3public PdfViewCtrlTabHostFragment2 addViewerFragment(int fragmentContainer,
4 AppCompatActivity activity, Uri fileUri, String password)
5{
6 // Create the viewer fragment
7 PdfViewCtrlTabHostFragment2 fragment =
8 (PdfViewCtrlTabHostFragment2) ViewerBuilder2.WithUri(fileUri, password).Build(this);
9
10 // Add the fragment to the layout fragment container
11 activity.SupportFragmentManager.BeginTransaction()
12 .Replace(fragmentContainer, fragment, null)
13 .Commit();
14
15 return fragment;
16}
where fragmentContainer
is the resource id of a layout in your activity that will contain your fragment:
For example:
XML
1<?xml version="1.0" encoding="utf-8"?>
2<!-- This FrameLayout will contain our viewer fragment-->
3<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/>
Alternatively if you have extended PdfViewCtrlTabFragment2
or PdfViewCtrlTabHostFragment2
, you can specify your custom classes using the ViewerBuilder2.usingTabClass()
method and the ViewerBuilder2.build()
method as follows:
C#
1// Add a viewer fragment to the layout container in the specified activity,
2// and returns the added fragment
3public MyCustomTabHostFragment addViewerFragment(int fragmentContainer,
4 AppCompatActivity activity, Uri fileUri, String password)
5{
6 // Create the viewer fragment with a custom
7 // PdfViewCtrlTabFragment2 and PdfViewCtrlTabHostFragment2
8 PdfViewCtrlTabHostFragment2 fragment =
9 (PdfViewCtrlTabHostFragment2) ViewerBuilder2.WithUri(fileUri, password)
10 .UsingTabClass(Java.Lang.Class.FromType(typeof(MyCustomTabFragment)))
11 .Build(activity, Java.Lang.Class.FromType(typeof(MyCustomTabHostFragment)));
12
13 // Add the fragment to the layout fragment container
14 activity.SupportFragmentManager.BeginTransaction()
15 .Replace(fragmentContainer, fragment, null)
16 .Commit();
17
18 return fragment;
19}
- If you would like to customize the appearance of the viewer activity, define
PDFTronAppTheme
in styles.xml
:You can learn more about this in the customize the viewer's theme guide .
XML
1<style name="PDFTronAppTheme" parent="PDFTronAppThemeBase"> <item name="colorPrimary">@color/app_color_primary_day</item> <item name="colorPrimaryDark">@color/app_color_primary_dark_day</item> <item name="colorAccent">@color/app_color_accent</item> <!-- Action bar --> <item name="actionModeBackground">?attr/colorPrimary</item> <item name="windowActionModeOverlay">true</item> </style>
PdfViewCtrlTabHostFragment2
uses the AppCompat
theme for material colors. Make sure that the value of android:theme
in your activity
tag also extends the AppCompat
theme.
- If you would like to customize certain viewer settings or the UI of
PdfViewCtrlTabHostFragment2
, you can use ViewerConfig.Builder
. For example:
C#
1public PdfViewCtrlTabHostFragment2 createUsingViewerConfig(Context context, Uri fileUri, String password)
2 {
3 // Create a ViewerConfig object with custom settings
4 var config = new ViewerConfig.Builder()
5 .FullscreenModeEnabled(true)
6 .MultiTabEnabled(true)
7 .DocumentEditingEnabled(true)
8 .LongPressQuickMenuEnabled(true)
9 .ToolbarTitle("Host Fragment")
10 .ShowSearchView(true)
11 .Build();
12
13 // Pass in the ViewerConfig object into the ViewerBuilder2
14 return (PdfViewCtrlTabHostFragment2) ViewerBuilder2.WithUri(fileUri, password)
15 .UsingConfig(config).Build(context);
16 }
The default toolbar menu consists of the following buttons on phones:
- App navigation
- Toolbar switcher
- Tab switcher
- Overflow menu
The default toolbar menu consists of the following buttons on tablets:
- App navigation
- Toolbar switcher
- Document text search
- View mode configuration
- Thumbnails browser
- List container
- Overflow menu
You can fully customize the toolbar menu and the navigation icon by calling the following in ViewerBuilder2
, with custom menu resource and drawable resource files:
C#
1public PdfViewCtrlTabHostFragment2 createUsingCustomToolbar(Context context, Uri fileUri, int navIcon, int[] menuRes)
2{
3 return ViewerBuilder2.WithUri(fileUri)
4 .UsingCustomToolbar(menuRes)// Specify a custom toolbar
5 .UsingNavIcon(navIcon) // Specify a custom navigation component
6 .Build(context);
7}
To change the icon color and overflow icon color, in styles.xml
:
XML
1<style name="ToolbarTheme" parent="ThemeOverlay.AppCompat.Dark.ActionBar"> <item name="colorControlNormal">@color/red</item> <item name="iconTint">@color/red</item> </style>
To change the navigation icon color, in styles.xml
(assume MyTheme
is used as the app theme):
C#
1<style name="MyTheme" parent="PDFTronAppTheme"> <item name="toolbarNavigationButtonStyle">@style/ToolbarButtonNavigationStyle</item> </style>
2
3<style name="ToolbarButtonNavigationStyle" parent="Widget.AppCompat.Toolbar.Button.Navigation"> <item name="android:tint">@color/red</item> </style>
If you would like to interact with the host fragment you can override the methods that you are interested in through events. For example, you may want to override ToolbarOptionsItemSelected
when you add a new menu item, so when the item is clicked you can get a callback. As another example, you can get the callback when the navigation icon is clicked if you override NavButtonPressed
.
Here's an example that replaces the default navigation icon and uses a custom toolbar:
C#
1var PdfViewCtrlTabHostFragment2 =
2 (PdfViewCtrlTabHostFragment2) ViewerBuilder2.WithUri(fileUri)
3 // Specify a custom toolbar
4 .UsingCustomToolbar(new int[] { Resource.Menu.my_custom_toolbar })
5 // Specify a custom navigation component
6 .UsingNavIcon(Resource.Drawable.ic_arrow_back_white_24dp)
7 .Build(context);
8
9PdfViewCtrlTabHostFragment2.ToolbarOptionsItemSelected += (sender, e) =>
10{
11 // Called when toolbar option item is selected
12};
13
14PdfViewCtrlTabHostFragment2.NavButtonPressed += (sender, e) =>
15{
16 // Called when navigation button has been clicked
17};
where ic_arrow_back_white_24dp.xml
is a drawable resource file for a back arrow icon, and my_custom_toolbar.xml
is a menu resource file that contains:
XML
1<?xml version="1.0" encoding="utf-8"?>
2<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
3 <item android:id="@+id/action_settings" android:icon="@drawable/ic_settings" android:title="@string/action_settings" app:showAsAction="ifRoom"/>
4 <item android:id="@+id/action_show_toast" android:title="Show toast" app:showAsAction="never" />
5</menu>
This sample replaces the navigation icon, removes all toolbar buttons except the annotation toolbar button, and adds a new Show Toast
button: