Selecting text in Android PDF viewer

The TextSelectionManager interface provides two listeners:

These listeners enable you to monitor text selection changes. The default PdfActivity implementation displays a contextual toolbar when text is long-pressed and text selection mode starts. This toolbar is called TextSelectionToolbar and allows you to perform the following five actions with the selected text:

  • Highlight
  • Speak
  • Copy to clipboard
  • Share
  • Search

Registering custom listeners

You can create custom listeners for TextSelectionManager to handle changes in text selection and text selection mode (entering and exiting):

class MyActivity : PdfActivity(), TextSelectionManager.OnTextSelectionChangeListener, TextSelectionManager.OnTextSelectionModeChangeListener {
const val TAG = "MyActivity.TextSelection"
override fun onCreate(savedInstanceState: Bundle?) {
PdfFragment.addOnTextSelectionModeChangeListener(this)
PdfFragment.addOnTextSelectionChangeListener(this)
}
override fun onDestroy(savedInstanceState: Bundle?) {
PdfFragment.removeOnTextSelectionModeChangeListener(this)
PdfFragment.removeOnTextSelectionChangeListener(this)
}
override fun onEnterTextSelectionMode(controller: TextSelectionController) {
Log.i(TAG, "Text selection mode has started.")
}
override fun onExitTextSelectionMode(controller: TextSelectionController) {
Log.i(TAG, "Text selection mode has ended.")
}
override fun onTextSelectionChange(newTextSelection: TextSelection?, currentTextSelection: TextSelection?): Boolean {
if (newTextSelection != null) {
Log.i(TAG, "Selected text was: ${newTextSelection.text}")
} else {
Log.i(TAG, "Text selection is cleared.")
}
// Return `false` to prevent changes to the current selection state, if needed.
return true
}
}

By implementing these listeners, you can add custom reactions to text selection events.

This setup doesn’t override the default behavior — it only adds additional listeners. If you need to completely change the behavior (e.g. replacing the toolbar with a custom user interface), use PdfFragment in a custom activity and bind it to the TextSelectionController.

Customize text selection actions

You can modify existing text selection actions or add new ones using toolbar.setMenuItems(...). To access the TextSelectionToolbar, register the OnContextualToolbarLifecycleListener and configure actions in its #onPrepareContextualToolbar method:

class MyActivity : PdfActivity(), ToolbarCoordinatorLayout.OnContextualToolbarLifecycleListener {
private lateinit var customTextSelectionAction: ContextualToolbarMenuItem
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Register the activity as a callback for contextual toolbar changes.
// It will be called once the `TextSelectionToolbar` is going to be presented.
setOnContextualToolbarLifecycleListener(this)
// Create a custom menu item that will be shown inside the text selection toolbar.
customTextSelectionAction = ContextualToolbarMenuItem.create(
this,
R.id.custom_text_action,
AppCompatDrawableManager.get().getDrawable(this, R.drawable.ic_my_action),
"Custom text action",
Color.WHITE,
Color.RED,
false)
}
override fun onPrepareContextualToolbar(toolbar: ContextualToolbar) {
// Add the custom action once the selection toolbar is being prepared.
// At this point, you could also remove undesired actions from the toolbar.
if (toolbar is TextSelectionToolbar) {
val menuItems = toolbar.getMenuItems()
if (!menuItems.contains(customTextSelectionAction)) {
menuItems.add(customTextSelectionAction)
toolbar.setMenuItems(menuItems)
}
}
}
override fun onDisplayContextualToolbar(toolbar: ContextualToolbar) {
// Register a click listener to handle taps on the custom text selection action.
toolbar.setOnMenuItemClickListener { toolbar, menuItem ->
var handled = false
if (menuItem.id == R.id.custom_text_action) {
handled = true
Toast.makeText(this@MyActivity, "Text selection action triggered!", Toast.LENGTH_SHORT)
.show()
}
handled
}
}
override fun onRemoveContextualToolbar(toolbar: ContextualToolbar) {
toolbar.setOnMenuItemClickListener(null)
}
}

This approach allows you to add custom actions to the toolbar or remove existing ones when the toolbar is prepared.

Selecting text programmatically

You can programmatically select text using the PdfFragment#enterTextSelectionMode method and specifying the text range to be selected. You can retrieve the text of the current page by calling the PdfDocument#getPageText method.

For example, to select the first occurrence of a string on the page, use the following code:

// Search for the position of text that should be selected.
val textToSelect = "text to select"
val textIndexOnPage = document.getPageText(pageIndex).indexOf(textToSelect)
if (textIndexOnPage >= 0) {
// Select the text.
fragment.enterTextSelectionMode(pageIndex, Range(textIndexOnPage, textToSelect.length))
}

Alternatively, you can select text by providing a list of rectangles, and the text beneath these rectangles will be selected. Use the TextSelectionRectangles object, which is created in one of the following ways:

  • Provide a list of rectangles (no markup padding applied).
  • Provide a list of rectangles with markup padding.
fragment.enterTextSelectionMode(pageIndex, TextSelectionRectangles(rectangles, markupRectangles))

Nutrient Android SDK throws an IllegalStateException in the following scenarios:

  • Invalid parameters are provided.
  • The text range exceeds the available text on the page.
  • No text exists beneath the specified rectangles.