X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2Factivities%2FMainWebViewActivity.java;h=ed0259f21c2805179ec03f36b85c41e19d86e89c;hp=a363ef1dc718de05fdbe46e28d7000064969d5ee;hb=b4ad3d976ddc7902546f820df9d8e0e3172b7c69;hpb=026e3182ead986bf03026f1dd31e47ceb330303d diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index a363ef1d..ed0259f2 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -95,6 +95,7 @@ import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.view.GravityCompat; @@ -104,6 +105,7 @@ import androidx.fragment.app.FragmentManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import androidx.viewpager.widget.ViewPager; +import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.navigation.NavigationView; import com.google.android.material.snackbar.Snackbar; @@ -152,8 +154,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -// TODO. New tabs are white in dark mode. - // AppCompatActivity from android.support.v7.app.AppCompatActivity must be used to have access to the SupportActionBar until the minimum API is >= 21. public class MainWebViewActivity extends AppCompatActivity implements CreateBookmarkDialog.CreateBookmarkListener, CreateBookmarkFolderDialog.CreateBookmarkFolderListener, DownloadFileDialog.DownloadFileListener, DownloadImageDialog.DownloadImageListener, DownloadLocationPermissionDialog.DownloadLocationPermissionDialogListener, EditBookmarkDialog.EditBookmarkListener, @@ -221,8 +221,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `inFullScreenBrowsingMode` is used in `onCreate()`, `onConfigurationChanged()`, and `applyAppSettings()`. private boolean inFullScreenBrowsingMode; - // The hide app bar tracker is used in `applyAppSettings()` and `initializeWebView()`. + // The app bar trackers are set in `applyAppSettings()` and used in `initializeWebView()`. private boolean hideAppBar; + private boolean scrollAppBar; // `reapplyDomainSettingsOnRestart` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, and `onAddDomain()`, . private boolean reapplyDomainSettingsOnRestart; @@ -268,6 +269,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // `fileChooserCallback` is used in `onCreate()` and `onActivityResult()`. private ValueCallback fileChooserCallback; + // The default progress view offsets are set in `onCreate()` and used in `initializeWebView()`. + private int defaultProgressViewStartOffset; + private int defaultProgressViewEndOffset; + + // The swipe refresh layout top padding is used when exiting full screen browsing mode. It is used in an inner class in `initializeWebView()`. + private int swipeRefreshLayoutPaddingTop; + // The download strings are used in `onCreate()`, `onRequestPermissionResult()` and `initializeWebView()`. private String downloadUrl; private String downloadContentDisposition; @@ -611,8 +619,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void afterTextChanged(Editable s) { - // Search for the text in `mainWebView`. - currentWebView.findAllAsync(findOnPageEditText.getText().toString()); + // Search for the text in the WebView if it is not null. Sometimes on resume after a period of non-use the WebView will be null. + if (currentWebView != null) { + currentWebView.findAllAsync(findOnPageEditText.getText().toString()); + } } }); @@ -633,8 +643,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Implement swipe to refresh. swipeRefreshLayout.setOnRefreshListener(() -> currentWebView.reload()); - // The swipe to refresh circle doesn't always hide itself completely unless it is moved up 10 pixels. - swipeRefreshLayout.setProgressViewOffset(false, swipeRefreshLayout.getProgressViewStartOffset() - 10, swipeRefreshLayout.getProgressViewEndOffset()); + // Store the default progress view offsets for use later in `initializeWebView()`. + defaultProgressViewStartOffset = swipeRefreshLayout.getProgressViewStartOffset(); + defaultProgressViewEndOffset = swipeRefreshLayout.getProgressViewEndOffset(); // Set the swipe to refresh color according to the theme. if (darkTheme) { @@ -801,8 +812,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Sets the new intent as the activity intent, which replaces the one that originally started the app. setIntent(intent); - // Add a new tab. - addTab(null); + // Get the shared preferences. + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + + if (sharedPreferences.getBoolean("open_intents_in_new_tab", true)) { + // Add a new tab. + addTab(null); + } // Create a URL string. String url; @@ -894,8 +910,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Reset the current domain name so the domain settings will be reapplied. nestedScrollWebView.resetCurrentDomainName(); - // Reapply the domain settings. - applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true); + // Reapply the domain settings if the URL is not null, which can happen if an empty tab is active when returning from settings. + if (nestedScrollWebView.getUrl() != null) { + applyDomainSettings(nestedScrollWebView, nestedScrollWebView.getUrl(), false, true); + } } } } @@ -1062,7 +1080,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Only show Ad Consent if this is the free flavor. adConsentMenuItem.setVisible(BuildConfig.FLAVOR.contentEquals("free")); - // Get the shared preference values. + // Get the shared preferences. SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); // Get the dark theme and app bar preferences.. @@ -3282,11 +3300,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook proxyThroughOrbot = sharedPreferences.getBoolean("proxy_through_orbot", false); fullScreenBrowsingModeEnabled = sharedPreferences.getBoolean("full_screen_browsing_mode", false); hideAppBar = sharedPreferences.getBoolean("hide_app_bar", true); + scrollAppBar = sharedPreferences.getBoolean("scroll_app_bar", true); // Get handles for the views that need to be modified. FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout); + AppBarLayout appBarLayout = findViewById(R.id.appbar_layout); ActionBar actionBar = getSupportActionBar(); LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout); + SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout); // Remove the incorrect lint warning below that the action bar might be null. assert actionBar != null; @@ -3301,6 +3322,24 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook customHeaders.remove("DNT"); } + // Get the current layout parameters. Using coordinator layout parameters allows the `setBehavior()` command. + CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) swipeRefreshLayout.getLayoutParams(); + + // Add the scrolling behavior to the layout parameters. + if (scrollAppBar) { + // Enable scrolling of the app bar. + layoutParams.setBehavior(new AppBarLayout.ScrollingViewBehavior()); + } else { + // Disable scrolling of the app bar. + layoutParams.setBehavior(null); + + // Expand the app bar if it is currently collapsed. + appBarLayout.setExpanded(true); + } + + // Apply the modified layout parameters to the swipe refresh layout. + swipeRefreshLayout.setLayoutParams(layoutParams); + // Set the app bar scrolling for each WebView. for (int i = 0; i < webViewPagerAdapter.getCount(); i++) { // Get the WebView tab fragment. @@ -3315,7 +3354,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview); // Set the app bar scrolling. - nestedScrollWebView.setNestedScrollingEnabled(sharedPreferences.getBoolean("scroll_app_bar", true)); + nestedScrollWebView.setNestedScrollingEnabled(scrollAppBar); } } @@ -4226,23 +4265,37 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Update the privacy icons. `true` redraws the icons in the app bar. updatePrivacyIcons(true); - // Clear the focus from the URL text box. - urlEditText.clearFocus(); - // Get a handle for the input method manager. InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); // Remove the lint warning below that the input method manager might be null. assert inputMethodManager != null; - // Hide the soft keyboard. - inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); + // Get the current URL. + String url = currentWebView.getUrl(); + + if ((url == null) || url.equals("about:blank")) { // The WebView is blank. + // Display the hint in the URL edit text. + urlEditText.setText(""); + + // Request focus for the URL text box. + urlEditText.requestFocus(); + + // Display the keyboard. + inputMethodManager.showSoftInput(urlEditText, 0); + } else { // The WebView has a loaded URL. + // Clear the focus from the URL text box. + urlEditText.clearFocus(); - // Display the current URL in the URL text box. - urlEditText.setText(currentWebView.getUrl()); + // Hide the soft keyboard. + inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); + + // Display the current URL in the URL text box. + urlEditText.setText(url); - // Highlight the URL text. - highlightUrlText(); + // Highlight the URL text. + highlightUrlText(); + } // Set the background to indicate the domain settings status. if (currentWebView.getDomainSettingsApplied()) { @@ -4328,6 +4381,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Toggle the full screen browsing mode. if (inFullScreenBrowsingMode) { // Switch to full screen mode. + // Store the swipe refresh layout top padding. + swipeRefreshLayoutPaddingTop = swipeRefreshLayout.getPaddingTop(); + // Hide the app bar if specified. if (hideAppBar) { // Close the find on page bar if it is visible. @@ -4338,6 +4394,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide the action bar. actionBar.hide(); + + // Check to see if app bar scrolling is disabled. + if (!scrollAppBar) { + // Remove the padding from the top of the swipe refresh layout. + swipeRefreshLayout.setPadding(0, 0, 0, 0); + } } // Hide the banner ad in the free flavor. @@ -4363,6 +4425,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Show the action bar. actionBar.show(); + // Check to see if app bar scrolling is disabled. + if (!scrollAppBar) { + // Add the padding from the top of the swipe refresh layout. + swipeRefreshLayout.setPadding(0, swipeRefreshLayoutPaddingTop, 0, 0); + } + // Show the banner ad in the free flavor. if (BuildConfig.FLAVOR.contentEquals("free")) { // Reload the ad. @@ -4465,15 +4533,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook } }); - if (Build.VERSION.SDK_INT >= 23) { - nestedScrollWebView.setOnScrollChangeListener((View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) -> { - // Update the status of swipe to refresh if it is enabled. - if (nestedScrollWebView.getSwipeToRefresh()) { - // Only enable swipe to refresh if the WebView is scrolled to the top. - swipeRefreshLayout.setEnabled(scrollY == 0); - } - }); - } + // Update the status of swipe to refresh based on the scroll position of the nested scroll WebView. + // Once the minimum API >= 23 this can be replaced with `nestedScrollWebView.setOnScrollChangeListener()`. + nestedScrollWebView.getViewTreeObserver().addOnScrollChangedListener(() -> { + if (nestedScrollWebView.getSwipeToRefresh()) { + // Only enable swipe to refresh if the WebView is scrolled to the top. + swipeRefreshLayout.setEnabled(nestedScrollWebView.getScrollY() == 0); + } + }); // Set the web chrome client. nestedScrollWebView.setWebChromeClient(new WebChromeClient() { @@ -4481,7 +4548,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onProgressChanged(WebView view, int progress) { // Inject the night mode CSS if night mode is enabled. - if (nestedScrollWebView.getNightMode()) { + if (nestedScrollWebView.getNightMode()) { // Night mode is enabled. // `background-color: #212121` sets the background to be dark gray. `color: #BDBDBD` sets the text color to be light gray. `box-shadow: none` removes a lower underline on links // used by WordPress. `text-decoration: none` removes all text underlines. `text-shadow: none` removes text shadows, which usually have a hard coded color. // `border: none` removes all borders, which can also be used to underline text. `a {color: #1565C0}` sets links to be a dark blue. @@ -4503,6 +4570,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Display the WebView after 500 milliseconds. displayWebViewHandler.postDelayed(displayWebViewRunnable, 500); }); + } else { // Night mode is disabled. + // Display the nested scroll WebView if night mode is disabled. + // Because of a race condition between `applyDomainSettings` and `onPageStarted`, + // when night mode is set by domain settings the WebView may be hidden even if night mode is not currently enabled. + nestedScrollWebView.setVisibility(View.VISIBLE); } // Update the progress bar. @@ -4516,13 +4588,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Hide the progress bar. progressBar.setVisibility(View.GONE); - // Display the nested scroll WebView if night mode is disabled. - // Because of a race condition between `applyDomainSettings` and `onPageStarted`, - // when night mode is set by domain settings the WebView may be hidden even if night mode is not currently enabled. - if (!nestedScrollWebView.getNightMode()) { - nestedScrollWebView.setVisibility(View.VISIBLE); - } - //Stop the swipe to refresh indicator if it is running swipeRefreshLayout.setRefreshing(false); } @@ -5095,9 +5160,31 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { - // Get the theme preference. + // Get the preferences. + boolean scrollAppBar = sharedPreferences.getBoolean("scroll_app_bar", true); boolean darkTheme = sharedPreferences.getBoolean("dark_theme", false); + // Get a handler for the app bar layout. + AppBarLayout appBarLayout = findViewById(R.id.appbar_layout); + + // Set the top padding of the swipe refresh layout according to the app bar scrolling preference. + if (scrollAppBar) { + // No padding is needed because it will automatically be placed below the app bar layout due to the scrolling layout behavior. + swipeRefreshLayout.setPadding(0, 0, 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, defaultProgressViewEndOffset); + } else { + // Get the app bar layout height. This can't be done in `applyAppSettings()` because the app bar is not yet populated. + int appBarHeight = appBarLayout.getHeight(); + + // 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); + } + // Reset the list of resource requests. nestedScrollWebView.clearResourceRequests(); @@ -5107,6 +5194,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // If night mode is enabled, hide `mainWebView` until after the night mode CSS is applied. if (nestedScrollWebView.getNightMode()) { nestedScrollWebView.setVisibility(View.INVISIBLE); + } else { + nestedScrollWebView.setVisibility(View.VISIBLE); } // Hide the keyboard. @@ -5250,8 +5339,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Display the keyboard. inputMethodManager.showSoftInput(urlEditText, 0); - // Hide the WebView, which causes the default background color to be displayed according to the theme. // TODO - nestedScrollWebView.setVisibility(View.GONE); + // Hide the WebView, which causes the default background color to be displayed according to the theme. + nestedScrollWebView.setVisibility(View.INVISIBLE); // Apply the domain settings. This clears any settings from the previous domain. applyDomainSettings(nestedScrollWebView, "", true, false);