> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/android/changelogs/version-10/v10-2-0.md).

# Version 10.2.0 Changelog (June 21, 2023)

World's #1 PDF SDK Library for Web, Mobile, Server, Desktop

Version: 10.2.0.82346

Release Date: June 21, 2023

## New features

* Adds `ViewerConfig.Builder.movableToolbarEnabled(bool)` to move annotation toolbar to left, right, and bottom edge of the viewer

![](https://226546913-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F0QItsdFBmuuL9ezHimHy%2Fuploads%2Fgit-blob-a8b705ae2e93eb263dc4ee39cbd4808cdda7c889%2F523f56d7e8c48a861e3ae4b8b45eaa643f48a0a9-600x1333.gif?alt=media)

* Adds `ToolManagerBuilder.setInsertMultipleImagesEnabled(bool)` to add multiple image stamps to the viewer at a time

## Breaking changes

* `com.edmodo:cropper:2.0.0` dependency must be removed from dependency list if you integrated manually with AAR or Tools source project

## Notes

This release of Apryse for Android brings the core PDF functionality inline with version 10.2.0 of the Apryse cross-platform APIs. More information can be found on What's new for cross-platform APIs. Most non-module related changes apply to Android.

## Fixed

* Fix issue where view mode dialog is cutoff in phone landscape mode
* Fix issue where search would not restart when show/hide the full search result window
* Fix issue where on tablet signature selection dialog does not show up on first tap
* Fix issue where line ending style changes when select/deselect
* Fix potential crash when import XFDF to collaboration viewer when bbox is invalid
* Fix potential crash when rotating signature selection dialog when activity is recreated on orientation change
* Improve ReflowControl where show/hide toolbar will no longer change current viewport

## APIs

### PDFViewCtrlTools package

#### ToolManagerBuilder

*new* method: `ToolManagerBuilder setInsertMultipleImagesEnabled(boolean)`

#### ViewerConfig

*new* method: `AnnotationToolbarPosition annotationToolbarPosition()`

*new* method: `boolean movableToolbarEnabled()`

*new* method: `boolean presetExpanding()`

*new* method: `boolean showEmptyPreset()`

#### Builder

*new* method: `Builder annotationToolbarPosition(AnnotationToolbarPosition)`

*new* method: `Builder movableToolbarEnabled(boolean)`

*new* method: `Builder presetExpanding(boolean)`

*new* method: `Builder showEmptyPreset(boolean)`

#### Builder

*new* method: `Builder setShowHorizontally(boolean)`

#### PdfViewCtrlTabFragment2

*new* method: `View getOverlayStub()`

*new* method: `void setAnnotationToolbarComponentListener(AnnotationToolbarComponentListener)`

#### AnnotationToolbarComponentListener

*new* interface: `AnnotationToolbarComponentListener`

*new* method: `AnnotationToolbarPosition getAnnotationToolbarPosition()`

#### PdfViewCtrlTabHostFragment2

*new* method: `AnnotationToolbarPosition getAnnotationToolbarPosition()`

*new* method: `boolean onDrag(View, DragEvent)`

*new* method: `void setAnnotationToolbarPosition(AnnotationToolbarPosition)`

*modified* class: `PdfViewCtrlTabHostFragment2`

|       | Declaration                                                                                                                                                                                 |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| From: | public class PdfViewCtrlTabHostFragment2 extends PdfViewCtrlTabHostBaseFragment implements TabListener,SnackbarListener,ComponentListener                                                   |
| To:   | public class PdfViewCtrlTabHostFragment2 extends PdfViewCtrlTabHostBaseFragment implements TabListener,SnackbarListener,ComponentListener,AnnotationToolbarComponentListener,OnDragListener |

#### AnnotationToolbarPosition

*new* final class: `AnnotationToolbarPosition`

*new* static final field: `AnnotationToolbarPosition BOTTOM`

*new* static final field: `AnnotationToolbarPosition END`

*new* static final field: `AnnotationToolbarPosition START`

*new* static final field: `AnnotationToolbarPosition TOP`

*new* static method: `boolean isVertical(AnnotationToolbarPosition)`

*new* static method: `AnnotationToolbarPosition valueOf(String)`

*new* static method: `AnnotationToolbarPosition[] values()`

#### ReflowControl

*new* method: `void scrollPageBy(int, int)`

#### ReflowPagerAdapter

*new* method: `void scrollPageBy(int, int)`

#### StyleDialogBehavior

*new* class: `StyleDialogBehavior`

*new* method: `boolean onLayoutChild(CoordinatorLayout, View, int)`

*new* method: `void showHorizontally(boolean)`

#### TabSwitcherAdapter

*new* method: `ArrayList<TabSwitcherItem> getItems()`

*new* method: `void insert(int, TabSwitcherItem)`

*new* method: `void onItemDismiss(int)`

*new* method: `void onItemDrop(int, int)`

*new* method: `boolean onItemMove(int, int)`

*new* method: `TabSwitcherItem removeAt(int)`

*modified* class: `TabSwitcherAdapter`

|       | Declaration                                                                       |
| ----- | --------------------------------------------------------------------------------- |
| From: | public class TabSwitcherAdapter extends Adapter                                   |
| To:   | public class TabSwitcherAdapter extends Adapter implements ItemTouchHelperAdapter |

#### TabSwitcherDialogFragment

*new* method: `void onDismiss(DialogInterface)`

#### TabSwitcherItem

*new* method: `boolean equals(Object)`

*new* method: `int hashCode()`

#### Builder

*new* method: `Builder setShowHorizontally(boolean)`

#### LineCreate

*new* static method: `void calculateLineEndingStyle(LineEndingStyle, PointF, PointF, PointF, PointF, LineEndingCalculationVariables)`

*removed* static method: `void calculateLineEndingStyle(LineEndingStyle, LineEndingStyle, PointF, PointF, PointF, PointF, PointF, PointF, float, double, LineEndingCalculationVariables)`

#### Stamper

*new* static field: `int STAMPER_MULTI_SELECT_MAX_NUM`

#### ToolManager

*new* method: `boolean isInsertMultipleImagesEnabled()`

*new* method: `void setInsertMultipleImagesEnabled(boolean)`

#### LineEndingCalculationVariables

*new* constructor: `LineEndingCalculationVariables(PointF, PointF, float, double, LineEndingStyle, LineEndingStyle)`

*new* method: `void recalculate(Vec2, Vec2)`

*removed* field: `Vec2 current`

*removed* field: `Vec2 end`

*removed* field: `double len`

*removed* field: `Vec2 line`

*removed* field: `Vec2 line90`

*removed* field: `double sqrt2`

*removed* field: `double sqrt3`

#### PdfViewCtrlSettingsManager

*new* static method: `AnnotationToolbarPosition getAnnotationToolbarPosition(Context, AnnotationToolbarPosition)`

*new* static method: `void setAnnotationToolbarPosition(Context, AnnotationToolbarPosition)`

#### Utils

*new* static method: `boolean isAndroidT()`

*new* static method: `void requestPostNotificationsPermissions(Activity, int)`

#### Vec2

*new* method: `void addX(Vec2)`

*new* method: `void addY(Vec2)`

*new* method: `Vec2 normalized()`

*new* method: `void subtractX(Vec2)`

*new* method: `void subtractY(Vec2)`

#### ViewerUtils

*new* static method: `Uri openImageIntent(Fragment, boolean)`

*new* static method: `List<Map<String, Object>> readMultiImageIntent(Intent, Context, Uri, boolean)`

#### ConsumeEndInsetFrameLayout

*new* class: `ConsumeEndInsetFrameLayout`

*new* constructor: `ConsumeEndInsetFrameLayout(Context)`

*new* constructor: `ConsumeEndInsetFrameLayout(Context, AttributeSet)`

*new* constructor: `ConsumeEndInsetFrameLayout(Context, AttributeSet, int)`

*new* method: `WindowInsets dispatchApplyWindowInsets(WindowInsets)`

#### ConsumeHorizontalInsetFrameLayout

*new* class: `ConsumeHorizontalInsetFrameLayout`

*new* constructor: `ConsumeHorizontalInsetFrameLayout(Context)`

*new* constructor: `ConsumeHorizontalInsetFrameLayout(Context, AttributeSet)`

*new* constructor: `ConsumeHorizontalInsetFrameLayout(Context, AttributeSet, int)`

*new* method: `WindowInsets dispatchApplyWindowInsets(WindowInsets)`

#### ConsumeStartInsetFrameLayout

*new* class: `ConsumeStartInsetFrameLayout`

*new* constructor: `ConsumeStartInsetFrameLayout(Context)`

*new* constructor: `ConsumeStartInsetFrameLayout(Context, AttributeSet)`

*new* constructor: `ConsumeStartInsetFrameLayout(Context, AttributeSet, int)`

*new* method: `WindowInsets dispatchApplyWindowInsets(WindowInsets)`

#### PresetActionButton

*new* method: `void setPresetIconSize(int)`

*new* method: `void setVerticalLayout(AnnotationToolbarPosition)`

#### PresetBarView

*new* constructor: `PresetBarView(ViewGroup, AnnotationToolbarPosition)`

*new* method: `AnnotationToolbarPosition getToolbarPosition()`

*new* method: `void setInsideAnnotationToolbar(boolean)`

*new* method: `void setVerticalLayout(AnnotationToolbarPosition)`

#### PresetSingleButton

*new* method: `void setVerticalLayout(AnnotationToolbarPosition)`

#### TabletPresetBarView

*new* constructor: `TabletPresetBarView(ViewGroup, AnnotationToolbarPosition)`

#### SignaturePresetComponent

*new* constructor: `SignaturePresetComponent(LifecycleOwner, SignatureViewModel, Context)`

*new* method: `void createSignatureSelectionDialog()`

*new* method: `void setAnchorView(View)`

*new* method: `void setShowHorizontally(boolean)`

*new* method: `void show(FragmentManager)`

*removed* constructor: `SignaturePresetComponent(LifecycleOwner, SignatureViewModel, SignatureSelectionView, Context)`

*removed* method: `void show()`

#### SignatureSelectionDialog

*new* constructor: `SignatureSelectionDialog()`

*new* method: `void closeDialog()`

*new* static method: `SignatureSelectionDialog newInstance()`

*new* method: `void setShowHorizontally(boolean)`

*new* method: `void showDialog(FragmentManager)`

*removed* constructor: `SignatureSelectionDialog(FragmentManager)`

*removed* method: `void close()`

*removed* method: `void show()`

#### SignatureSelectionView

*new* method: `void closeDialog()`

*new* method: `void showDialog(FragmentManager)`

*removed* method: `void close()`

*removed* method: `void show()`

#### ToolbarButtonType

*new* static final field: `ToolbarButtonType DRAG_HANDLE`

#### AnnotationToolbarComponent

*new* method: `void addButtonLongClickListener(OnLongClickListener)`

*new* method: `void addToolbarActionsLeftOptionalContainer(View)`

*new* method: `ActionToolbar getToolbarView()`

*new* method: `void removeButtonLongClickListener(OnLongClickListener)`

*new* method: `void setVerticalLayout(ViewGroup, AnnotationToolbarPosition)`

*modified* method: `AppCompatButton buildRedactionApplyButton()`

|       | Declaration                                        |
| ----- | -------------------------------------------------- |
| From: | public AppCompatButton buildRedactionApplyButton() |
| To:   | public View buildRedactionApplyButton()            |

#### ButtonId

*new* static final field: `ButtonId DRAG_HANDLE`

#### TabletAnnotationToolbarComponent

*new* constructor: `TabletAnnotationToolbarComponent(LifecycleOwner, FragmentManager, AnnotationToolbarViewModel, PresetBarViewModel, ToolManagerViewModel, SignatureViewModel, AnnotationToolbarView, TabletPresetBarView, boolean, HashSet<ToolbarButtonType>, boolean)`

*new* method: `void setInsideAnnotationToolbar(boolean)`

*new* method: `void setPresetBarVerticalLayout(AnnotationToolbarPosition)`

*removed* constructor: `TabletAnnotationToolbarComponent(Fragment, FragmentManager, AnnotationToolbarViewModel, PresetBarViewModel, ToolManagerViewModel, SignatureViewModel, AnnotationToolbarView, boolean, HashSet<ToolbarButtonType>, boolean)`

*removed* method: `void setTabletMode(boolean)`

#### ActionToolbar

*new* constructor: `ActionToolbar(Context, AnnotationToolbarPosition, boolean, boolean)`

*new* method: `void addToolbarActionsLeftOptionalContainer(View)`

*new* method: `AnnotationToolbarPosition getToolbarPosition()`

*new* method: `boolean isVertical()`

*new* method: `void scrollToToolButton(int)`

*new* method: `void setVerticalLayout(AnnotationToolbarPosition)`

#### AnnotationToolbarImageButtonInflater

*new* class: `AnnotationToolbarImageButtonInflater`

*new* static method: `AppCompatImageButton inflate(Context, int)`

#### AnnotationToolbarView

*new* constructor: `AnnotationToolbarView(ViewGroup, AnnotationToolbarPosition, boolean, boolean)`

*new* method: `void addToolbarActionsLeftOptionalContainer(View)`

*new* method: `ActionToolbar getActionToolbar()`

*new* method: `AnnotationToolbarPosition getToolbarPosition()`

*new* method: `boolean isVertical()`

*new* method: `void scrollToToolButton(int)`

*new* method: `void setVerticalLayout(ViewGroup, AnnotationToolbarPosition)`

#### SingleButtonToolbar

*new* constructor: `SingleButtonToolbar(Context, AnnotationToolbarPosition)`

### pdfnet-demo-utils package

#### PopulateFileInfoListTask

*new* class: `PopulateFileInfoListTask`

*new* constructor: `PopulateFileInfoListTask(FavoritesViewFragment, Context)`

#### DialogConfirmationListener

*new* interface: `DialogConfirmationListener`

*new* method: `void onDialogConfirmed()`

#### FileManager

*new* static method: `CharSequence createDeleteConfirmationMessage(Context, TrashEntity)`

*new* static method: `void showDeleteConfirmationDialog(Context, CharSequence, DialogConfirmationListener)`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/android/changelogs/version-10/v10-2-0.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
