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=e3adab232ba16b4d74a0b2cf9030ae8b3c0836e1;hp=4193364de5c0041abc3b31948a7272f19b0ef80c;hb=16c71df36aa4c1a82d4afdb040758902049e4cb0;hpb=fd2c21ea8241dce9c86a3213b9b9e325d5e7ce4a 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 4193364d..e3adab23 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,9 +154,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -// TODO. New tabs are white in dark mode. -// TODO. Find on page. - // 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, @@ -222,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; @@ -269,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; @@ -479,6 +486,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook @Override public void onPageSelected(int position) { + // Close the find on page bar if it is open. + closeFindOnPage(null); + // Set the current WebView. setCurrentWebView(position); @@ -609,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()); + } } }); @@ -631,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) { @@ -892,8 +905,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); + } } } } @@ -1926,6 +1941,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook LinearLayout findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout); EditText findOnPageEditText = findViewById(R.id.find_on_page_edittext); + // Set the minimum height of the find on page linear layout to match the toolbar. + findOnPageLinearLayout.setMinimumHeight(toolbar.getHeight()); + // Hide the toolbar. toolbar.setVisibility(View.GONE); @@ -3277,11 +3295,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; @@ -3296,6 +3317,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. @@ -3310,7 +3349,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); } } @@ -4221,23 +4260,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(); + + // Hide the soft keyboard. + inputMethodManager.hideSoftInputFromWindow(currentWebView.getWindowToken(), 0); - // Display the current URL in the URL text box. - urlEditText.setText(currentWebView.getUrl()); + // 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()) { @@ -4323,13 +4376,25 @@ 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. + closeFindOnPage(null); + // Hide the tab linear layout. tabsLinearLayout.setVisibility(View.GONE); // 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. @@ -4355,6 +4420,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. @@ -4457,15 +4528,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() { @@ -4473,7 +4543,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. @@ -4495,6 +4565,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. @@ -4508,13 +4583,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); } @@ -5087,9 +5155,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(); @@ -5099,6 +5189,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. @@ -5242,8 +5334,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);