Customize toolbar menus on Android
You can modify Nutrient’s menus by adding new actions or removing existing actions. For code examples, see CustomActionsExample
(Java) or CustomActionsKotlinExample
(Kotlin) from our example Catalog.
Modifying the action bar
If you are using the PdfActivity
or a custom subclass of this activity, Nutrient will automatically show toolbar actions based on the loaded configuration. Nutrient uses the default support Toolbar
widget together with a dynamically populated Menu
.
Adding custom actions
To add custom actions to existing actions, you need to use a custom activity class and override #onCreateOptionsMenu
or #onPrepareOptionsMenu
, depending on your needs. The calls to these methods are made the same way they are by default on the Android system. #onCreateOptionsMenu
is called the first time the menu is created, and #onPrepareOptionsMenu
is called whenever the menu is changed or invalidated. To alter the list of items that will be displayed in the first place, you need to override #onGenerateMenuItemIds
and return a final list of menu item IDs that will be displayed, like so:
class CustomActivity : PdfActivity() { /** * Override this method to get the list of menu item IDs, as they'll be ordered by default. * You can add your own menu item IDs that you can later edit in `[.onCreateOptionsMenu]` * or `[.onPrepareOptionsMenu]`. */ override fun onGenerateMenuItemIds(menuItems: MutableList<Int>): List<Int> { // For example, let's say we want to add custom menu items after the outline button. // First, we get an index of outline buttons (all default button IDs can be retrieved // via `MENU_OPTION_*` variables defined in the `PdfActivity`). val indexOfOutlineButton = menuItems.indexOf(PdfActivity.MENU_OPTION_OUTLINE) // Add a custom item after the outline button. menuItems.addAll(indexOfOutlineButton + 1, R.id.custom_action1) // Return the new menu items order. return menuItems } override fun onCreateOptionsMenu(menu: Menu): Boolean { // This will populate the menu with items ordered as specified in `onGenerateMenuItemIds()`. super.onCreateOptionsMenu(menu) // Edit the custom button. val customMenuItem = menu.findItem(R.id.custom_action1) customMenuItem.title = "Menu Item 1" customMenuItem.setIcon(R.drawable.ic_arrow_left) // Let's say we want the icon to be tinted the same color as the default ones. We can read the color // from the theme, or we can specify the same color we have in the theme. Reading from the theme is a bit // more complex, but this a better way to do it, so here's how: val a = theme.obtainStyledAttributes( null, R.styleable.pspdf__ActionBarIcons, R.attr.pspdf__actionBarIconsStyle, R.style.PSPDFKit_ActionBarIcons ) val mainToolbarIconsColor = a.getColor(R.styleable.pspdf__ActionBarIcons_pspdf__iconsColor, ContextCompat.getColor(this, R.color.white)) a.recycle() // Tinting custom menu drawable. val customIcon = customMenuItem.icon DrawableCompat.setTint(customIcon, mainToolbarIconsColor) customMenuItem.icon = customIcon // All our menu items are marked as `SHOW_AS_ALWAYS`. If you want to, for example, // just show the first four items and send the others to the overflow, you can simply do: for (i in 0 until menu.size()) { menu.getItem(i).setShowAsAction(if (i < 4) MenuItem.SHOW_AS_ACTION_ALWAYS else MenuItem.SHOW_AS_ACTION_NEVER) } return true } override fun onPrepareOptionsMenu(menu: Menu): Boolean { // Here, you can edit your items when the menu is being invalidated. // To invalidate the menu, call `supportInvalidateOptionsMenu();` return super.onPrepareOptionsMenu(menu) } }
public class CustomActivity extends PdfActivity { /** * Override this method to get the list of menu item IDs, as they'll be ordered by default. * You can add your own menu item IDs that you can later edit in `{@link #onCreateOptionsMenu(Menu)}` * or `{@link #onPrepareOptionsMenu(Menu)}`. */ @NonNull @Override public List<Integer> onGenerateMenuItemIds(@NonNull List<Integer> menuItems) { // For example let's say we want to add custom menu items after the outline button. // First, we get an index of outline buttons (all default button IDs can be retrieved // via `MENU_OPTION_*` variables defined in the `PdfActivity`. int indexOfOutlineButton = menuItems.indexOf(MENU_OPTION_OUTLINE); // Add a custom item after the outline button. menuItems.add(indexOfOutlineButton + 1, R.id.custom_action1); // Return the new menu items order. return menuItems; } @Override public boolean onCreateOptionsMenu(Menu menu) { // This will populate the menu with items ordered as specified in `onGenerateMenuItemIds()`. super.onCreateOptionsMenu(menu); // Edit the custom button. MenuItem customMenuItem = menu.findItem(R.id.custom_action1); customMenuItem.setTitle("Menu Item 1"); customMenuItem.setIcon(R.drawable.ic_arrow_left); // Let's say we want the icon to be tinted the same color as the default ones. We can read the color // from the theme, or we can specify the same color we have in the theme. Reading from the theme is a bit // more complex, but this a better way to do it, so here's how: final TypedArray a = getTheme().obtainStyledAttributes( null, R.styleable.pspdf__ActionBarIcons, R.attr.pspdf__actionBarIconsStyle, R.style.PSPDFKit_ActionBarIcons ); int mainToolbarIconsColor = a.getColor(R.styleable.pspdf__ActionBarIcons_pspdf__iconsColor, ContextCompat.getColor(this, R.color.white)); a.recycle(); // Tinting custom menu drawable. Drawable customIcon = customMenuItem.getIcon(); DrawableCompat.setTint(customIcon, mainToolbarIconsColor); customMenuItem.setIcon(customIcon); // All our menu items are marked as `SHOW_AS_ALWAYS`. If you want to, for example, // just show the first four items and send the others to the overflow, you can simply do: for (int i = 0; i < menu.size(); i++) { menu.getItem(i).setShowAsAction(i < 4 ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER); } return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { // Here, you can edit your items when the menu is being invalidated. // To invalidate the menu, call `supportInvalidateOptionsMenu();` return super.onPrepareOptionsMenu(menu); } }
Specifying the position for custom actions
To add a custom action at a specific position, your activity has to override the #onGenerateMenuItemIds
method. From there, you can control at which position the custom item should be inserted. Below is an example of how to insert a custom menu item directly after the outline button:
class CustomActivity : PdfActivity() { override fun onGenerateMenuItemIds(menuItems: MutableList<Int>): List<Int> { // First, we get an index of the outline button. val indexOfOutlineButton = menuItems.indexOf(PdfActivity.MENU_OPTION_OUTLINE) // Add items after the outline button. menuItems.add( indexOfOutlineButton + 1, R.id.custom_action // Your custom action ID. ) // Return the new order for menu items. return menuItems } }
public class CustomActivity extends PdfActivity { @Override public List<Integer> onGenerateMenuItemIds(@NonNull List<Integer> menuItems) { // First, we get an index of the outline button. int indexOfOutlineButton = menuItems.indexOf(MENU_OPTION_OUTLINE); // Add items after the outline button. menuItems.add( indexOfOutlineButton + 1, R.id.custom_action // Your custom action ID. ); // Return the new order for menu items. return menuItems; } }
Default menu option IDs
Here are the IDs for all the menu options from the main action bar. You can reference them using PdfActivity
:
ID | Default action |
---|---|
MENU_OPTION_EDIT_ANNOTATIONS |
Enters annotation editing mode. |
MENU_OPTION_OUTLINE |
Shows PdfOutlineView with bookmarks, document info, an outline, and the annotation list. |
MENU_OPTION_SEARCH |
Enters the search document contents mode. |
MENU_OPTION_SETTINGS |
Shows the document settings menu. |
MENU_OPTION_SHARE |
Shows the share dialog. |
MENU_OPTION_THUMBNAIL_GRID |
Enters document editor mode. |
Removing default actions
To remove default actions (search, share, document settings, etc.), you need to override the #onGenerateMenuItemIds
method and remove the corresponding IDs from the list:
class CustomActivity : PdfActivity() { override fun onGenerateMenuItemIds(menuItems: MutableList<Int>): List<Int> { // Take the default menu item IDs and remove the outlined items. menuItems.remove(PdfActivity.MENU_OPTION_OUTLINE) // Return the new order for the menu items. return menuItems } }
public class CustomActivity extends PdfActivity { @Override public List<Integer> onGenerateMenuItemIds(@NonNull List<Integer> menuItems) { // Take the default menu item IDs and remove the outlined items. menuItems.remove(PdfActivity.MENU_OPTION_OUTLINE); // Return the new order for the menu items. return menuItems; } }
Keep in mind that manipulating menu items will not affect certain initialization steps performed for the actions they represent, and it will still be possible to trigger those actions programmatically. For example, removing the search action as described above will still initialize SearchView
under the hood, and it can still be invoked programmatically.
If you want to not only remove a certain action from the menu but also completely disable the functionality it represents, use one of the following PdfActivityConfiguration
options:
Configuration option | Result |
---|---|
annotationEditingEnabled(false) |
Disables annotation editing and removes all related UI elements. |
outlineEnabled(false) |
Disables the outline and removes all related UI elements. |
searchEnabled(false) |
Disables search functionality and removes all related UI elements. |
settingsMenuEnabled(false) |
Removes the settings menu. |
setEnabledShareFeatures(ShareFeatures.none()) |
Disables share functionality and removes all related UI elements. |
thumbnailGridEnabled(false) |
Disables the thumbnail grid and removes all related UI elements. |
Customizing the document settings menu
You can control which items will be shown in a document settings menu (see the default version below).
To specify which items should be shown in this menu, use PdfActivityConfiguration.Builder#setSettingsMenuItems
. For example, the following code will result in the settings menu showing only the page transition, page layout, and document theme:
configuration.setSettingsMenuItems(EnumSet.of( SettingsMenuItemType.THEME, SettingsMenuItemType.PAGE_LAYOUT, SettingsMenuItemType.PAGE_TRANSITION ) )
configuration.setSettingsMenuItems(EnumSet.of( SettingsMenuItemType.THEME, SettingsMenuItemType.PAGE_LAYOUT, SettingsMenuItemType.PAGE_TRANSITION ) )
The result will look like the following.
To exclude the settings menu completely, you can use PdfActivityConfiguration.Builder#settingsMenuEnabled(false)
:
configuration.settingsMenuEnabled(false)
configuration.settingsMenuEnabled(false)
Adding an action to the share menu
By overriding the #onPrepareOptionsMenu
method, you can also add actions to submenus — for example, to the share menu. To do so, first fetch the menu item via its ID, PdfActivity.MENU_OPTION_SHARE
, and then add your action to its submenu:
val shareMenu = menu.findItem(PdfActivity.MENU_OPTION_SHARE).subMenu shareMenu.add(0, R.id.my_custom_action, 0, "My custom share action")
final SubMenu shareMenu = menu.findItem(PdfActivity.MENU_OPTION_SHARE).getSubMenu(); shareMenu.add(0, R.id.my_custom_action, 0, "My custom share action");