+ // Get a handle for the input method manager.
+ InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ // Instantiate the blocklist helper.
+ BlocklistHelper blocklistHelper = new BlocklistHelper();
+
+ // Remove the lint warning below that the input method manager might be null.
+ assert inputMethodManager != null;
+
+ // Set the app bar scrolling.
+ nestedScrollWebView.setNestedScrollingEnabled(scrollAppBar);
+
+ // Allow pinch to zoom.
+ nestedScrollWebView.getSettings().setBuiltInZoomControls(true);
+
+ // Hide zoom controls.
+ nestedScrollWebView.getSettings().setDisplayZoomControls(false);
+
+ // Don't allow mixed content (HTTP and HTTPS) on the same website.
+ nestedScrollWebView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
+
+ // Set the WebView to load in overview mode (zoomed out to the maximum width).
+ nestedScrollWebView.getSettings().setLoadWithOverviewMode(true);
+
+ // Explicitly disable geolocation.
+ nestedScrollWebView.getSettings().setGeolocationEnabled(false);
+
+ // Allow loading of file:// URLs. This is necessary for opening MHT web archives, which are copies into a temporary cache location.
+ nestedScrollWebView.getSettings().setAllowFileAccess(true);
+
+ // Create a double-tap gesture detector to toggle full-screen mode.
+ GestureDetector doubleTapGestureDetector = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener() {
+ // Override `onDoubleTap()`. All other events are handled using the default settings.
+ @Override
+ public boolean onDoubleTap(MotionEvent event) {
+ if (fullScreenBrowsingModeEnabled) { // Only process the double-tap if full screen browsing mode is enabled.
+ // Toggle the full screen browsing mode tracker.
+ inFullScreenBrowsingMode = !inFullScreenBrowsingMode;
+
+ // Toggle the full screen browsing mode.
+ if (inFullScreenBrowsingMode) { // Switch to full screen mode.
+ // Hide the app bar if specified.
+ if (hideAppBar) { // The app bar is hidden.
+ // Close the find on page bar if it is visible.
+ closeFindOnPage(null);
+
+ // Hide the tab linear layout.
+ tabsLinearLayout.setVisibility(View.GONE);
+
+ // Hide the action bar.
+ actionBar.hide();
+
+ // Set layout and scrolling parameters according to the position of the app bar.
+ if (bottomAppBar) { // The app bar is at the bottom.
+ // Reset the WebView padding to fill the available space.
+ swipeRefreshLayout.setPadding(0, 0, 0, 0);
+ } else { // The app bar is at the top.
+ // Check to see if the app bar is normally scrolled.
+ if (scrollAppBar) { // The app bar is scrolled when it is displayed.
+ // Get the swipe refresh layout parameters.
+ CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
+
+ // Remove the off-screen scrolling layout.
+ swipeRefreshLayoutParams.setBehavior(null);
+ } else { // The app bar is not scrolled when it is displayed.
+ // Remove the padding from the top of the swipe refresh layout.
+ swipeRefreshLayout.setPadding(0, 0, 0, 0);
+
+ // The swipe refresh circle must be moved above the now removed status bar location.
+ swipeRefreshLayout.setProgressViewOffset(false, -200, defaultProgressViewEndOffset);
+ }
+ }
+ } else { // The app bar is not hidden.
+ // Adjust the UI for the bottom app bar.
+ if (bottomAppBar) {
+ // Adjust the UI according to the scrolling of the app bar.
+ if (scrollAppBar) {
+ // Reset the WebView padding to fill the available space.
+ swipeRefreshLayout.setPadding(0, 0, 0, 0);
+ } else {
+ // Move the WebView above the app bar layout.
+ swipeRefreshLayout.setPadding(0, 0, 0, appBarHeight);
+ }
+ }
+ }
+
+ /* Hide the system bars.
+ * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
+ * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
+ * SYSTEM_UI_FLAG_HIDE_NAVIGATION hides the navigation bar on the bottom or right of the screen.
+ * SYSTEM_UI_FLAG_IMMERSIVE_STICKY makes the status and navigation bars translucent and automatically re-hides them after they are shown.
+ */
+ rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ } else { // Switch to normal viewing mode.
+ // Show the app bar if it was hidden.
+ if (hideAppBar) {
+ // Show the tab linear layout.
+ tabsLinearLayout.setVisibility(View.VISIBLE);
+
+ // Show the action bar.
+ actionBar.show();
+ }
+
+ // Set layout and scrolling parameters according to the position of the app bar.
+ if (bottomAppBar) { // The app bar is at the bottom.
+ // Adjust the UI.
+ if (scrollAppBar) {
+ // Reset the WebView padding to fill the available space.
+ swipeRefreshLayout.setPadding(0, 0, 0, 0);
+ } else {
+ // Move the WebView above the app bar layout.
+ swipeRefreshLayout.setPadding(0, 0, 0, appBarHeight);
+ }
+ } else { // The app bar is at the top.
+ // Check to see if the app bar is normally scrolled.
+ if (scrollAppBar) { // The app bar is scrolled when it is displayed.
+ // Get the swipe refresh layout parameters.
+ CoordinatorLayout.LayoutParams swipeRefreshLayoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams();
+
+ // Add the off-screen scrolling layout.
+ swipeRefreshLayoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior());
+ } else { // The app bar is not scrolled when it is displayed.
+ // The swipe refresh layout must be manually moved below the app bar layout.
+ swipeRefreshLayout.setPadding(0, appBarHeight, 0, 0);
+
+ // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels.
+ swipeRefreshLayout.setProgressViewOffset(false, defaultProgressViewStartOffset - 10 + appBarHeight, defaultProgressViewEndOffset + appBarHeight);
+ }
+ }
+
+ // Remove the `SYSTEM_UI` flags from the root frame layout.
+ rootFrameLayout.setSystemUiVisibility(0);
+ }
+
+ // Consume the double-tap.
+ return true;
+ } else { // Do not consume the double-tap because full screen browsing mode is disabled.
+ return false;