Migrate to AndroidX from the Android Support Library. https://redmine.stoutner.com...
authorSoren Stoutner <soren@stoutner.com>
Wed, 20 Feb 2019 03:04:01 +0000 (20:04 -0700)
committerSoren Stoutner <soren@stoutner.com>
Wed, 20 Feb 2019 03:04:01 +0000 (20:04 -0700)
99 files changed:
app/build.gradle
app/src/free/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java
app/src/free/java/com/stoutner/privacybrowser/helpers/AdHelper.java
app/src/free/res/layout/main_webview.xml
app/src/main/AndroidManifest.xml
app/src/main/assets/de/about_licenses_dark.html
app/src/main/assets/de/about_licenses_light.html
app/src/main/assets/en/about_licenses_dark.html
app/src/main/assets/en/about_licenses_light.html
app/src/main/assets/es/about_licenses_dark.html
app/src/main/assets/es/about_licenses_light.html
app/src/main/assets/it/about_licenses_dark.html
app/src/main/assets/it/about_licenses_light.html
app/src/main/assets/ru/about_licenses_dark.html
app/src/main/assets/ru/about_licenses_light.html
app/src/main/assets/tr/about_licenses_dark.html
app/src/main/assets/tr/about_licenses_light.html
app/src/main/java/com/stoutner/privacybrowser/activities/AboutActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/DomainsActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/GuideActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/LogcatActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/RequestsActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/SettingsActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/ViewSourceActivity.java
app/src/main/java/com/stoutner/privacybrowser/adapters/HistoryArrayAdapter.java
app/src/main/java/com/stoutner/privacybrowser/adapters/RequestsArrayAdapter.java
app/src/main/java/com/stoutner/privacybrowser/definitions/WrapVerticalContentViewPager.java [deleted file]
app/src/main/java/com/stoutner/privacybrowser/dialogs/AddDomainDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateHomeScreenShortcutDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadFileDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadImageDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/DownloadLocationPermissionDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/HttpAuthenticationDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/MoveToFolderDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/PinnedMismatchDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/SslCertificateErrorDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/StoragePermissionDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewRequestDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/ViewSslCertificateDialog.java
app/src/main/java/com/stoutner/privacybrowser/fragments/AboutTabFragment.java
app/src/main/java/com/stoutner/privacybrowser/fragments/DomainSettingsFragment.java
app/src/main/java/com/stoutner/privacybrowser/fragments/DomainsListFragment.java
app/src/main/java/com/stoutner/privacybrowser/fragments/GuideTabFragment.java
app/src/main/java/com/stoutner/privacybrowser/helpers/OrbotProxyHelper.java
app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java
app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java [new file with mode: 0644]
app/src/main/java/com/stoutner/privacybrowser/views/WrapVerticalContentViewPager.java [new file with mode: 0644]
app/src/main/res/layout-w900dp/bookmarks_drawer.xml
app/src/main/res/layout-w900dp/domains_list_fragment.xml
app/src/main/res/layout/about_coordinatorlayout.xml
app/src/main/res/layout/add_domain_dialog.xml
app/src/main/res/layout/bookmarks_coordinatorlayout.xml
app/src/main/res/layout/bookmarks_databaseview_coordinatorlayout.xml
app/src/main/res/layout/bookmarks_databaseview_item_linearlayout.xml
app/src/main/res/layout/bookmarks_drawer.xml
app/src/main/res/layout/create_bookmark_dialog.xml
app/src/main/res/layout/create_bookmark_folder_dialog.xml
app/src/main/res/layout/create_home_screen_shortcut_dialog.xml
app/src/main/res/layout/domain_settings_fragment.xml
app/src/main/res/layout/domains_coordinatorlayout.xml
app/src/main/res/layout/download_file_dialog.xml
app/src/main/res/layout/download_image_dialog.xml
app/src/main/res/layout/edit_bookmark_databaseview_dialog.xml
app/src/main/res/layout/edit_bookmark_dialog.xml
app/src/main/res/layout/edit_bookmark_folder_databaseview_dialog.xml
app/src/main/res/layout/edit_bookmark_folder_dialog.xml
app/src/main/res/layout/find_on_page_app_bar.xml
app/src/main/res/layout/guide_coordinatorlayout.xml
app/src/main/res/layout/http_authentication_dialog.xml
app/src/main/res/layout/import_export_coordinatorlayout.xml
app/src/main/res/layout/logcat_coordinatorlayout.xml
app/src/main/res/layout/main_drawerlayout.xml
app/src/main/res/layout/main_webview.xml
app/src/main/res/layout/pinned_mismatch_linearlayout.xml
app/src/main/res/layout/requests_coordinatorlayout.xml
app/src/main/res/layout/save_logcat_dialog.xml
app/src/main/res/layout/view_source_app_bar.xml
app/src/main/res/layout/view_source_coordinatorlayout.xml
app/src/main/res/values-de/strings.xml
app/src/main/res/values-es/strings.xml
app/src/main/res/values-it/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-tr/strings.xml
app/src/main/res/values/strings.xml
app/src/standard/java/com/stoutner/privacybrowser/dialogs/AdConsentDialog.java
app/src/standard/java/com/stoutner/privacybrowser/helpers/AdHelper.java
gradle.properties

index 5c0e7da..714cd71 100644 (file)
@@ -71,7 +71,19 @@ android {
 
 dependencies {
     implementation fileTree(include: ['*.jar'], dir: 'libs')
-    implementation 'com.android.support:design:28.0.0'
+
+    // Include the following AndroidX libraries.
+    implementation 'androidx.arch.core:core-common:2.0.0'
+    implementation 'androidx.arch.core:core-runtime:2.0.0'
+    implementation 'androidx.appcompat:appcompat:1.0.2'
+    implementation 'androidx.cardview:cardview:1.0.0'
+    implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0'
+    implementation 'androidx.drawerlayout:drawerlayout:1.0.0'
+    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
+    implementation 'androidx.viewpager:viewpager:1.0.0'
+
+    // Include the Google material library.
+    implementation 'com.google.android.material:material:1.0.0'
 
     // Only compile Firebase ads for the free flavor.
     freeImplementation 'com.google.firebase:firebase-ads:17.1.3'
index 94f8a91..c0cf972 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -21,17 +21,20 @@ package com.stoutner.privacybrowser.dialogs;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.content.DialogInterface;
 import android.os.Build;
 import android.os.Bundle;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.AdConsentDatabaseHelper;
 import com.stoutner.privacybrowser.helpers.AdHelper;
 
 public class AdConsentDialog extends DialogFragment {
+    @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         // Use a builder to create the alert dialog.
@@ -46,8 +49,11 @@ public class AdConsentDialog extends DialogFragment {
             dialogBuilder.setIcon(R.drawable.block_ads_enabled_light);
         }
 
+        // Remove the incorrect lint warning below that `getApplicationContext()` might be null.
+        assert getActivity() != null;
+
         // Initialize the bookmarks database helper.  The `0` specifies a database version, but that is ignored and set instead using a constant in `AdConsentDatabaseHelper`.
-        // `getContext()` can be used instead of `getActivity.getApplicationContext()` on the minimum API >= 23.
+        // `getContext()` can be used instead of `getActivity.getApplicationContext()` when the minimum API >= 23.
         AdConsentDatabaseHelper adConsentDatabaseHelper = new AdConsentDatabaseHelper(getActivity().getApplicationContext(), null, null, 0);
 
         // Set the title.
@@ -88,8 +94,11 @@ public class AdConsentDialog extends DialogFragment {
     // Close Privacy Browser Free if the dialog is cancelled without selecting a button (by tapping on the background).
     @Override
     public void onCancel(DialogInterface dialogInterface) {
+        // Remove the incorrect lint warning below that `getApplicationContext()` might be null.
+        assert getActivity() != null;
+
         // Initialize the bookmarks database helper.  The `0` specifies a database version, but that is ignored and set instead using a constant in `AdConsentDatabaseHelper`.
-        // `getContext()` can be used instead of `getActivity.getApplicationContext()` on the minimum API >= 23.
+        // `getContext()` can be used instead of `getActivity.getApplicationContext()` when the minimum API >= 23.
         AdConsentDatabaseHelper adConsentDatabaseHelper = new AdConsentDatabaseHelper(getActivity().getApplicationContext(), null, null, 0);
 
         // Update the ad consent database.
index 7de4e52..c3aae5d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
 
 package com.stoutner.privacybrowser.helpers;
 
-import android.app.DialogFragment;
-import android.app.FragmentManager;
 import android.content.Context;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.RelativeLayout;
 
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;
+
 import com.google.ads.mediation.admob.AdMobAdapter;
 import com.google.android.gms.ads.AdRequest;
 import com.google.android.gms.ads.AdSize;
@@ -37,7 +38,7 @@ import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
 public class AdHelper {
     private static boolean initialized;
 
-    public static void initializeAds (View view, Context applicationContext, FragmentManager fragmentManager, String googleAppId, String adUnitId) {
+    public static void initializeAds(View view, Context applicationContext, FragmentManager fragmentManager, String googleAppId, String adUnitId) {
         if (!initialized) {  // This is the first run.
             // Initialize mobile ads.
             MobileAds.initialize(applicationContext, googleAppId);
@@ -66,7 +67,7 @@ public class AdHelper {
         }
     }
 
-    public static void loadAd (View view, Context applicationContext, String adUnitId) {
+    public static void loadAd(View view, Context applicationContext, String adUnitId) {
         // Cast the generic view to an AdView.
         AdView adView = (AdView) view;
 
index 48e12f0..53fd465 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -21,7 +21,6 @@
 <!-- `android:layout_weight="1"` sets the `RelativeLayout` to fill the rest of the screen because it is encapsulated in a `LinearLayout` with `android:orientation="vertical"`.-->
 <!-- `android:background=@color/gray_900` sets the background color that is displayed when a website is loading in night mode. -->
 <RelativeLayout
-    android:id="@+id/main_webview_relativelayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     xmlns:ads="http://schemas.android.com/apk/res-auto"
@@ -42,7 +41,7 @@
         ads:adUnitId="@string/ad_unit_id" >
     </com.google.android.gms.ads.AdView>
 
-    <android.support.v4.widget.SwipeRefreshLayout
+    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
         android:id="@+id/swiperefreshlayout"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -55,5 +54,5 @@
             android:layout_height="match_parent"
             android:focusable="true"
             android:focusableInTouchMode="true" />
-    </android.support.v4.widget.SwipeRefreshLayout>
+    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
 </RelativeLayout>
\ No newline at end of file
index 9e443d8..625833f 100644 (file)
@@ -67,7 +67,7 @@
 
         <!-- The file provider is required to encrypt files with OpenKeychain. -->
         <provider
-            android:name="android.support.v4.content.FileProvider"
+            android:name="androidx.core.content.FileProvider"
             android:authorities="@string/file_provider"
             android:exported="false"
             android:grantUriPermissions="true" >
index 26e7b4b..3b458ae 100644 (file)
@@ -33,7 +33,7 @@
         <p>Privacy Browser ist veröffentlicht unter der <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ Lizenz</a>. The full text of the license is below.
             The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
 
-        <h3>Block Lists</h3>
+        <h3>Blocklists</h3>
         <p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
             are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
             and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
@@ -46,8 +46,9 @@
         <p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
 
         <h3>Libraries</h3>
-        <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index 6592f4f..6df4e52 100644 (file)
@@ -32,7 +32,7 @@
         <p>Privacy Browser ist veröffentlicht unter der <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ Lizenz</a>. The full text of the license is below.
             The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
 
-        <h3>Block Lists</h3>
+        <h3>Blocklists</h3>
         <p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
             are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
             and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
@@ -45,8 +45,9 @@
         <p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
 
         <h3>Libraries</h3>
-        <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index da0defc..fb7fb8a 100644 (file)
@@ -31,7 +31,7 @@
         <p>Privacy Browser is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>. The full text of the license is below.
             The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
 
-        <h3>Block Lists</h3>
+        <h3>Blocklists</h3>
         <p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
             are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
             and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
@@ -44,8 +44,9 @@
         <p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
 
         <h3>Libraries</h3>
-        <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index 5ecac0a..2afc962 100644 (file)
@@ -31,7 +31,7 @@
         <p>Privacy Browser is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>. The full text of the license is below.
             The source code is available from <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
 
-        <h3>Block Lists</h3>
+        <h3>Blocklists</h3>
         <p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> and <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
             are <a href="https://easylist.to/pages/licence.html">dual licensed</a> under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
             and the <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a> licenses.
@@ -44,8 +44,9 @@
         <p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
 
         <h3>Libraries</h3>
-        <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index 1c36c97..f51a5b6 100644 (file)
@@ -46,8 +46,9 @@
         <p>Más información sobre las listas de bloqueo puede encontrarse en la <a href="https://easylist.to/">página web de EasyList</a>.</p>
 
         <h3>Librerías</h3>
-        <p>Navegador privado está construido con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">librería de soporte de android</a>,
-            que se libera bajo la <a href="https://www.apache.org/licenses/LICENSE-2.0">Licencia Apache 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>El sabor o versión libre de Navegador Privado está construido con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">anuncios de Firebase</a>,
             que se libera bajo la <a href="https://developer.android.com/studio/terms">Licencia del Android Software Development Kit</a>.</p>
 
index 1c8476f..65fffaf 100644 (file)
@@ -46,8 +46,9 @@
         <p>Más información sobre las listas de bloqueo puede encontrarse en la <a href="https://easylist.to/">página web de EasyList</a>.</p>
 
         <h3>Librerías</h3>
-        <p>Navegador privado está construido con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">librería de soporte de android</a>,
-            que se libera bajo la <a href="https://www.apache.org/licenses/LICENSE-2.0">Licencia Apache 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>El sabor o versión libre de Navegador Privado está construido con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">anuncios de Firebase</a>,
             que se libera bajo la <a href="https://developer.android.com/studio/terms">Licencia del Android Software Development Kit</a>.</p>
 
index 695c33d..92643e3 100644 (file)
@@ -37,7 +37,7 @@
             E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini <a href="https://www.gnu.org/licenses/translations.html">qui</a> riportati.
             Il codice sorgente è disponibile su <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
 
-        <h3>Block List</h3>
+        <h3>Blocklist</h3>
         <p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> e <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
             sono <a href="https://easylist.to/pages/licence.html">sotto doppia licenza</a> con le licenze <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
             e <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a>. Privacy Browser le incorpora utilizzando l'opzione GPLv3+.</p>
@@ -49,8 +49,9 @@
         <p>E' possibile reperire maggiori informazioni sulle block list sul <a href="https://easylist.to/">sito web EasyList</a>.</p>
 
         <h3>Librerie</h3>
-        <p>Privacy Browser è sviluppato con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            che è rilasciata con <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>La versione gratuita di Privacy Browser è compilata con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             che è rilasciato sotto la <a href="https://developer.android.com/studio/terms">Licenza Android Software Development Kit</a>.</p>
 
index f869847..23b33f4 100644 (file)
@@ -37,7 +37,7 @@
             E' inoltre ammessa la modifica e la pubblicazione di questa traduzione, ma solamente in accordo ai termini <a href="https://www.gnu.org/licenses/translations.html">qui</a> riportati.
             Il codice sorgente è disponibile su <a href="https://git.stoutner.com/?p=PrivacyBrowser.git;a=summary">git.stoutner.com</a>.</p>
 
-        <h3>Block List</h3>
+        <h3>Blocklist</h3>
         <p><a href="https://easylist.to/easylist/easylist.txt">EasyList</a> e <a href="https://easylist.to/easylist/easyprivacy.txt">EasyPrivacy</a>
             sono <a href="https://easylist.to/pages/licence.html">sotto doppia licenza</a> con le licenze <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+</a>
             e <a href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0+ Unported</a>. Privacy Browser le incorpora utilizzando l'opzione GPLv3+.</p>
@@ -49,8 +49,9 @@
         <p>E' possibile reperire maggiori informazioni sulle block list sul <a href="https://easylist.to/">sito web EasyList</a>.</p>
 
         <h3>Librerie</h3>
-        <p>Privacy Browser è sviluppato con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            che è rilasciata con <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>La versione gratuita di Privacy Browser è compilata con <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             che è rilasciato sotto la <a href="https://developer.android.com/studio/terms">Licenza Android Software Development Kit</a>.</p>
 
index fb207f6..4ff48e6 100644 (file)
@@ -44,8 +44,9 @@
         <p>Более подробную информацию о списках блокировки можно найти на <a href="https://easylist.to/">веб-сайте EasyList</a>.</p>
 
         <h3>Библиотеки</h3>
-        <p>Privacy Browser создан с использованием <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            которая выпущена под <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>Бесплатный вариант Privacy Browser создан с помощью <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             выпущенной по лицензии <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index 9770ee6..eb8a9c0 100644 (file)
@@ -44,8 +44,9 @@
         <p>Более подробную информацию о списках блокировки можно найти на <a href="https://easylist.to/">веб-сайте EasyList</a>.</p>
 
         <h3>Библиотеки</h3>
-        <p>Privacy Browser создан с использованием <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            которая выпущена под <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>Бесплатный вариант Privacy Browser создан с помощью <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             выпущенной по лицензии <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index da0defc..98308dd 100644 (file)
@@ -44,8 +44,9 @@
         <p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
 
         <h3>Libraries</h3>
-        <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index 5ecac0a..7aa77d4 100644 (file)
@@ -44,8 +44,9 @@
         <p>More information about the blocklists can be found on the <a href="https://easylist.to/">EasyList website</a>.</p>
 
         <h3>Libraries</h3>
-        <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
-            which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>Privacy Browser is built with the <a href="https://developer.android.com/jetpack/androidx/">AndroidX Libraries</a>
+            and code from the <a href="https://mvnrepository.com/artifact/com.google.android.material/material">Google Material Maven repository</a>,
+            which are released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
         <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
             which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
 
index ca71d59..d84b9c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
 package com.stoutner.privacybrowser.activities;
 
 import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
 import android.view.WindowManager;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.google.android.material.tabs.TabLayout;
+
 import com.stoutner.privacybrowser.fragments.AboutTabFragment;
 import com.stoutner.privacybrowser.R;
 
@@ -55,13 +57,17 @@ public class AboutActivity extends AppCompatActivity {
         setContentView(R.layout.about_coordinatorlayout);
 
         // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21.
-        Toolbar aboutAppBar = findViewById(R.id.about_toolbar);
-        setSupportActionBar(aboutAppBar);
+        Toolbar toolbar = findViewById(R.id.about_toolbar);
+        setSupportActionBar(toolbar);
+
+        // Get a handle for the action bar.
+        final ActionBar actionBar = getSupportActionBar();
+
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;  //
 
-        // Display the home arrow on `supportAppBar`.
-        final ActionBar appBar = getSupportActionBar();
-        assert appBar != null;  // This assert removes the incorrect warning in Android Studio on the following line that appBar might be null.
-        appBar.setDisplayHomeAsUpEnabled(true);
+        // Display the home arrow on action bar.
+        actionBar.setDisplayHomeAsUpEnabled(true);
 
         //  Setup the ViewPager.
         ViewPager aboutViewPager = findViewById(R.id.about_viewpager);
@@ -73,8 +79,9 @@ public class AboutActivity extends AppCompatActivity {
     }
 
     private class aboutPagerAdapter extends FragmentPagerAdapter {
-        private aboutPagerAdapter(FragmentManager fm) {
-            super(fm);
+        private aboutPagerAdapter(FragmentManager fragmentManager) {
+            // Run the default commands.
+            super(fragmentManager);
         }
 
         @Override
index 3858418..b93dc36 100644 (file)
@@ -19,6 +19,7 @@
 
 package com.stoutner.privacybrowser.activities;
 
+import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -29,14 +30,6 @@ import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.NavUtils;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
-import android.support.v7.widget.Toolbar;
 import android.util.SparseBooleanArray;
 import android.view.ActionMode;
 import android.view.Menu;
@@ -52,6 +45,15 @@ import android.widget.ListView;
 import android.widget.RadioButton;
 import android.widget.TextView;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API is >= 21.
+import androidx.core.app.NavUtils;
+import androidx.fragment.app.DialogFragment;
+
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.snackbar.Snackbar;
+
 import com.stoutner.privacybrowser.dialogs.CreateBookmarkDialog;
 import com.stoutner.privacybrowser.dialogs.CreateBookmarkFolderDialog;
 import com.stoutner.privacybrowser.dialogs.EditBookmarkDialog;
@@ -144,9 +146,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
         // Set the content view.
         setContentView(R.layout.bookmarks_coordinatorlayout);
 
-        // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
-        final Toolbar bookmarksAppBar = findViewById(R.id.bookmarks_toolbar);
-        setSupportActionBar(bookmarksAppBar);
+        // The AndroidX toolbar must be used until the minimum API is >= 21.
+        final Toolbar toolbar = findViewById(R.id.bookmarks_toolbar);
+        setSupportActionBar(toolbar);
 
         // Get a handle for the activity, the app bar, and the ListView.
         final Activity bookmarksActivity = this;
@@ -395,7 +397,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
                         checkedItemIds = bookmarksListView.getCheckedItemIds();
 
                         // Show the `MoveToFolderDialog` `AlertDialog` and name the instance `@string/move_to_folder
-                        AppCompatDialogFragment moveToFolderDialog = new MoveToFolderDialog();
+                        DialogFragment moveToFolderDialog = new MoveToFolderDialog();
                         moveToFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.move_to_folder));
                         break;
 
@@ -419,11 +421,11 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
                             oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
 
                             // Show the edit bookmark folder dialog.
-                            AppCompatDialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
+                            DialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
                             editFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_folder));
                         } else {
                             // Show the edit bookmark dialog.
-                            AppCompatDialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
+                            DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
                             editBookmarkDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark));
                         }
                         break;
@@ -451,6 +453,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
                                     // Do nothing because everything will be handled by `onDismissed()` below.
                                 })
                                 .addCallback(new Snackbar.Callback() {
+                                    @SuppressLint("SwitchIntDef")  // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
                                     @Override
                                     public void onDismissed(Snackbar snackbar, int event) {
                                         switch (event) {
@@ -544,14 +547,14 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
         // Set the create new bookmark folder FAB to display the `AlertDialog`.
         createBookmarkFolderFab.setOnClickListener(v -> {
             // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`.
-            AppCompatDialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
+            DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
             createBookmarkFolderDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_folder));
         });
 
         // Set the create new bookmark FAB to display the `AlertDialog`.
         createBookmarkFab.setOnClickListener(view -> {
             // Show the `CreateBookmarkDialog` `AlertDialog` and name the instance `@string/create_bookmark`.
-            AppCompatDialogFragment createBookmarkDialog = new CreateBookmarkDialog();
+            DialogFragment createBookmarkDialog = new CreateBookmarkDialog();
             createBookmarkDialog.show(getSupportFragmentManager(), getResources().getString(R.string.create_bookmark));
         });
     }
@@ -637,7 +640,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
     }
 
     @Override
-    public void onCreateBookmark(AppCompatDialogFragment dialogFragment) {
+    public void onCreateBookmark(DialogFragment dialogFragment) {
         // Get the `EditTexts` from the `dialogFragment`.
         EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext);
         EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext);
@@ -668,7 +671,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
     }
 
     @Override
-    public void onCreateBookmarkFolder(AppCompatDialogFragment dialogFragment) {
+    public void onCreateBookmarkFolder(DialogFragment dialogFragment) {
         // Get handles for the views in `dialogFragment`.
         EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext);
         RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton);
@@ -713,7 +716,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
     }
 
     @Override
-    public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+    public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
         // Get handles for the views from `dialogFragment`.
         EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
         EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext);
@@ -747,7 +750,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
     }
 
     @Override
-    public void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId) {
+    public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) {
         // Get handles for the views from `dialogFragment`.
         RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
         RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton);
@@ -814,7 +817,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
     }
 
     @Override
-    public void onMoveToFolder(AppCompatDialogFragment dialogFragment) {
+    public void onMoveToFolder(DialogFragment dialogFragment) {
         // Get a handle for the `ListView` from `dialogFragment`.
         ListView folderListView = dialogFragment.getDialog().findViewById(R.id.move_to_folder_listview);
 
index 70bd773..4bdbd44 100644 (file)
@@ -19,6 +19,7 @@
 
 package com.stoutner.privacybrowser.activities;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.database.Cursor;
 import android.database.MatrixCursor;
@@ -29,15 +30,6 @@ import android.graphics.Typeface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.design.widget.Snackbar;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.widget.CursorAdapter;
-import android.support.v4.widget.ResourceCursorAdapter;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
-import android.support.v7.widget.Toolbar;
 import android.util.SparseBooleanArray;
 import android.view.ActionMode;
 import android.view.Menu;
@@ -51,9 +43,19 @@ import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.RadioButton;
+import android.widget.ResourceCursorAdapter;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API is >= 21.
+import androidx.core.content.ContextCompat;
+import androidx.cursoradapter.widget.CursorAdapter;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
+import com.google.android.material.snackbar.Snackbar;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.EditBookmarkDatabaseViewDialog;
 import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDatabaseViewDialog;
@@ -115,19 +117,19 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
         // Set the content view.
         setContentView(R.layout.bookmarks_databaseview_coordinatorlayout);
 
-        // The `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21.
-        Toolbar bookmarksDatabaseViewAppBar = findViewById(R.id.bookmarks_databaseview_toolbar);
-        setSupportActionBar(bookmarksDatabaseViewAppBar);
+        // The AndroidX toolbar must be used until the minimum API is >= 21.
+        Toolbar toolbar = findViewById(R.id.bookmarks_databaseview_toolbar);
+        setSupportActionBar(toolbar);
 
         // Get a handle for the `AppBar`.
-        ActionBar appBar = getSupportActionBar();
+        ActionBar actionBar = getSupportActionBar();
 
-        // Remove the incorrect warning in Android Studio that `appBar` might be null.
-        assert appBar != null;
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
 
-        // Display the spinner and the back arrow in the app bar.
-        appBar.setCustomView(R.layout.spinner);
-        appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
+        // Display the spinner and the back arrow in the action bar.
+        actionBar.setCustomView(R.layout.spinner);
+        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
 
         // Initialize the database handler.  The `0` is to specify a database version, but that is set instead using a constant in `BookmarksDatabaseHelper`.
         bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0);
@@ -335,11 +337,11 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
                 oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
 
                 // Show the edit bookmark folder dialog.
-                AppCompatDialogFragment editBookmarkFolderDatabaseViewDialog = EditBookmarkFolderDatabaseViewDialog.folderDatabaseId(databaseId);
+                DialogFragment editBookmarkFolderDatabaseViewDialog = EditBookmarkFolderDatabaseViewDialog.folderDatabaseId(databaseId);
                 editBookmarkFolderDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_folder));
             } else {
                 // Show the edit bookmark dialog.
-                AppCompatDialogFragment editBookmarkDatabaseViewDialog = EditBookmarkDatabaseViewDialog.bookmarkDatabaseId(databaseId);
+                DialogFragment editBookmarkDatabaseViewDialog = EditBookmarkDatabaseViewDialog.bookmarkDatabaseId(databaseId);
                 editBookmarkDatabaseViewDialog.show(getSupportFragmentManager(), getResources().getString(R.string.edit_bookmark));
             }
         });
@@ -502,6 +504,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
                                     // Do nothing because everything will be handled by `onDismissed()` below.
                                 })
                                 .addCallback(new Snackbar.Callback() {
+                                    @SuppressLint("SwitchIntDef")  // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
                                     @Override
                                     public void onDismissed(Snackbar snackbar, int event) {
                                         switch (event) {
@@ -733,7 +736,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
     }
 
     @Override
-    public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+    public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
         // Get handles for the views from dialog fragment.
         RadioButton currentBookmarkIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_current_icon_radiobutton);
         EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
@@ -775,7 +778,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
     }
 
     @Override
-    public void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+    public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
         // Get handles for the views from dialog fragment.
         RadioButton currentBookmarkIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
         RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_default_icon_radiobutton);
index 7dbb6bf..d54499a 100644 (file)
@@ -19,6 +19,7 @@
 
 package com.stoutner.privacybrowser.activities;
 
+import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -27,15 +28,6 @@ import android.database.Cursor;
 import android.net.http.SslCertificate;
 import android.os.Bundle;
 import android.os.Handler;
-import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.NavUtils;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
-import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -49,6 +41,16 @@ import android.widget.Spinner;
 import android.widget.Switch;
 import android.widget.TextView;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API is >= 21.
+import androidx.core.app.NavUtils;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.snackbar.Snackbar;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.AddDomainDialog;
 import com.stoutner.privacybrowser.fragments.DomainSettingsFragment;
@@ -79,9 +81,6 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
     // `context` is used in `onCreate()`, `onOptionsItemSelected()`, and `onAddDomain()`.
     private Context context;
 
-    // `supportFragmentManager` is used in `onCreate()` and `onCreateOptionsMenu()`.
-    private FragmentManager supportFragmentManager;
-
     // `domainsDatabaseHelper` is used in `onCreate()`, `saveDomainSettings()`, and `onDestroy()`.
     private static DomainsDatabaseHelper domainsDatabaseHelper;
 
@@ -155,16 +154,19 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         coordinatorLayout = findViewById(R.id.domains_coordinatorlayout);
         resources = getResources();
         context = this;
-        supportFragmentManager = getSupportFragmentManager();
 
         // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21.
-        final Toolbar domainsAppBar = findViewById(R.id.domains_toolbar);
-        setSupportActionBar(domainsAppBar);
+        final Toolbar toolbar = findViewById(R.id.domains_toolbar);
+        setSupportActionBar(toolbar);
+
+        // Get a handle for the action bar.
+        ActionBar actionBar = getSupportActionBar();
 
-        // Display the home arrow on the support action bar.
-        ActionBar appBar = getSupportActionBar();
-        assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that `appBar` might be null.
-        appBar.setDisplayHomeAsUpEnabled(true);
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
+
+        // Set the back arrow on the action bar.
+        actionBar.setDisplayHomeAsUpEnabled(true);
 
         // Initialize the database handler.  The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
         domainsDatabaseHelper = new DomainsDatabaseHelper(context, null, null, 0);
@@ -176,8 +178,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         addDomainFAB = findViewById(R.id.add_domain_fab);
         addDomainFAB.setOnClickListener((View view) -> {
             // Show the add domain `AlertDialog`.
-            AppCompatDialogFragment addDomainDialog = new AddDomainDialog();
-            addDomainDialog.show(supportFragmentManager, resources.getString(R.string.add_domain));
+            DialogFragment addDomainDialog = new AddDomainDialog();
+            addDomainDialog.show(getSupportFragmentManager(), resources.getString(R.string.add_domain));
         });
     }
 
@@ -192,6 +194,9 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
         // Only display `deleteMenuItem` (initially) in two-paned mode.
         deleteMenuItem.setVisible(twoPanedMode);
 
+        // Get a handle for the fragment manager.
+        FragmentManager fragmentManager = getSupportFragmentManager();
+
         // Display the fragments.  This must be done from `onCreateOptionsMenu()` instead of `onCreate()` because `populateDomainsListView()` needs `deleteMenuItem` to be inflated.
         if (restartAfterRotate && domainSettingsDisplayedBeforeRotate) {  // The device was rotated and domain settings were displayed previously.
             if (twoPanedMode) {  // The device is in two-paned mode.
@@ -200,8 +205,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
 
                 // Display `DomainsListFragment`.
                 DomainsListFragment domainsListFragment = new DomainsListFragment();
-                supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
-                supportFragmentManager.executePendingTransactions();
+                fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+                fragmentManager.executePendingTransactions();
 
                 // Populate the list of domains.  `domainSettingsDatabaseId` highlights the domain that was highlighted before the rotation.
                 populateDomainsListView(domainSettingsDatabaseIdBeforeRotate);
@@ -227,7 +232,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                 addDomainFAB.hide();
 
                 // Display `domainSettingsFragment`.
-                supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
+                fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
             }
         } else {  // The device was not rotated or, if it was, domain settings were not displayed previously.
             if (goDirectlyToDatabaseId >=0) {  // Load the indicated domain settings.
@@ -237,8 +242,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                 if (twoPanedMode) {  // The device is in two-paned mode.
                     // Display `DomainsListFragment`.
                     DomainsListFragment domainsListFragment = new DomainsListFragment();
-                    supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
-                    supportFragmentManager.executePendingTransactions();
+                    fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+                    fragmentManager.executePendingTransactions();
 
                     // Populate the list of domains.  `domainSettingsDatabaseId` highlights the domain that was highlighted before the rotation.
                     populateDomainsListView(goDirectlyToDatabaseId);
@@ -258,13 +263,13 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                     addDomainFAB.hide();
 
                     // Display `domainSettingsFragment`.
-                    supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
+                    fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
                 }
             } else {  // Highlight the first domain.
                 // Display `DomainsListFragment`.
                 DomainsListFragment domainsListFragment = new DomainsListFragment();
-                supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
-                supportFragmentManager.executePendingTransactions();
+                fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+                fragmentManager.executePendingTransactions();
 
                 // Populate the list of domains.  `-1` highlights the first domain.
                 populateDomainsListView(-1);
@@ -277,9 +282,12 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
 
     @Override
     public boolean onOptionsItemSelected(MenuItem menuItem) {
-        // Get the ID of the `MenuItem` that was selected.
+        // Get the ID of the menu item that was selected.
         int menuItemID = menuItem.getItemId();
 
+        // Get a handle for the fragment manager.
+        FragmentManager fragmentManager = getSupportFragmentManager();
+
         switch (menuItemID) {
             case android.R.id.home:  // The home arrow is identified as `android.R.id.home`, not just `R.id.home`.
                 if (twoPanedMode) {  // The device is in two-paned mode.
@@ -311,8 +319,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
 
                     // Display the domains list fragment.
                     DomainsListFragment domainsListFragment = new DomainsListFragment();
-                    supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
-                    supportFragmentManager.executePendingTransactions();
+                    fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+                    fragmentManager.executePendingTransactions();
 
                     // Populate the list of domains.  `-1` highlights the first domain if in two-paned mode.  It has no effect in single-paned mode.
                     populateDomainsListView(-1);
@@ -354,12 +362,12 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                     deleteMenuItem.setIcon(R.drawable.delete_blue);
 
                     // Remove the domain settings fragment.
-                    supportFragmentManager.beginTransaction().remove(Objects.requireNonNull(supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container))).commit();
+                    fragmentManager.beginTransaction().remove(Objects.requireNonNull(fragmentManager.findFragmentById(R.id.domain_settings_fragment_container))).commit();
                 } else {  // Single-paned mode.
                     // Display `DomainsListFragment`.
                     DomainsListFragment domainsListFragment = new DomainsListFragment();
-                    supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
-                    supportFragmentManager.executePendingTransactions();
+                    fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+                    fragmentManager.executePendingTransactions();
 
                     // Show the add domain FAB.
                     addDomainFAB.show();
@@ -403,6 +411,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                             // Do nothing because everything will be handled by `onDismissed()` below.
                         })
                         .addCallback(new Snackbar.Callback() {
+                            @SuppressLint("SwitchIntDef")  // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
                             @Override
                             public void onDismissed(Snackbar snackbar, int event) {
                                 switch (event) {
@@ -444,14 +453,14 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                                             domainsListView.setItemChecked(deletedDomainPosition, true);
 
                                             // Display `domainSettingsFragment`.
-                                            supportFragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit();
+                                            fragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit();
 
                                             // Enable the options `MenuItems`.
                                             deleteMenuItem.setEnabled(true);
                                             deleteMenuItem.setIcon(R.drawable.delete_light);
                                         } else {  // The device in in one-paned mode.
                                             // Display `domainSettingsFragment`.
-                                            supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
+                                            fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
 
                                             // Hide the add domain FAB.
                                             addDomainFAB.hide();
@@ -460,7 +469,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
                                             deleteMenuItem.setVisible(true);
 
                                             // Display `domainSettingsFragment`.
-                                            supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
+                                            fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
                                         }
                                         break;
 
@@ -539,6 +548,9 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
     // Control what the navigation bar back button does.
     @Override
     public void onBackPressed() {
+        // Get a handle for the fragment manager.
+        FragmentManager fragmentManager = getSupportFragmentManager();
+
         if (twoPanedMode) {  // The device is in two-paned mode.
             // Save the current domain settings if the domain settings fragment is displayed.
             if (findViewById(R.id.domain_settings_scrollview) != null) {
@@ -568,8 +580,8 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
 
             // Display the domains list fragment.
             DomainsListFragment domainsListFragment = new DomainsListFragment();
-            supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
-            supportFragmentManager.executePendingTransactions();
+            fragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainsListFragment).commit();
+            fragmentManager.executePendingTransactions();
 
             // Populate the list of domains.  `-1` highlights the first domain if in two-paned mode.  It has no effect in single-paned mode.
             populateDomainsListView(-1);
@@ -595,7 +607,7 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
     }
 
     @Override
-    public void onAddDomain(AppCompatDialogFragment dialogFragment) {
+    public void onAddDomain(DialogFragment dialogFragment) {
         // Dismiss the undo delete snackbar if it is currently displayed.
         if ((undoDeleteSnackbar != null) && undoDeleteSnackbar.isShown()) {
             undoDeleteSnackbar.dismiss();
@@ -618,16 +630,16 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
             // Show and enable `deleteMenuItem`.
             DomainsActivity.deleteMenuItem.setVisible(true);
 
-            // Add `currentDomainDatabaseId` to `argumentsBundle`.
+            // Add the current domain database ID to the arguments bundle.
             Bundle argumentsBundle = new Bundle();
             argumentsBundle.putInt(DomainSettingsFragment.DATABASE_ID, currentDomainDatabaseId);
 
-            // Add `argumentsBundle` to `domainSettingsFragment`.
+            // Add and arguments bundle to the domain setting fragment.
             DomainSettingsFragment domainSettingsFragment = new DomainSettingsFragment();
             domainSettingsFragment.setArguments(argumentsBundle);
 
-            // Display `domainSettingsFragment`.
-            supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
+            // Display the domain settings fragment.
+            getSupportFragmentManager().beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
         }
     }
 
@@ -788,22 +800,22 @@ public class DomainsActivity extends AppCompatActivity implements AddDomainDialo
             // Select the highlighted domain.
             domainsListView.setItemChecked(highlightedDomainPosition, true);
 
-            // Get the `databaseId` for the highlighted domain.
+            // Get the database ID for the highlighted domain.
             domainsCursor.moveToPosition(highlightedDomainPosition);
             currentDomainDatabaseId = domainsCursor.getInt(domainsCursor.getColumnIndex(DomainsDatabaseHelper._ID));
 
-            // Store `databaseId` in `argumentsBundle`.
+            // Store the database ID in the arguments bundle.
             Bundle argumentsBundle = new Bundle();
             argumentsBundle.putInt(DomainSettingsFragment.DATABASE_ID, currentDomainDatabaseId);
 
-            // Add `argumentsBundle` to `domainSettingsFragment`.
+            // Add and arguments bundle to the domain settings fragment.
             DomainSettingsFragment domainSettingsFragment = new DomainSettingsFragment();
             domainSettingsFragment.setArguments(argumentsBundle);
 
-            // Display `domainSettingsFragment`.
-            supportFragmentManager.beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit();
+            // Display the domain settings fragment.
+            getSupportFragmentManager().beginTransaction().replace(R.id.domain_settings_fragment_container, domainSettingsFragment).commit();
 
-            // Enable the options `MenuItems`.
+            // Enable the delete options menu items.
             deleteMenuItem.setEnabled(true);
 
             // Set the delete icon according to the theme.
index 5cbf0c5..0f73f06 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
 package com.stoutner.privacybrowser.activities;
 
 import android.os.Bundle;
-import android.support.design.widget.TabLayout;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
 import android.view.WindowManager;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API is >= 21.
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.google.android.material.tabs.TabLayout;
+
 import com.stoutner.privacybrowser.fragments.GuideTabFragment;
 import com.stoutner.privacybrowser.R;
 
@@ -54,14 +56,18 @@ public class GuideActivity extends AppCompatActivity {
         // Set the content view.
         setContentView(R.layout.guide_coordinatorlayout);
 
-        // We need to use `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
-        Toolbar guideAppBar = findViewById(R.id.guide_toolbar);
-        setSupportActionBar(guideAppBar);
+        // The AndroidX toolbar must be used until the minimum API is >= 21.
+        Toolbar toolbar = findViewById(R.id.guide_toolbar);
+        setSupportActionBar(toolbar);
+
+        // Get a handle for the action bar.
+        final ActionBar actionBar = getSupportActionBar();
+
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
 
-        // Display the home arrow on `ppBar`.
-        final ActionBar appBar = getSupportActionBar();
-        assert appBar != null;  // This assert removes the incorrect lint warning in Android Studio on the following line that `appBar` might be `null`.
-        appBar.setDisplayHomeAsUpEnabled(true);
+        // Display the home arrow on the action bar.
+        actionBar.setDisplayHomeAsUpEnabled(true);
 
         //  Setup the ViewPager.
         ViewPager aboutViewPager = findViewById(R.id.guide_viewpager);
@@ -75,8 +81,9 @@ public class GuideActivity extends AppCompatActivity {
     }
 
     private class guidePagerAdapter extends FragmentPagerAdapter {
-        private guidePagerAdapter(FragmentManager fm) {
-            super(fm);
+        private guidePagerAdapter(FragmentManager fragmentManager) {
+            // Run the default commands.
+            super(fragmentManager);
         }
 
         @Override
index 80a3a98..3f7d296 100644 (file)
@@ -29,17 +29,6 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.provider.DocumentsContract;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.design.widget.TextInputLayout;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.FileProvider;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.CardView;
-import android.support.v7.widget.Toolbar;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.View;
@@ -53,6 +42,19 @@ import android.widget.RadioButton;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.cardview.widget.CardView;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.core.content.FileProvider;
+import androidx.fragment.app.DialogFragment;
+
+import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputLayout;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog;
 import com.stoutner.privacybrowser.helpers.ImportExportDatabaseHelper;
@@ -105,13 +107,17 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
         setContentView(R.layout.import_export_coordinatorlayout);
 
         // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
-        Toolbar importExportAppBar = findViewById(R.id.import_export_toolbar);
-        setSupportActionBar(importExportAppBar);
+        Toolbar toolbar = findViewById(R.id.import_export_toolbar);
+        setSupportActionBar(toolbar);
+
+        // Get a handle for the action bar.
+        ActionBar actionBar = getSupportActionBar();
+
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
 
         // Display the home arrow on the support action bar.
-        ActionBar appBar = getSupportActionBar();
-        assert appBar != null;// This assert removes the incorrect warning in Android Studio on the following line that `appBar` might be null.
-        appBar.setDisplayHomeAsUpEnabled(true);
+        actionBar.setDisplayHomeAsUpEnabled(true);
 
         // Find out if we are running KitKat
         boolean runningKitKat = (Build.VERSION.SDK_INT == 19);
@@ -162,11 +168,11 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
         // Set the default file paths according to the storage permission status.
         if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {  // The storage permission has been granted.
             // Set the default file paths to use the external public directory.
-            defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.privacy_browser_settings_pbs);
+            defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.settings_pbs);
             defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
         } else {  // The storage permission has not been granted.
             // Set the default file paths to use the external private directory.
-            defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.privacy_browser_settings_pbs);
+            defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.settings_pbs);
             defaultPasswordEncryptionFilePath = defaultFilePath + ".aes";
         }
 
@@ -438,7 +444,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
             exportBrowseIntent.setType("*/*");
 
             // Set the initial export file name.
-            exportBrowseIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.privacy_browser_settings_pbs));
+            exportBrowseIntent.putExtra(Intent.EXTRA_TITLE, getString(R.string.settings_pbs));
 
             // Set the initial directory if the minimum API >= 26.
             if (Build.VERSION.SDK_INT >= 26) {
@@ -599,7 +605,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
 
             case OPENPGP_EXPORT_RESULT_CODE:
                 // Get the temporary unencrypted export file.
-                File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs));
+                File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs));
 
                 // Delete the temporary unencrypted export file if it exists.
                 if (temporaryUnencryptedExportFile.exists()) {
@@ -623,7 +629,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
 
         // Get the export and temporary unencrypted export files.
         File exportFile = new File(exportFileString);
-        File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs));
+        File temporaryUnencryptedExportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs));
 
         // Create an export status string.
         String exportStatus;
@@ -802,7 +808,7 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe
 
             case PASSWORD_ENCRYPTION:
                 // Use a private temporary import location.
-                File temporaryUnencryptedImportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.privacy_browser_settings_pbs));
+                File temporaryUnencryptedImportFile = new File(getApplicationContext().getCacheDir() + "/" + getString(R.string.settings_pbs));
 
                 try {
                     // Create an encrypted import file input stream.
index 32d1bf4..a615a54 100644 (file)
@@ -31,22 +31,22 @@ import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.app.AppCompatDialogFragment;
-import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.WindowManager;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API is >= 21.
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import com.google.android.material.snackbar.Snackbar;
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog;
 import com.stoutner.privacybrowser.dialogs.SaveLogcatDialog;
@@ -86,18 +86,18 @@ public class LogcatActivity extends AppCompatActivity implements SaveLogcatDialo
         // Set the content view.
         setContentView(R.layout.logcat_coordinatorlayout);
 
-        // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
-        Toolbar logcatAppBar = findViewById(R.id.logcat_toolbar);
-        setSupportActionBar(logcatAppBar);
+        // The AndroidX toolbar must be used until the minimum API is >= 21.
+        Toolbar toolbar = findViewById(R.id.logcat_toolbar);
+        setSupportActionBar(toolbar);
 
-        // Get a handle for the app bar.
-        ActionBar appBar = getSupportActionBar();
+        // Get a handle for the action bar.
+        ActionBar actionBar = getSupportActionBar();
 
-        // Remove the incorrect lint warning that `appBar` might be null.
-        assert appBar != null;
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
 
-        // Display the the back arrow in the app bar.
-        appBar.setDisplayHomeAsUpEnabled(true);
+        // Display the the back arrow in the action bar.
+        actionBar.setDisplayHomeAsUpEnabled(true);
 
         // Implement swipe to refresh.
         SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.logcat_swiperefreshlayout);
@@ -190,7 +190,7 @@ public class LogcatActivity extends AppCompatActivity implements SaveLogcatDialo
     }
 
     @Override
-    public void onSaveLogcat(AppCompatDialogFragment dialogFragment) {
+    public void onSaveLogcat(DialogFragment dialogFragment) {
         // Get a handle for the file name edit text.
         EditText fileNameEditText = dialogFragment.getDialog().findViewById(R.id.file_name_edittext);
 
index 868b6d7..bbdf853 100644 (file)
@@ -24,7 +24,6 @@ package com.stoutner.privacybrowser.activities;
 import android.Manifest;
 import android.annotation.SuppressLint;
 import android.app.Activity;
-import android.app.DialogFragment;
 import android.app.DownloadManager;
 import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
@@ -55,26 +54,6 @@ import android.os.Handler;
 import android.preference.PreferenceManager;
 import android.print.PrintDocumentAdapter;
 import android.print.PrintManager;
-import android.support.annotation.NonNull;
-import android.support.design.widget.CoordinatorLayout;
-import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.NavigationView;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.content.ContextCompat;
-// `ShortcutInfoCompat`, `ShortcutManagerCompat`, and `IconCompat` can be switched to the non-compat version once API >= 26.
-import android.support.v4.content.pm.ShortcutInfoCompat;
-import android.support.v4.content.pm.ShortcutManagerCompat;
-import android.support.v4.graphics.drawable.IconCompat;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarDrawerToggle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.app.AppCompatDialogFragment;
-import android.support.v7.widget.Toolbar;
 import android.text.Editable;
 import android.text.Spanned;
 import android.text.TextWatcher;
@@ -114,6 +93,28 @@ import android.widget.RadioButton;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+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;
+// `ShortcutInfoCompat`, `ShortcutManagerCompat`, and `IconCompat` can be switched to the non-compat versions once API >= 26.
+import androidx.core.content.pm.ShortcutInfoCompat;
+import androidx.core.content.pm.ShortcutManagerCompat;
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.core.view.GravityCompat;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.android.material.navigation.NavigationView;
+import com.google.android.material.snackbar.Snackbar;
+
 import com.stoutner.privacybrowser.BuildConfig;
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.AdConsentDialog;
@@ -308,23 +309,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     // `ignorePinnedDomainInformation` is used in `onSslMismatchProceed()`, `applyDomainSettings()`, and `checkPinnedMismatch()`.
     private static boolean ignorePinnedDomainInformation;
 
-    // `supportFragmentManager` is used in `onCreate()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onCreateContextMenu()`, `onRequestPermissionResult()`, `viewSslCertificate()`,
-    // `applyAppSettings()`, and `checkPinnedMismatch()`.
-    private static FragmentManager supportFragmentManager;
-
+    // The fragment manager is initialized in `onCreate()` and accessed from the static `checkPinnedMismatch()`.
+    private static FragmentManager fragmentManager;
 
-    // `appBar` is used in `onCreate()`, `onOptionsItemSelected()`, `closeFindOnPage()`, `applyAppSettings()`, and `applyProxyThroughOrbot()`.
-    private ActionBar appBar;
 
     // `navigatingHistory` is used in `onCreate()`, `onNavigationItemSelected()`, `onSslMismatchBack()`, and `applyDomainSettings()`.
     private boolean navigatingHistory;
 
-    // `drawerLayout` is used in `onCreate()`, `onNewIntent()`, `onBackPressed()`, and `onRestart()`.
-    private DrawerLayout drawerLayout;
-
-    // `rootCoordinatorLayout` is used in `onCreate()` and `applyAppSettings()`.
-    private CoordinatorLayout rootCoordinatorLayout;
-
     // `mainWebView` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, `onNavigationItemSelected()`, `onRestart()`, `onCreateContextMenu()`, `findPreviousOnPage()`,
     // `findNextOnPage()`, `closeFindOnPage()`, `loadUrlFromTextBox()`, `onSslMismatchBack()`, and `applyProxyThroughOrbot()`.
     private WebView mainWebView;
@@ -332,9 +323,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     // `fullScreenVideoFrameLayout` is used in `onCreate()` and `onConfigurationChanged()`.
     private FrameLayout fullScreenVideoFrameLayout;
 
-    // `swipeRefreshLayout` is used in `onCreate()`, `onPrepareOptionsMenu()`, `onOptionsItemSelected()`, and `onRestart()`.
-    private SwipeRefreshLayout swipeRefreshLayout;
-
     // `urlAppBarRelativeLayout` is used in `onCreate()` and `applyDomainSettings()`.
     private RelativeLayout urlAppBarRelativeLayout;
 
@@ -462,11 +450,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     // `displayAdditionalAppBarIcons` is used in `onCreate()` and `onCreateOptionsMenu()`.
     private boolean displayAdditionalAppBarIcons;
 
-    // `drawerToggle` is used in `onCreate()`, `onPostCreate()`, `onConfigurationChanged()`, `onNewIntent()`, and `onNavigationItemSelected()`.
-    private ActionBarDrawerToggle drawerToggle;
-
-    // `supportAppBar` is used in `onCreate()`, `onOptionsItemSelected()`, and `closeFindOnPage()`.
-    private Toolbar supportAppBar;
+    // The action bar drawer toggle is initialized in `onCreate()` and used in `onPostCreate()`.
+    private ActionBarDrawerToggle actionBarDrawerToggle;
 
     // `urlTextBox` is used in `onCreate()`, `onOptionsItemSelected()`, `loadUrlFromTextBox()`, `loadUrl()`, and `highlightUrlText()`.
     private EditText urlTextBox;
@@ -490,9 +475,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     // `inputMethodManager` is used in `onOptionsItemSelected()`, `loadUrlFromTextBox()`, and `closeFindOnPage()`.
     private InputMethodManager inputMethodManager;
 
-    // `mainWebViewRelativeLayout` is used in `onCreate()` and `onNavigationItemSelected()`.
-    private RelativeLayout mainWebViewRelativeLayout;
-
     // `bookmarksDatabaseHelper` is used in `onCreate()`, `onDestroy`, `onOptionsItemSelected()`, `onCreateBookmark()`, `onCreateBookmarkFolder()`, `onSaveEditBookmark()`, `onSaveEditBookmarkFolder()`,
     // and `loadBookmarksFolder()`.
     private BookmarksDatabaseHelper bookmarksDatabaseHelper;
@@ -563,24 +545,22 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Set the content view.
         setContentView(R.layout.main_drawerlayout);
 
-        // Get a handle for the resources and the support fragment manager.
+        // Get handles for views, resources, and managers.
         Resources resources = getResources();
-        supportFragmentManager = getSupportFragmentManager();
-
-        // Get a handle for `inputMethodManager`.
+        fragmentManager = getSupportFragmentManager();
         inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+        Toolbar toolbar = findViewById(R.id.toolbar);
 
-        // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21.
-        supportAppBar = findViewById(R.id.app_bar);
-        setSupportActionBar(supportAppBar);
-        appBar = getSupportActionBar();
+        // Set the action bar.  `SupportActionBar` must be used until the minimum API is >= 21.
+        setSupportActionBar(toolbar);
+        ActionBar actionBar = getSupportActionBar();
 
-        // This is needed to get rid of the Android Studio warning that `appBar` might be null.
-        assert appBar != null;
+        // This is needed to get rid of the Android Studio warning that the action bar might be null.
+        assert actionBar != null;
 
         // Add the custom `url_app_bar` layout, which shows the favorite icon and the URL text bar.
-        appBar.setCustomView(R.layout.url_app_bar);
-        appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+        actionBar.setCustomView(R.layout.url_app_bar);
+        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
 
         // Initialize the foreground color spans for highlighting the URLs.  We have to use the deprecated `getColor()` until API >= 23.
         redColorSpan = new ForegroundColorSpan(resources.getColor(R.color.red_a700));
@@ -650,15 +630,15 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Register `orbotStatusBroadcastReceiver` on `this` context.
         this.registerReceiver(orbotStatusBroadcastReceiver, new IntentFilter("org.torproject.android.intent.action.STATUS"));
 
-        // Get handles for views that need to be accessed.
-        drawerLayout = findViewById(R.id.drawerlayout);
-        rootCoordinatorLayout = findViewById(R.id.root_coordinatorlayout);
+        // Get handles for views that need to be modified.
+        DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+        CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorlayout);
         bookmarksListView = findViewById(R.id.bookmarks_drawer_listview);
         bookmarksTitleTextView = findViewById(R.id.bookmarks_title_textview);
         FloatingActionButton launchBookmarksActivityFab = findViewById(R.id.launch_bookmarks_activity_fab);
         FloatingActionButton createBookmarkFolderFab = findViewById(R.id.create_bookmark_folder_fab);
         FloatingActionButton createBookmarkFab = findViewById(R.id.create_bookmark_fab);
-        mainWebViewRelativeLayout = findViewById(R.id.main_webview_relativelayout);
+        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
         mainWebView = findViewById(R.id.main_webview);
         findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
         findOnPageEditText = findViewById(R.id.find_on_page_edittext);
@@ -693,16 +673,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Set the create new bookmark folder FAB to display an alert dialog.
         createBookmarkFolderFab.setOnClickListener(v -> {
-            // Show the `CreateBookmarkFolderDialog` `AlertDialog` and name the instance `@string/create_folder`.
-            AppCompatDialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
-            createBookmarkFolderDialog.show(supportFragmentManager, resources.getString(R.string.create_folder));
+            // Show the create bookmark folder dialog and name the instance `@string/create_folder`.
+            DialogFragment createBookmarkFolderDialog = new CreateBookmarkFolderDialog();
+            createBookmarkFolderDialog.show(fragmentManager, resources.getString(R.string.create_folder));
         });
 
         // Set the create new bookmark FAB to display an alert dialog.
         createBookmarkFab.setOnClickListener(view -> {
-            // Show the `CreateBookmarkDialog` `AlertDialog` and name the instance `@string/create_bookmark`.
-            AppCompatDialogFragment createBookmarkDialog = new CreateBookmarkDialog();
-            createBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.create_bookmark));
+            // Show the create bookmark dialog and name the instance `@string/create_bookmark`.
+            DialogFragment createBookmarkDialog = new CreateBookmarkDialog();
+            createBookmarkDialog.show(fragmentManager, resources.getString(R.string.create_bookmark));
         });
 
         // Create a double-tap listener to toggle full-screen mode.
@@ -715,8 +695,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     inFullScreenBrowsingMode = !inFullScreenBrowsingMode;
 
                     if (inFullScreenBrowsingMode) {  // Switch to full screen mode.
-                        // Hide the `appBar`.
-                        appBar.hide();
+                        // Hide the action bar.
+                        actionBar.hide();
 
                         // Hide the banner ad in the free flavor.
                         if (BuildConfig.FLAVOR.contentEquals("free")) {
@@ -736,13 +716,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                              * 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.
                              */
-                            rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                            coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
 
-                            // Set `rootCoordinatorLayout` to fill the whole screen.
-                            rootCoordinatorLayout.setFitsSystemWindows(false);
+                            // Set the coordinator layout to fill the entire screen.
+                            coordinatorLayout.setFitsSystemWindows(false);
                         } else {  // Hide everything except the status and navigation bars.
-                            // Set `rootCoordinatorLayout` to fit under the status and navigation bars.
-                            rootCoordinatorLayout.setFitsSystemWindows(false);
+                            // Set the coordinator layout to fill the entire screen.
+                            coordinatorLayout.setFitsSystemWindows(false);
 
                             // There is an Android Support Library bug that causes a scrim to print on the right side of the `Drawer Layout` when the navigation bar is displayed on the right of the screen.
                             if (translucentNavigationBarOnFullscreen) {
@@ -751,8 +731,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                             }
                         }
                     } else {  // Switch to normal viewing mode.
-                        // Show the `appBar`.
-                        appBar.show();
+                        // Show the action bar.
+                        actionBar.show();
 
                         // Show the `BannerAd` in the free flavor.
                         if (BuildConfig.FLAVOR.contentEquals("free")) {
@@ -766,11 +746,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         // Add the translucent status flag if it is unset.  This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`.
                         getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
 
-                        // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
-                        rootCoordinatorLayout.setSystemUiVisibility(0);
+                        // Remove any `SYSTEM_UI` flags from the coordinator layout.
+                        coordinatorLayout.setSystemUiVisibility(0);
 
-                        // Constrain `rootCoordinatorLayout` inside the status and navigation bars.
-                        rootCoordinatorLayout.setFitsSystemWindows(true);
+                        // Constrain the coordinator layout inside the status and navigation bars.
+                        coordinatorLayout.setFitsSystemWindows(true);
                     }
 
                     // Consume the double-tap.
@@ -782,9 +762,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         });
 
         // Pass all touch events on `mainWebView` through `gestureDetector` to check for double-taps.
-        mainWebView.setOnTouchListener((View v, MotionEvent event) -> {
+        mainWebView.setOnTouchListener((View view, MotionEvent event) -> {
             // Call `performClick()` on the view, which is required for accessibility.
-            v.performClick();
+            view.performClick();
 
             // Send the `event` to `gestureDetector`.
             return gestureDetector.onTouchEvent(event);
@@ -847,7 +827,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         });
 
         // Implement swipe to refresh.
-        swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
         swipeRefreshLayout.setOnRefreshListener(() -> mainWebView.reload());
 
         // Set the swipe to refresh color according to the theme.
@@ -921,12 +900,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 oldFolderNameString = bookmarksCursor.getString(bookmarksCursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME));
 
                 // Show the edit bookmark folder `AlertDialog` and name the instance `@string/edit_folder`.
-                AppCompatDialogFragment editFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
-                editFolderDialog.show(supportFragmentManager, resources.getString(R.string.edit_folder));
+                DialogFragment editBookmarkFolderDialog = EditBookmarkFolderDialog.folderDatabaseId(databaseId);
+                editBookmarkFolderDialog.show(fragmentManager, resources.getString(R.string.edit_folder));
             } else {
                 // Show the edit bookmark `AlertDialog` and name the instance `@string/edit_bookmark`.
-                AppCompatDialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
-                editBookmarkDialog.show(supportFragmentManager, resources.getString(R.string.edit_bookmark));
+                DialogFragment editBookmarkDialog = EditBookmarkDialog.bookmarkDatabaseId(databaseId);
+                editBookmarkDialog.show(fragmentManager, resources.getString(R.string.edit_bookmark));
             }
 
             // Consume the event.
@@ -992,8 +971,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             }
         });
 
-        // drawerToggle creates the hamburger icon at the start of the AppBar.
-        drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, supportAppBar, R.string.open_navigation_drawer, R.string.close_navigation_drawer);
+        // Create the hamburger icon at the start of the AppBar.
+        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer);
 
         // Get a handle for the progress bar.
         final ProgressBar progressBar = findViewById(R.id.progress_bar);
@@ -1092,10 +1071,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                  * 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.
                  */
-                rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+
+                // Set the coordinator layout to fill the entire screen.
+                coordinatorLayout.setFitsSystemWindows(false);
 
-                // Set `rootCoordinatorLayout` to fill the entire screen.
-                rootCoordinatorLayout.setFitsSystemWindows(false);
+                // Hide the action bar.
+                actionBar.hide();
 
                 // Disable the sliding drawers.
                 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
@@ -1134,10 +1116,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                          * 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.
                          */
-                        rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                        coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
                     } else {  // Hide everything except the status and navigation bars.
-                        // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
-                        rootCoordinatorLayout.setSystemUiVisibility(0);
+                        // Remove any `SYSTEM_UI` flags from the coordinator layout.
+                        coordinatorLayout.setSystemUiVisibility(0);
 
                         // Add the translucent status flag if it is unset.
                         getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
@@ -1151,19 +1133,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         }
                     }
                 } else {  // Switch to normal viewing mode.
-                    // Show the `appBar` if `findOnPageLinearLayout` is not visible.
+                    // Show the action bar if the find on page linear layout is not visible.
                     if (findOnPageLinearLayout.getVisibility() == View.GONE) {
-                        appBar.show();
+                        actionBar.show();
                     }
 
                     // Show the `BannerAd` in the free flavor.
                     if (BuildConfig.FLAVOR.contentEquals("free")) {
                         // Initialize the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
-                        AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
+                        AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), fragmentManager, getString(R.string.google_app_id), getString(R.string.ad_unit_id));
                     }
 
-                    // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
-                    rootCoordinatorLayout.setSystemUiVisibility(0);
+                    // Remove any `SYSTEM_UI` flags from the coordinator layout.
+                    coordinatorLayout.setSystemUiVisibility(0);
 
                     // Remove the translucent navigation bar flag if it is set.
                     getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
@@ -1171,8 +1153,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     // Add the translucent status flag if it is unset.  This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`.
                     getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
 
-                    // Constrain `rootCoordinatorLayout` inside the status and navigation bars.
-                    rootCoordinatorLayout.setFitsSystemWindows(true);
+                    // Constrain the coordinator layout inside the status and navigation bars.
+                    coordinatorLayout.setFitsSystemWindows(true);
+
+                    // Show the action bar.
+                    actionBar.show();
                 }
 
                 // Show the ad if this is the free flavor.
@@ -1224,17 +1209,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_FILE);
 
                         // Show the download location permission alert dialog.  The permission will be requested when the the dialog is closed.
-                        downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location));
+                        downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location));
                     } else {  // Show the permission request directly.
                         // Request the permission.  The download dialog will be launched by `onRequestPermissionResult()`.
                         ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_FILE_REQUEST_CODE);
                     }
                 } else {  // The storage permission has already been granted.
                     // Get a handle for the download file alert dialog.
-                    AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(url, contentDisposition, contentLength);
+                    DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(url, contentDisposition, contentLength);
 
                     // Show the download file alert dialog.
-                    downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download));
+                    downloadFileDialogFragment.show(fragmentManager, getString(R.string.download));
                 }
             }
         });
@@ -1611,8 +1596,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 httpAuthHandler = handler;
 
                 // Display the HTTP authentication dialog.
-                AppCompatDialogFragment httpAuthenticationDialogFragment = HttpAuthenticationDialog.displayDialog(host, realm);
-                httpAuthenticationDialogFragment.show(supportFragmentManager, getString(R.string.http_authentication));
+                DialogFragment httpAuthenticationDialogFragment = HttpAuthenticationDialog.displayDialog(host, realm);
+                httpAuthenticationDialogFragment.show(fragmentManager, getString(R.string.http_authentication));
             }
 
             // Update the URL in urlTextBox when the page starts to load.
@@ -1819,8 +1804,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     sslErrorHandler = handler;
 
                     // Display the SSL error `AlertDialog`.
-                    AppCompatDialogFragment sslCertificateErrorDialogFragment = SslCertificateErrorDialog.displayDialog(error);
-                    sslCertificateErrorDialogFragment.show(supportFragmentManager, getString(R.string.ssl_certificate_error));
+                    DialogFragment sslCertificateErrorDialogFragment = SslCertificateErrorDialog.displayDialog(error);
+                    sslCertificateErrorDialogFragment.show(fragmentManager, getString(R.string.ssl_certificate_error));
                 }
             }
         });
@@ -1888,6 +1873,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Load the URL.
         loadUrl(formattedUrlString);
 
+        // Get a handle for the drawer layout.
+        DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+
         // Close the navigation drawer if it is open.
         if (drawerLayout.isDrawerVisible(GravityCompat.START)) {
             drawerLayout.closeDrawer(GravityCompat.START);
@@ -1957,6 +1945,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Update the bookmarks drawer if returning from the Bookmarks activity.
         if (restartFromBookmarksActivity) {
+            // Get a handle for the drawer layout.
+            DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+
             // Close the bookmarks drawer.
             drawerLayout.closeDrawer(GravityCompat.END);
 
@@ -1999,6 +1990,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         }
 
         if (displayingFullScreenVideo) {
+            // Get handles for the layouts that need to be modified.
+            DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+            CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorlayout);
+
             // Remove the translucent overlays.
             getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
 
@@ -2009,7 +2004,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
              * 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.
              */
-            rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+            coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
         }
     }
 
@@ -2118,6 +2113,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
+        // Get a handle for the swipe refresh layout.
+        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
+
         // Get handles for the menu items.
         MenuItem addOrEditDomain = menu.findItem(R.id.add_or_edit_domain);
         MenuItem toggleFirstPartyCookiesMenuItem = menu.findItem(R.id.toggle_first_party_cookies);
@@ -2483,21 +2481,21 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                             // Do nothing because everything will be handled by `onDismissed()` below.
                         })
                         .addCallback(new Snackbar.Callback() {
+                            @SuppressLint("SwitchIntDef")  // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
                             @Override
                             public void onDismissed(Snackbar snackbar, int event) {
                                 switch (event) {
-                                    // The user pushed the `Undo` button.
+                                    // The user pushed the undo button.
                                     case Snackbar.Callback.DISMISS_EVENT_ACTION:
                                         // Do nothing.
                                         break;
 
-                                    // The `Snackbar` was dismissed without the `Undo` button being pushed.
+                                    // The snackbar was dismissed without the undo button being pushed.
                                     default:
                                         // `cookieManager.removeAllCookie()` varies by SDK.
                                         if (Build.VERSION.SDK_INT < 21) {
                                             cookieManager.removeAllCookie();
                                         } else {
-                                            // `null` indicates no callback.
                                             cookieManager.removeAllCookies(null);
                                         }
                                 }
@@ -2512,15 +2510,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                             // Do nothing because everything will be handled by `onDismissed()` below.
                         })
                         .addCallback(new Snackbar.Callback() {
+                            @SuppressLint("SwitchIntDef")  // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
                             @Override
                             public void onDismissed(Snackbar snackbar, int event) {
                                 switch (event) {
-                                    // The user pushed the `Undo` button.
+                                    // The user pushed the undo button.
                                     case Snackbar.Callback.DISMISS_EVENT_ACTION:
                                         // Do nothing.
                                         break;
 
-                                    // The `Snackbar` was dismissed without the `Undo` button being pushed.
+                                    // The snackbar was dismissed without the undo button being pushed.
                                     default:
                                         // Delete the DOM Storage.
                                         WebStorage webStorage = WebStorage.getInstance();
@@ -2567,15 +2566,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                             // Do nothing because everything will be handled by `onDismissed()` below.
                         })
                         .addCallback(new Snackbar.Callback() {
+                            @SuppressLint("SwitchIntDef")  // Ignore the lint warning about not handling the other possible events as they are covered by `default:`.
                             @Override
                             public void onDismissed(Snackbar snackbar, int event) {
                                 switch (event) {
-                                    // The user pushed the `Undo` button.
+                                    // The user pushed the undo button.
                                     case Snackbar.Callback.DISMISS_EVENT_ACTION:
                                         // Do nothing.
                                         break;
 
-                                    // The `Snackbar` was dismissed without the `Undo` button being pushed.
+                                    // The snackbar was dismissed without the `Undo` button being pushed.
                                     default:
                                         // Delete the form data.
                                         WebViewDatabase mainWebViewDatabase = WebViewDatabase.getInstance(getApplicationContext());
@@ -2793,6 +2793,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 return true;
 
             case R.id.swipe_to_refresh:
+                // Get a handle for the swipe refresh layout.
+                SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
+
                 // Toggle swipe to refresh.
                 swipeRefreshLayout.setEnabled(!swipeRefreshLayout.isEnabled());
                 return true;
@@ -2836,8 +2839,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 return true;
 
             case R.id.find_on_page:
+                // Get a handle for the toolbar.
+                Toolbar toolbar = findViewById(R.id.toolbar);
+
                 // Hide the URL app bar.
-                supportAppBar.setVisibility(View.GONE);
+                toolbar.setVisibility(View.GONE);
 
                 // Show the Find on Page `RelativeLayout`.
                 findOnPageLinearLayout.setVisibility(View.VISIBLE);
@@ -2896,8 +2902,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             case R.id.add_to_homescreen:
                 // Show the alert dialog.
-                AppCompatDialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog();
-                createHomeScreenShortcutDialogFragment.show(supportFragmentManager, getString(R.string.create_shortcut));
+                DialogFragment createHomeScreenShortcutDialogFragment = new CreateHomeScreenShortcutDialog();
+                createHomeScreenShortcutDialogFragment.show(getSupportFragmentManager(), getString(R.string.create_shortcut));
 
                 //Everything else will be handled by the alert dialog and the associated listener below.
                 return true;
@@ -2923,7 +2929,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             case R.id.ad_consent:
                 // Display the ad consent dialog.
                 DialogFragment adConsentDialogFragment = new AdConsentDialog();
-                adConsentDialogFragment.show(getFragmentManager(), getString(R.string.ad_consent));
+                adConsentDialogFragment.show(getSupportFragmentManager(), getString(R.string.ad_consent));
                 return true;
 
             default:
@@ -2973,9 +2979,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Get the `WebBackForwardList`.
                 WebBackForwardList webBackForwardList = mainWebView.copyBackForwardList();
 
-                // Show the `UrlHistoryDialog` `AlertDialog` and name this instance `R.string.history`.  `this` is the `Context`.
-                AppCompatDialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(this, webBackForwardList);
-                urlHistoryDialogFragment.show(supportFragmentManager, getString(R.string.history));
+                // Show the URL history dialog and name this instance `R.string.history`.
+                DialogFragment urlHistoryDialogFragment = UrlHistoryDialog.loadBackForwardList(this, webBackForwardList);
+                urlHistoryDialogFragment.show(getSupportFragmentManager(), getString(R.string.history));
                 break;
 
             case R.id.requests:
@@ -3156,9 +3162,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Clear `customHeaders`.
                 customHeaders.clear();
 
-                // Detach all views from `mainWebViewRelativeLayout`.
-                mainWebViewRelativeLayout.removeAllViews();
-
                 // Destroy the internal state of `mainWebView`.
                 mainWebView.destroy();
 
@@ -3188,6 +3191,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 break;
         }
 
+        // Get a handle for the drawer layout.
+        DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+
         // Close the navigation drawer.
         drawerLayout.closeDrawer(GravityCompat.START);
         return true;
@@ -3195,10 +3201,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
     @Override
     public void onPostCreate(Bundle savedInstanceState) {
+        // Run the default commands.
         super.onPostCreate(savedInstanceState);
 
         // Sync the state of the DrawerToggle after onRestoreInstanceState has finished.
-        drawerToggle.syncState();
+        actionBarDrawerToggle.syncState();
     }
 
     @Override
@@ -3237,8 +3244,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         final String imageUrl;
         final String linkUrl;
 
-        // Get a handle for the `ClipboardManager`.
+        // Get a handle for the the clipboard and fragment managers.
         final ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+        FragmentManager fragmentManager = getSupportFragmentManager();
 
         // Remove the lint errors below that `clipboardManager` might be `null`.
         assert clipboardManager != null;
@@ -3287,17 +3295,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                                 DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_FILE);
 
                                 // Show the download location permission alert dialog.  The permission will be requested when the the dialog is closed.
-                                downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location));
+                                downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location));
                             } else {  // Show the permission request directly.
                                 // Request the permission.  The download dialog will be launched by `onRequestPermissionResult()`.
                                 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_FILE_REQUEST_CODE);
                             }
                         } else {  // The storage permission has already been granted.
                             // Get a handle for the download file alert dialog.
-                            AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(linkUrl, "none", -1);
+                            DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(linkUrl, "none", -1);
 
                             // Show the download file alert dialog.
-                            downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download));
+                            downloadFileDialogFragment.show(fragmentManager, getString(R.string.download));
                         }
                     }
                     return false;
@@ -3387,17 +3395,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                                 DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE);
 
                                 // Show the download location permission alert dialog.  The permission will be requested when the dialog is closed.
-                                downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location));
+                                downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location));
                             } else {  // Show the permission request directly.
                                 // Request the permission.  The download dialog will be launched by `onRequestPermissionResult().
                                 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_IMAGE_REQUEST_CODE);
                             }
                         } else {  // The storage permission has already been granted.
                             // Get a handle for the download image alert dialog.
-                            AppCompatDialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl);
+                            DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl);
 
                             // Show the download image alert dialog.
-                            downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download));
+                            downloadImageDialogFragment.show(fragmentManager, getString(R.string.download));
                         }
                     }
                     return false;
@@ -3461,17 +3469,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                                 DialogFragment downloadLocationPermissionDialogFragment = DownloadLocationPermissionDialog.downloadType(DownloadLocationPermissionDialog.DOWNLOAD_IMAGE);
 
                                 // Show the download location permission alert dialog.  The permission will be requested when the dialog is closed.
-                                downloadLocationPermissionDialogFragment.show(getFragmentManager(), getString(R.string.download_location));
+                                downloadLocationPermissionDialogFragment.show(fragmentManager, getString(R.string.download_location));
                             } else {  // Show the permission request directly.
                                 // Request the permission.  The download dialog will be launched by `onRequestPermissionResult().
                                 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, DOWNLOAD_IMAGE_REQUEST_CODE);
                             }
                         } else {  // The storage permission has already been granted.
                             // Get a handle for the download image alert dialog.
-                            AppCompatDialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl);
+                            DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(imageUrl);
 
                             // Show the download image alert dialog.
-                            downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download));
+                            downloadImageDialogFragment.show(fragmentManager, getString(R.string.download));
                         }
                     }
                     return false;
@@ -3506,7 +3514,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onCreateBookmark(AppCompatDialogFragment dialogFragment) {
+    public void onCreateBookmark(DialogFragment dialogFragment) {
         // Get the `EditTexts` from the `dialogFragment`.
         EditText createBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext);
         EditText createBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext);
@@ -3537,7 +3545,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onCreateBookmarkFolder(AppCompatDialogFragment dialogFragment) {
+    public void onCreateBookmarkFolder(DialogFragment dialogFragment) {
         // Get handles for the views in `dialogFragment`.
         EditText createFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.create_folder_name_edittext);
         RadioButton defaultFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.create_folder_default_icon_radiobutton);
@@ -3582,7 +3590,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onCreateHomeScreenShortcut(AppCompatDialogFragment dialogFragment) {
+    public void onCreateHomeScreenShortcut(DialogFragment dialogFragment) {
         // Get the shortcut name.
         EditText shortcutNameEditText = dialogFragment.getDialog().findViewById(R.id.shortcut_name_edittext);
         String shortcutNameString = shortcutNameEditText.getText().toString();
@@ -3623,16 +3631,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        // Get a handle for the fragment manager.
+        FragmentManager fragmentManager = getSupportFragmentManager();
+
         switch (requestCode) {
             case DOWNLOAD_FILE_REQUEST_CODE:
                 // Show the download file alert dialog.  When the dialog closes, the correct command will be used based on the permission status.
-                AppCompatDialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(downloadUrl, downloadContentDisposition, downloadContentLength);
+                DialogFragment downloadFileDialogFragment = DownloadFileDialog.fromUrl(downloadUrl, downloadContentDisposition, downloadContentLength);
 
                 // On API 23, displaying the fragment must be delayed or the app will crash.
                 if (Build.VERSION.SDK_INT == 23) {
-                    new Handler().postDelayed(() -> downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download)), 500);
+                    new Handler().postDelayed(() -> downloadFileDialogFragment.show(fragmentManager, getString(R.string.download)), 500);
                 } else {
-                    downloadFileDialogFragment.show(supportFragmentManager, getString(R.string.download));
+                    downloadFileDialogFragment.show(fragmentManager, getString(R.string.download));
                 }
 
                 // Reset the download variables.
@@ -3643,13 +3654,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             case DOWNLOAD_IMAGE_REQUEST_CODE:
                 // Show the download image alert dialog.  When the dialog closes, the correct command will be used based on the permission status.
-                AppCompatDialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(downloadImageUrl);
+                DialogFragment downloadImageDialogFragment = DownloadImageDialog.imageUrl(downloadImageUrl);
 
                 // On API 23, displaying the fragment must be delayed or the app will crash.
                 if (Build.VERSION.SDK_INT == 23) {
-                    new Handler().postDelayed(() -> downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download)), 500);
+                    new Handler().postDelayed(() -> downloadImageDialogFragment.show(fragmentManager, getString(R.string.download)), 500);
                 } else {
-                    downloadImageDialogFragment.show(supportFragmentManager, getString(R.string.download));
+                    downloadImageDialogFragment.show(fragmentManager, getString(R.string.download));
                 }
 
                 // Reset the image URL variable.
@@ -3659,7 +3670,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onDownloadImage(AppCompatDialogFragment dialogFragment, String imageUrl) {
+    public void onDownloadImage(DialogFragment dialogFragment, String imageUrl) {
         // Download the image if it has an HTTP or HTTPS URI.
         if (imageUrl.startsWith("http")) {
             // Get a handle for the system `DOWNLOAD_SERVICE`.
@@ -3711,7 +3722,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onDownloadFile(AppCompatDialogFragment dialogFragment, String downloadUrl) {
+    public void onDownloadFile(DialogFragment dialogFragment, String downloadUrl) {
         // Download the file if it has an HTTP or HTTPS URI.
         if (downloadUrl.startsWith("http")) {
             // Get a handle for the system `DOWNLOAD_SERVICE`.
@@ -3763,7 +3774,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
+    public void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId) {
         // Get handles for the views from `dialogFragment`.
         EditText editBookmarkNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext);
         EditText editBookmarkUrlEditText = dialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext);
@@ -3794,7 +3805,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId) {
+    public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId) {
         // Get handles for the views from `dialogFragment`.
         EditText editFolderNameEditText = dialogFragment.getDialog().findViewById(R.id.edit_folder_name_edittext);
         RadioButton currentFolderIconRadioButton = dialogFragment.getDialog().findViewById(R.id.edit_folder_current_icon_radiobutton);
@@ -3862,7 +3873,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onHttpAuthenticationProceed(AppCompatDialogFragment dialogFragment) {
+    public void onHttpAuthenticationProceed(DialogFragment dialogFragment) {
         // Get handles for the `EditTexts`.
         EditText usernameEditText = dialogFragment.getDialog().findViewById(R.id.http_authentication_username);
         EditText passwordEditText = dialogFragment.getDialog().findViewById(R.id.http_authentication_password);
@@ -3874,7 +3885,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     public void viewSslCertificate(View view) {
         // Show the `ViewSslCertificateDialog` `AlertDialog` and name this instance `@string/view_ssl_certificate`.
         DialogFragment viewSslCertificateDialogFragment = new ViewSslCertificateDialog();
-        viewSslCertificateDialogFragment.show(getFragmentManager(), getString(R.string.view_ssl_certificate));
+        viewSslCertificateDialogFragment.show(getSupportFragmentManager(), getString(R.string.view_ssl_certificate));
     }
 
     @Override
@@ -3931,6 +3942,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     // Override `onBackPressed` to handle the navigation drawer and `mainWebView`.
     @Override
     public void onBackPressed() {
+        // Get a handle for the drawer layout.
+        DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+
         if (drawerLayout.isDrawerVisible(GravityCompat.START)) {  // The navigation drawer is open.
             // Close the navigation drawer.
             drawerLayout.closeDrawer(GravityCompat.START);
@@ -4073,8 +4087,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Hide the Find on Page `RelativeLayout`.
         findOnPageLinearLayout.setVisibility(View.GONE);
 
-        // Show the URL app bar.
-        supportAppBar.setVisibility(View.VISIBLE);
+        // Get a handle for the toolbar.
+        Toolbar toolbar = findViewById(R.id.toolbar);
+
+        // Show the toolbar.
+        toolbar.setVisibility(View.VISIBLE);
 
         // Hide the keyboard so we can see the webpage.  `0` indicates no additional flags.
         inputMethodManager.hideSoftInputFromWindow(mainWebView.getWindowToken(), 0);
@@ -4103,6 +4120,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             customHeaders.remove("DNT");
         }
 
+        // Get handles for the views that need to be modified.  `getSupportActionBar()` must be used until the minimum API >= 21.
+        DrawerLayout drawerLayout = findViewById(R.id.drawerlayout);
+        CoordinatorLayout coordinatorLayout = findViewById(R.id.coordinatorlayout);
+        ActionBar actionBar = getSupportActionBar();
+
         // Apply the appropriate full screen mode the `SYSTEM_UI` flags.
         if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) {  // Privacy Browser is currently in full screen browsing mode.
             if (hideSystemBarsOnFullscreen) {  // Hide everything.
@@ -4119,10 +4141,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                  * 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.
                  */
-                rootCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+                coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
             } else {  // Hide everything except the status and navigation bars.
-                // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
-                rootCoordinatorLayout.setSystemUiVisibility(0);
+                // Remove any `SYSTEM_UI` flags from the coordinator layout.
+                coordinatorLayout.setSystemUiVisibility(0);
 
                 // Add the translucent status flag if it is unset.
                 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
@@ -4139,19 +4161,22 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Reset the full screen tracker, which could be true if Privacy Browser was in full screen mode before entering settings and full screen browsing was disabled.
             inFullScreenBrowsingMode = false;
 
-            // Show the `appBar` if `findOnPageLinearLayout` is not visible.
+            // Remove the incorrect lint warning below that the action bar might be null.
+            assert actionBar != null;
+
+            // Show the action bar if the find on page linear layout is not visible.
             if (findOnPageLinearLayout.getVisibility() == View.GONE) {
-                appBar.show();
+                actionBar.show();
             }
 
             // Show the `BannerAd` in the free flavor.
             if (BuildConfig.FLAVOR.contentEquals("free")) {
                 // Initialize the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
-                AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
+                AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), fragmentManager, getString(R.string.google_app_id), getString(R.string.ad_unit_id));
             }
 
-            // Remove any `SYSTEM_UI` flags from `rootCoordinatorLayout`.
-            rootCoordinatorLayout.setSystemUiVisibility(0);
+            // Remove any `SYSTEM_UI` flags from the coordinator layout.
+            coordinatorLayout.setSystemUiVisibility(0);
 
             // Remove the translucent navigation bar flag if it is set.
             getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
@@ -4159,8 +4184,8 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Add the translucent status flag if it is unset.  This also resets `drawerLayout's` `View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`.
             getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
 
-            // Constrain `rootCoordinatorLayout` inside the status and navigation bars.
-            rootCoordinatorLayout.setFitsSystemWindows(true);
+            // Constrain the coordinator layout inside the status and navigation bars.
+            coordinatorLayout.setFitsSystemWindows(true);
         }
     }
 
@@ -4211,6 +4236,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 favoriteIconImageView.setImageBitmap(Bitmap.createScaledBitmap(favoriteIconBitmap, 64, 64, true));
             }
 
+            // Get a handle for the swipe refresh layout.
+            SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
+
             // Initialize the database handler.  The `0` specifies the database version, but that is ignored and set instead using a constant in `DomainsDatabaseHelper`.
             DomainsDatabaseHelper domainsDatabaseHelper = new DomainsDatabaseHelper(this, null, null, 0);
 
@@ -4556,6 +4584,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             if (mainMenu != null) {
                 updatePrivacyIcons(true);
             }
+
+            // TODO.
+            swipeRefreshLayout.setEnabled(false);
         }
 
         // Reload the website if returning from the Domains activity.
@@ -4579,6 +4610,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         String searchString = sharedPreferences.getString("search", getString(R.string.search_default_value));
         String searchCustomUrlString = sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value));
 
+        // Get a handle for the action bar.  `getSupportActionBar()` must be used until the minimum API >= 21.
+        ActionBar actionBar = getSupportActionBar();
+
+        // Remove the incorrect lint warning later that the action bar might be null.
+        assert actionBar != null;
+
         // Set the homepage, search, and proxy options.
         if (proxyThroughOrbot) {  // Set the Tor options.
             // Set `torHomepageString` as `homepage`.
@@ -4601,9 +4638,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             // Set the `appBar` background to indicate proxying through Orbot is enabled.  `this` refers to the context.
             if (darkTheme) {
-                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.dark_blue_30));
+                actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.dark_blue_30));
             } else {
-                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.blue_50));
+                actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.blue_50));
             }
 
             // Check to see if Orbot is ready.
@@ -4641,9 +4678,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             // Set the default `appBar` background.  `this` refers to the context.
             if (darkTheme) {
-                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_900));
+                actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_900));
             } else {
-                appBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_100));
+                actionBar.setBackgroundDrawable(ContextCompat.getDrawable(this, R.color.gray_100));
             }
 
             // Reset `waitingForOrbot.
@@ -4923,10 +4960,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                     !currentWebsiteSslEndDateString.equals(pinnedSslEndDateString)))) {
 
                 // Get a handle for the pinned mismatch alert dialog.
-                AppCompatDialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(pinnedSslCertificate, pinnedIpAddresses);
+                DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(pinnedSslCertificate, pinnedIpAddresses);
 
                 // Show the pinned mismatch alert dialog.
-                pinnedMismatchDialogFragment.show(supportFragmentManager, "Pinned Mismatch");
+                pinnedMismatchDialogFragment.show(fragmentManager, "Pinned Mismatch");
             }
         }
     }
index 098fd66..4c42db7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -23,10 +23,6 @@ import android.content.Context;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.app.AppCompatDialogFragment;
-import android.support.v7.widget.Toolbar;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
@@ -36,6 +32,11 @@ import android.widget.ResourceCursorAdapter;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API >= 21.
+import androidx.fragment.app.DialogFragment;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.adapters.RequestsArrayAdapter;
 import com.stoutner.privacybrowser.dialogs.ViewRequestDialog;
@@ -67,9 +68,9 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi
         // Set the content view.
         setContentView(R.layout.requests_coordinatorlayout);
 
-        // Use the `SupportActionBar` from `android.support.v7.app.ActionBar` until the minimum API is >= 21.
-        Toolbar requestsAppBar = findViewById(R.id.requests_toolbar);
-        setSupportActionBar(requestsAppBar);
+        // Use the AndroidX toolbar from until the minimum API is >= 21.
+        Toolbar toolbar = findViewById(R.id.requests_toolbar);
+        setSupportActionBar(toolbar);
 
         // Get a handle for the app bar and the list view.
         ActionBar appBar = getSupportActionBar();
@@ -244,7 +245,7 @@ public class RequestsActivity extends AppCompatActivity implements ViewRequestDi
         assert selectedRequestStringArray != null;
 
         // Show the request detail dialog.
-        AppCompatDialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray);
+        DialogFragment viewRequestDialogFragment = ViewRequestDialog.request(id, isLastRequest, selectedRequestStringArray);
         viewRequestDialogFragment.show(getSupportFragmentManager(), getString(R.string.request_details));
     }
 }
\ No newline at end of file
index cb4146d..2687ab1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
 package com.stoutner.privacybrowser.activities;
 
 import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
 import android.view.WindowManager;
 
+import androidx.appcompat.app.AppCompatActivity;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.fragments.SettingsFragment;
 
index 62c704d..052750b 100644 (file)
@@ -29,11 +29,6 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.LocaleList;
 import android.preference.PreferenceManager;
-import android.support.v4.app.NavUtils;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
@@ -49,6 +44,12 @@ import android.widget.EditText;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;  // The AndroidX toolbar must be used until the minimum API is >= 21.
+import androidx.core.app.NavUtils;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.dialogs.AboutViewSourceDialog;
 
@@ -93,19 +94,19 @@ public class ViewSourceActivity extends AppCompatActivity {
         // Set the content view.
         setContentView(R.layout.view_source_coordinatorlayout);
 
-        // `SupportActionBar` from `android.support.v7.app.ActionBar` must be used until the minimum API is >= 21.
-        Toolbar viewSourceAppBar = findViewById(R.id.view_source_toolbar);
-        setSupportActionBar(viewSourceAppBar);
+        // The AndroidX toolbar must be used until the minimum API is >= 21.
+        Toolbar toolbar = findViewById(R.id.view_source_toolbar);
+        setSupportActionBar(toolbar);
 
-        // Setup the app bar.
-        final ActionBar appBar = getSupportActionBar();
+        // Get a handle for the action bar.
+        final ActionBar actionBar = getSupportActionBar();
 
-        // Remove the incorrect warning in Android Studio that appBar might be null.
-        assert appBar != null;
+        // Remove the incorrect lint warning that the action bar might be null.
+        assert actionBar != null;
 
-        // Add the custom layout to the app bar.
-        appBar.setCustomView(R.layout.view_source_app_bar);
-        appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+        // Add the custom layout to the action bar.
+        actionBar.setCustomView(R.layout.view_source_app_bar);
+        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
 
         // Get a handle for the url text box.
         EditText urlEditText = findViewById(R.id.url_edittext);
index be6d11a..5150fb3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -21,7 +21,6 @@ package com.stoutner.privacybrowser.adapters;
 
 import android.content.Context;
 import android.graphics.Typeface;
-import android.support.annotation.NonNull;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -29,6 +28,8 @@ import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.definitions.History;
 
index 62dec5d..f6f1e8b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -20,7 +20,6 @@
 package com.stoutner.privacybrowser.adapters;
 
 import android.content.Context;
-import android.support.annotation.NonNull;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -28,6 +27,8 @@ import android.widget.ArrayAdapter;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
diff --git a/app/src/main/java/com/stoutner/privacybrowser/definitions/WrapVerticalContentViewPager.java b/app/src/main/java/com/stoutner/privacybrowser/definitions/WrapVerticalContentViewPager.java
deleted file mode 100644 (file)
index 8b1d978..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.stoutner.privacybrowser.definitions;
-
-/*
- * Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
- *
- * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
- *
- * Privacy Browser is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Privacy Browser is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-import android.content.Context;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.view.View;
-
-public class WrapVerticalContentViewPager extends ViewPager {
-    // Setup the default constructors.
-    public WrapVerticalContentViewPager(Context context) {
-        super(context);
-    }
-
-    public WrapVerticalContentViewPager(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Perform an initial `super.onMeasure`, which populates `getChildCount`.
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-        // Initialize `maximumHeight`.
-        int maximumHeight = 0;
-
-        // Find the maximum height of each of the child views.
-        for (int i = 0; i < getChildCount(); i++) {
-            View childView = getChildAt(i);
-
-            // Measure the child view height with no constraints.
-            childView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-
-            // Store the child's height if it is larger than `maximumHeight`.
-            if (childView.getMeasuredHeight() > maximumHeight) {
-                maximumHeight = childView.getMeasuredHeight();
-            }
-        }
-
-        // Perform a final `super.onMeasure` to set the `maximumHeight`.
-        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maximumHeight, MeasureSpec.EXACTLY));
-    }
-}
\ No newline at end of file
index edffc63..cfba553 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -26,9 +26,6 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.net.Uri;
 import android.os.Bundle;
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <= 22.
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
@@ -38,14 +35,18 @@ import android.widget.Button;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+// The AndroidX dialog fragment must be used or an error is produced on API <=22.
+import androidx.fragment.app.DialogFragment;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
 
-public class AddDomainDialog extends AppCompatDialogFragment {
+public class AddDomainDialog extends DialogFragment {
     // The public interface is used to send information back to the parent activity.
     public interface AddDomainListener {
-        void onAddDomain(AppCompatDialogFragment dialogFragment);
+        void onAddDomain(DialogFragment dialogFragment);
     }
 
     // `addDomainListener` is used in `onAttach()` and `onCreateDialog()`.
index d034aac..60b4cef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -27,21 +27,21 @@ import android.content.DialogInterface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <= 22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.EditText;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.R;
 
-public class CreateBookmarkDialog extends AppCompatDialogFragment {
+public class CreateBookmarkDialog extends DialogFragment {
     // The public interface is used to send information back to the parent activity.
     public interface CreateBookmarkListener {
-        void onCreateBookmark(AppCompatDialogFragment dialogFragment);
+        void onCreateBookmark(DialogFragment dialogFragment);
     }
 
     // `createBookmarkListener` is used in `onAttach()` and `onCreateDialog()`
index 83aa93f..7600db6 100644 (file)
@@ -26,9 +26,6 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.database.Cursor;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
@@ -38,14 +35,17 @@ import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
-public class CreateBookmarkFolderDialog extends AppCompatDialogFragment {
+public class CreateBookmarkFolderDialog extends DialogFragment {
     // The public interface is used to send information back to the parent activity.
     public interface CreateBookmarkFolderListener {
-        void onCreateBookmarkFolder(AppCompatDialogFragment dialogFragment);
+        void onCreateBookmarkFolder(DialogFragment dialogFragment);
     }
 
     // `createBookmarkFolderListener` is used in `onAttach()` and `onCreateDialog`.
index ca8d72b..cb9accc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2015-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2015-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -27,22 +27,22 @@ import android.content.DialogInterface;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.EditText;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.R;
 
-public class CreateHomeScreenShortcutDialog extends AppCompatDialogFragment {
+public class CreateHomeScreenShortcutDialog extends DialogFragment {
     // The public interface is used to send information back to the parent activity.
     public interface CreateHomeScreenShortcutListener {
-        void onCreateHomeScreenShortcut(AppCompatDialogFragment dialogFragment);
+        void onCreateHomeScreenShortcut(DialogFragment dialogFragment);
     }
 
     //`createHomeScreenShortcutListener` is used in `onAttach()` and `onCreateDialog()`.
index 2ade1ea..1fd2fd7 100644 (file)
@@ -26,9 +26,6 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.net.Uri;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -36,18 +33,21 @@ import android.view.WindowManager;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
 import java.util.Locale;
 
-public class DownloadFileDialog extends AppCompatDialogFragment {
+public class DownloadFileDialog extends DialogFragment {
     // `downloadFileListener` is used in `onAttach()` and `onCreateDialog()`.
     private DownloadFileListener downloadFileListener;
 
     // The public interface is used to send information back to the parent activity.
     public interface DownloadFileListener {
-        void onDownloadFile(AppCompatDialogFragment dialogFragment, String downloadUrl);
+        void onDownloadFile(DialogFragment dialogFragment, String downloadUrl);
     }
 
     @Override
index 94f2586..eb2624f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -26,27 +26,25 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.net.Uri;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <= 22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.EditText;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
-// `android.support.v7.app.AlertDialog` uses more of the horizontal screen real estate versus `android.app.AlertDialog's` smaller width.
-// We have to use `AppCompatDialogFragment` instead of `DialogFragment` or an error is produced on API <=22.
-public class DownloadImageDialog extends AppCompatDialogFragment {
+public class DownloadImageDialog extends DialogFragment {
     // `downloadImageListener` is used in `onAttach()` and `onCreateDialog()`.
     private DownloadImageListener downloadImageListener;
 
     // The public interface is used to send information back to the parent activity.
     public interface DownloadImageListener {
-        void onDownloadImage(AppCompatDialogFragment dialogFragment, String downloadUrl);
+        void onDownloadImage(DialogFragment dialogFragment, String downloadUrl);
     }
 
     // Check to make sure tha the parent activity implements the listener.
index a232058..c505973 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -21,7 +21,6 @@ package com.stoutner.privacybrowser.dialogs;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
@@ -30,6 +29,9 @@ import android.view.WindowManager;
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 public class DownloadLocationPermissionDialog extends DialogFragment {
     // The constants are used to differentiate between the two download types.
     public static final int DOWNLOAD_FILE = 1;
@@ -65,8 +67,12 @@ public class DownloadLocationPermissionDialog extends DialogFragment {
         return thisDownloadLocationPermissionDialog;
     }
 
+    @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Remove the incorrect lint warning below that `getArguments().getInt()` might be null.
+        assert getArguments() != null;
+
         // Store the download type in a local variable.
         int downloadType = getArguments().getInt("download_type");
 
index 5abda5b..57ca9b4 100644 (file)
@@ -30,11 +30,6 @@ import android.database.MergeCursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v4.content.ContextCompat;
-import android.support.v4.widget.ResourceCursorAdapter;
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
@@ -46,6 +41,7 @@ import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.RadioButton;
 import android.widget.RadioGroup;
+import android.widget.ResourceCursorAdapter;
 import android.widget.Spinner;
 import android.widget.TextView;
 
@@ -53,7 +49,11 @@ import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
-public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
+public class EditBookmarkDatabaseViewDialog extends DialogFragment {
     // Instantiate the constants.
     public static final int HOME_FOLDER_DATABASE_ID = -1;
 
@@ -72,7 +72,7 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
 
     // The public interface is used to send information back to the parent activity.
     public interface EditBookmarkDatabaseViewListener {
-        void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId);
+        void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId);
     }
 
     @Override
index 64efa61..3bfb796 100644 (file)
@@ -28,9 +28,6 @@ import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
@@ -42,11 +39,14 @@ import android.widget.ImageView;
 import android.widget.RadioButton;
 import android.widget.RadioGroup;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
-public class EditBookmarkDialog extends AppCompatDialogFragment {
+public class EditBookmarkDialog extends DialogFragment {
     // Instantiate the class variables.
     private EditBookmarkListener editBookmarkListener;
     private EditText nameEditText;
@@ -58,7 +58,7 @@ public class EditBookmarkDialog extends AppCompatDialogFragment {
 
     // The public interface is used to send information back to the parent activity.
     public interface EditBookmarkListener {
-        void onSaveBookmark(AppCompatDialogFragment dialogFragment, int selectedBookmarkDatabaseId);
+        void onSaveBookmark(DialogFragment dialogFragment, int selectedBookmarkDatabaseId);
     }
 
     public void onAttach(Context context) {
index 0f69143..e9eb51e 100644 (file)
@@ -31,11 +31,6 @@ import android.database.MergeCursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.widget.ResourceCursorAdapter;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
@@ -47,14 +42,19 @@ import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.RadioButton;
 import android.widget.RadioGroup;
+import android.widget.ResourceCursorAdapter;
 import android.widget.Spinner;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
-public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragment {
+public class EditBookmarkFolderDatabaseViewDialog extends DialogFragment {
     // Instantiate the constants.
     public static final int HOME_FOLDER_DATABASE_ID = -1;
 
@@ -73,7 +73,7 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen
 
     // The public interface is used to send information back to the parent activity.
     public interface EditBookmarkFolderDatabaseViewListener {
-        void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId);
+        void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId);
     }
 
     public void onAttach(Context context) {
index e854a06..e3606a7 100644 (file)
@@ -28,9 +28,6 @@ import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.KeyEvent;
@@ -42,17 +39,20 @@ import android.widget.ImageView;
 import android.widget.RadioButton;
 import android.widget.RadioGroup;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
-public class EditBookmarkFolderDialog extends AppCompatDialogFragment {
+public class EditBookmarkFolderDialog extends DialogFragment {
     // Instantiate the class variable.
     private EditBookmarkFolderListener editBookmarkFolderListener;
 
     // The public interface is used to send information back to the parent activity.
     public interface EditBookmarkFolderListener {
-        void onSaveBookmarkFolder(AppCompatDialogFragment dialogFragment, int selectedFolderDatabaseId);
+        void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId);
     }
 
     public void onAttach(Context context) {
index 46af64e..6099d2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -25,9 +25,6 @@ import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// `AppCompatDialogFragment` is used instead of `DialogFragment` to avoid an error on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
@@ -41,7 +38,10 @@ import android.widget.TextView;
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
-public class HttpAuthenticationDialog extends AppCompatDialogFragment{
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
+public class HttpAuthenticationDialog extends DialogFragment{
     // `httpAuthenticationListener` is used in `onAttach()` and `onCreateDialog()`
     private HttpAuthenticationListener httpAuthenticationListener;
 
@@ -49,7 +49,7 @@ public class HttpAuthenticationDialog extends AppCompatDialogFragment{
     public interface HttpAuthenticationListener {
         void onHttpAuthenticationCancel();
 
-        void onHttpAuthenticationProceed(AppCompatDialogFragment dialogFragment);
+        void onHttpAuthenticationProceed(DialogFragment dialogFragment);
     }
 
     public void onAttach(Context context) {
index 28d0fa5..9f57519 100644 (file)
@@ -33,10 +33,6 @@ import android.graphics.BitmapFactory;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-// `AppCompatDialogFragment` must be used instead of `DialogFragment` or an error is produced on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -47,6 +43,10 @@ import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <= 22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.BookmarksActivity;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
@@ -54,7 +54,7 @@ import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
 import java.io.ByteArrayOutputStream;
 
-public class MoveToFolderDialog extends AppCompatDialogFragment {
+public class MoveToFolderDialog extends DialogFragment {
     // Instantiate the class variables.
     private MoveToFolderListener moveToFolderListener;
     private BookmarksDatabaseHelper bookmarksDatabaseHelper;
@@ -62,7 +62,7 @@ public class MoveToFolderDialog extends AppCompatDialogFragment {
 
     // The public interface is used to send information back to the parent activity.
     public interface MoveToFolderListener {
-        void onMoveToFolder(AppCompatDialogFragment dialogFragment);
+        void onMoveToFolder(DialogFragment dialogFragment);
     }
 
     public void onAttach(Context context) {
@@ -78,7 +78,7 @@ public class MoveToFolderDialog extends AppCompatDialogFragment {
     @Override
     @NonNull
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        // Initialize the database helper.  The two `nulls` do not specify the database name or a `CursorFactory`.  The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
+        // Initialize the database helper.  The `0` specifies a database version, but that is ignored and set instead using a constant in `BookmarksDatabaseHelper`.
         bookmarksDatabaseHelper = new BookmarksDatabaseHelper(getContext(), null, null, 0);
 
         // Use an alert dialog builder to create the alert dialog.
@@ -303,4 +303,4 @@ public class MoveToFolderDialog extends AppCompatDialogFragment {
             addSubfoldersToExceptFolders(subfolderName);
         }
     }
-}
+}
\ No newline at end of file
index 0a25771..e1c035a 100644 (file)
@@ -29,11 +29,6 @@ import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.net.http.SslCertificate;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.TabLayout;
-import android.support.v4.view.PagerAdapter;
-// `AppCompatDialogFragment` is used instead of `DialogFragment` to avoid an error on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
@@ -43,15 +38,21 @@ import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.TextView;
 
+import com.google.android.material.tabs.TabLayout;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
-import com.stoutner.privacybrowser.definitions.WrapVerticalContentViewPager;
+import com.stoutner.privacybrowser.views.WrapVerticalContentViewPager;
 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
 
 import java.text.DateFormat;
 import java.util.Date;
 
-public class PinnedMismatchDialog extends AppCompatDialogFragment {
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+import androidx.viewpager.widget.PagerAdapter;
+
+public class PinnedMismatchDialog extends DialogFragment {
     // Instantiate the class variables.
     private PinnedMismatchListener pinnedMismatchListener;
     private LayoutInflater layoutInflater;
index 4faafcb..56c9d02 100644 (file)
@@ -31,10 +31,6 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.provider.DocumentsContract;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-// `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.  It is also required for the browser button to work correctly.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.View;
@@ -46,14 +42,18 @@ import android.widget.TextView;
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
-public class SaveLogcatDialog extends AppCompatDialogFragment {
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment is required or an error is produced on API <=22.  It is also required for the browse button to work correctly.
+
+public class SaveLogcatDialog extends DialogFragment {
     // Instantiate the class variables.
     private SaveLogcatListener saveLogcatListener;
     private Context parentContext;
 
     // The public interface is used to send information back to the parent activity.
     public interface SaveLogcatListener {
-        void onSaveLogcat(AppCompatDialogFragment dialogFragment);
+        void onSaveLogcat(DialogFragment dialogFragment);
     }
 
     public void onAttach(Context context) {
index 76732ff..602ee2c 100644 (file)
@@ -30,9 +30,6 @@ import android.net.http.SslCertificate;
 import android.net.http.SslError;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-// `AppCompatDialogFragment` is used instead of `DialogFragment` to avoid an error on API <=22.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
@@ -40,6 +37,9 @@ import android.view.LayoutInflater;
 import android.view.WindowManager;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
@@ -49,7 +49,7 @@ import java.net.UnknownHostException;
 import java.text.DateFormat;
 import java.util.Date;
 
-public class SslCertificateErrorDialog extends AppCompatDialogFragment {
+public class SslCertificateErrorDialog extends DialogFragment {
     // `sslCertificateErrorListener` is used in `onAttach` and `onCreateDialog`.
     private SslCertificateErrorListener sslCertificateErrorListener;
 
index ed11959..fbff4d2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -24,15 +24,15 @@ import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
-// `AppCompatDialogFragment` must be used instead of `DialogFragment` or the browse button doesn't work correctly in the other dialog for saving logcats.
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.WindowManager;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
-public class StoragePermissionDialog extends AppCompatDialogFragment {
+public class StoragePermissionDialog extends DialogFragment {
     // The listener is used in `onAttach()` and `onCreateDialog()`.
     private StoragePermissionDialogListener storagePermissionDialogListener;
 
index a593f5c..0fe8afa 100644 (file)
@@ -29,11 +29,6 @@ import android.graphics.BitmapFactory;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-// `AppCompatDialogFragment` must be used instead of `DialogFragment` or an error is produced on API <= 22.
-// `android.support.v7.app.AlertDialog` also uses more of the horizontal screen real estate versus `android.app.AlertDialog's` smaller width.
-import android.support.v7.app.AppCompatDialogFragment;
 import android.util.Base64;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -42,6 +37,10 @@ import android.webkit.WebBackForwardList;
 import android.widget.AdapterView;
 import android.widget.ListView;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.adapters.HistoryArrayAdapter;
@@ -50,7 +49,7 @@ import com.stoutner.privacybrowser.definitions.History;
 import java.io.ByteArrayOutputStream;
 import java.util.ArrayList;
 
-public class UrlHistoryDialog extends AppCompatDialogFragment{
+public class UrlHistoryDialog extends DialogFragment{
 
     // `historyArrayList`  and `currentPageId` pass information from `onCreate()` to `onCreateDialog()`.
     private final ArrayList<History> historyArrayList = new ArrayList<>();
index 86b4f95..6d6401f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -25,17 +25,18 @@ import android.app.Dialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v7.app.AppCompatDialogFragment;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.Button;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
-public class ViewRequestDialog extends AppCompatDialogFragment {
+public class ViewRequestDialog extends DialogFragment {
     // The public interface is used to send information back to the parent activity.
     public interface ViewRequestListener {
         void onPrevious(int id);
index 73ad2ce..c99eeba 100644 (file)
@@ -22,7 +22,6 @@ package com.stoutner.privacybrowser.dialogs;
 import android.annotation.SuppressLint;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.app.DialogFragment;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -35,6 +34,9 @@ import android.view.LayoutInflater;
 import android.view.WindowManager;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;  // The AndroidX dialog fragment must be used or an error is produced on API <=22.
+
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.R;
 import java.text.DateFormat;
@@ -44,7 +46,11 @@ import java.util.Date;
 // `@SuppressLing("InflateParams")` removes the warning about using `null` as the parent view group when inflating the `AlertDialog`.
 @SuppressLint("InflateParams")
 public class ViewSslCertificateDialog extends DialogFragment {
+    @NonNull
     public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Remove the incorrect lint warning below that the activity might be null.
+        assert getActivity() != null;
+
         // Get the activity's layout inflater.
         LayoutInflater layoutInflater = getActivity().getLayoutInflater();
 
index 2f206fe..91cb7dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -25,8 +25,6 @@ import android.content.pm.PackageManager;
 import android.content.pm.Signature;
 import android.os.Build;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
@@ -36,6 +34,9 @@ import android.view.ViewGroup;
 import android.webkit.WebView;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+
 import com.stoutner.privacybrowser.BuildConfig;
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
index 614bb37..f08f343 100644 (file)
@@ -28,10 +28,6 @@ import android.net.http.SslCertificate;
 import android.os.Build;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
-import android.support.annotation.NonNull;
-// `android.support.v4.app.Fragment` must be used until minimum API >= 23.  Otherwise `getContext()` does not work.
-import android.support.v4.app.Fragment;
-import android.support.v7.widget.CardView;
 import android.text.Editable;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
@@ -52,6 +48,10 @@ import android.widget.Spinner;
 import android.widget.Switch;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+import androidx.cardview.widget.CardView;
+import androidx.fragment.app.Fragment;  // The AndroidX fragment must be used until minimum API >= 23.  Otherwise `getContext()` does not work.
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.helpers.DomainsDatabaseHelper;
index 8f50d2f..b28289b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
 package com.stoutner.privacybrowser.fragments;
 
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.design.widget.FloatingActionButton;
-// `android.support.v4.app.Fragment` must be used until minimum API >= 23.  Otherwise `getContext()` cannot be called.
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.ListView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;  // The AndroidX fragment must be used until minimum API >= 23.  Otherwise `getContext()` does not work.
+import androidx.fragment.app.FragmentManager;
+
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.DomainsActivity;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
@@ -59,8 +60,14 @@ public class DomainsListFragment extends Fragment {
 
             // Save the current domain settings if operating in two-paned mode and a domain is currently selected.
             if (DomainsActivity.twoPanedMode && DomainsActivity.deleteMenuItem.isEnabled()) {
+                // Get a handle for the domain settings fragment.
+                Fragment domainSettingsFragment = supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container);
+
+                // Remove the incorrect lint error below that the domain settings fragment might be null.
+                assert domainSettingsFragment != null;
+
                 // Get a handle for the domain settings fragment view.
-                View domainSettingsFragmentView = supportFragmentManager.findFragmentById(R.id.domain_settings_fragment_container).getView();
+                View domainSettingsFragmentView = domainSettingsFragment.getView();
 
                 // Get a handle for the domains activity.
                 DomainsActivity domainsActivity = new DomainsActivity();
@@ -105,7 +112,7 @@ public class DomainsListFragment extends Fragment {
 
                 // Hide the add domain FAB.
                 FloatingActionButton addDomainFAB = getActivity().findViewById(R.id.add_domain_fab);
-                addDomainFAB.setVisibility(View.GONE);
+                addDomainFAB.hide();
 
                 // Display the domain settings fragment.
                 supportFragmentManager.beginTransaction().replace(R.id.domains_listview_fragment_container, domainSettingsFragment).commit();
index d22006c..4a417b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -21,13 +21,14 @@ package com.stoutner.privacybrowser.fragments;
 
 import android.annotation.SuppressLint;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.Fragment;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.WebView;
 
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+
 import com.stoutner.privacybrowser.R;
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 
index 9852dd0..3717354 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -26,10 +26,11 @@ import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.net.Proxy;
-import android.support.v7.app.AlertDialog;
 import android.util.ArrayMap;
 import android.util.Log;
 
+import androidx.appcompat.app.AlertDialog;
+
 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
 import com.stoutner.privacybrowser.R;
 
index e9bc804..06187db 100644 (file)
 package com.stoutner.privacybrowser.views;
 
 import android.content.Context;
-import android.support.annotation.Nullable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.Checkable;
 import android.widget.LinearLayout;
 
+import androidx.annotation.Nullable;
+
 public class CheckedLinearLayout extends LinearLayout implements Checkable {
     private boolean isCurrentlyChecked;
     private static final int[] CHECKED_STATE_SET = {
diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java b/app/src/main/java/com/stoutner/privacybrowser/views/NestedScrollWebView.java
new file mode 100644 (file)
index 0000000..ea94571
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright © 2019 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.webkit.WebView;
+
+import androidx.core.view.NestedScrollingChild2;
+import androidx.core.view.NestedScrollingChildHelper;
+import androidx.core.view.ViewCompat;
+
+// NestedScrollWebView extends WebView to handle nested scrolls (scrolling the app bar off the screen).
+public class NestedScrollWebView extends WebView implements NestedScrollingChild2 {
+    // The nested scrolling child helper is used throughout the class.
+    private NestedScrollingChildHelper nestedScrollingChildHelper;
+
+    // The previous Y position needs to be tracked between motion events.
+    private int previousYPosition;
+
+
+    // Basic constructor.
+    public NestedScrollWebView(Context context) {
+        // Roll up to the next constructor.
+        this(context, null);
+    }
+
+    // Intermediate constructor.
+    public NestedScrollWebView(Context context, AttributeSet attributeSet) {
+        // Roll up to the next constructor.
+        this(context, attributeSet, android.R.attr.webViewStyle);
+    }
+
+    // Full constructor.
+    public NestedScrollWebView(Context context, AttributeSet attributeSet, int defaultStyle) {
+        // Run the default commands.
+        super(context, attributeSet, defaultStyle);
+
+        // Initialize the nested scrolling child helper.
+        nestedScrollingChildHelper = new NestedScrollingChildHelper(this);
+
+        // Enable nested scrolling by default.
+        nestedScrollingChildHelper.setNestedScrollingEnabled(true);
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent motionEvent) {
+        // Initialize a tracker to return if this motion event is handled.
+        boolean motionEventHandled;
+
+        // Run the commands for the given motion event action.
+        switch (motionEvent.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                // Start nested scrolling along the vertical axis.  `ViewCompat` must be used until the minimum API >= 21.
+                startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
+
+                // Save the current Y position.  Action down will not be called again until a new motion starts.
+                previousYPosition = (int) motionEvent.getY();
+
+                // Run the default commands.
+                motionEventHandled = super.onTouchEvent(motionEvent);
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                // Get the current Y position.
+                int currentYPosition = (int) motionEvent.getY();
+
+                // Calculate the delta Y.
+                int deltaY = previousYPosition - currentYPosition;
+
+                // Store the current Y position for use in the next action move.
+                previousYPosition = currentYPosition;
+
+                // Dispatch the nested pre-school.
+                dispatchNestedPreScroll(0, deltaY, null, null);
+
+                // Dispatch the nested scroll.
+                dispatchNestedScroll(0, deltaY, 0, 0, null);
+
+                // Run the default commands.
+                motionEventHandled = super.onTouchEvent(motionEvent);
+                break;
+
+
+            default:
+                // Stop nested scrolling.
+                stopNestedScroll();
+
+                // Run the default commands.
+                motionEventHandled = super.onTouchEvent(motionEvent);
+        }
+
+        // Return the status of the motion event.
+        return motionEventHandled;
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public void setNestedScrollingEnabled(boolean status) {
+        // Set the status of the nested scrolling.
+        nestedScrollingChildHelper.setNestedScrollingEnabled(status);
+    }
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean isNestedScrollingEnabled() {
+        // Return the status of nested scrolling.
+        return nestedScrollingChildHelper.isNestedScrollingEnabled();
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean startNestedScroll(int axes) {
+        // Start a nested scroll along the indicated axes.
+        return nestedScrollingChildHelper.startNestedScroll(axes);
+    }
+
+    // Method from NestedScrollingChild2.
+    @Override
+    public boolean startNestedScroll(int axes, int type) {
+        // Start a nested scroll along the indicated axes for the given type of input which caused the scroll event.
+        return nestedScrollingChildHelper.startNestedScroll(axes, type);
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public void stopNestedScroll() {
+        // Stop the nested scroll.
+        nestedScrollingChildHelper.stopNestedScroll();
+    }
+
+    // Method from NestedScrollingChild2.
+    @Override
+    public void stopNestedScroll(int type) {
+        // Stop the nested scroll of the given type of input which caused the scroll event.
+        nestedScrollingChildHelper.stopNestedScroll(type);
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean hasNestedScrollingParent() {
+        // Return the status of the nested scrolling parent.
+        return nestedScrollingChildHelper.hasNestedScrollingParent();
+    }
+
+    // Method from NestedScrollingChild2.
+    @Override
+    public boolean hasNestedScrollingParent(int type) {
+        // return the status of the nested scrolling parent for the given type of input which caused the scroll event.
+        return nestedScrollingChildHelper.hasNestedScrollingParent(type);
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean dispatchNestedPreScroll(int deltaX, int deltaY, int[] consumed, int[] offsetInWindow) {
+        // Dispatch a nested pre-scroll with the specified deltas, which lets a parent to consume some of the scroll if desired.
+        return nestedScrollingChildHelper.dispatchNestedPreScroll(deltaX, deltaY, consumed, offsetInWindow);
+    }
+
+    // Method from NestedScrollingChild2.
+    @Override
+    public boolean dispatchNestedPreScroll(int deltaX, int deltaY, int[] consumed, int[] offsetInWindow, int type) {
+        // Dispatch a nested pre-scroll with the specified deltas for the given type of input which caused the scroll event, which lets a parent to consume some of the scroll if desired.
+        return nestedScrollingChildHelper.dispatchNestedPreScroll(deltaX, deltaY, consumed, offsetInWindow, type);
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean dispatchNestedScroll(int deltaXConsumed, int deltaYConsumed, int deltaXUnconsumed, int deltaYUnconsumed, int[] offsetInWindow) {
+        // Dispatch a nested scroll with the specified deltas.
+        return nestedScrollingChildHelper.dispatchNestedScroll(deltaXConsumed, deltaYConsumed, deltaXUnconsumed, deltaYUnconsumed, offsetInWindow);
+    }
+
+    // Method from NestedScrollingChild2.
+    @Override
+    public boolean dispatchNestedScroll(int deltaXConsumed, int deltaYConsumed, int deltaXUnconsumed, int deltaYUnconsumed, int[] offsetInWindow, int type) {
+        // Dispatch a nested scroll with the specified deltas for the given type of input which caused the scroll event.
+        return nestedScrollingChildHelper.dispatchNestedScroll(deltaXConsumed, deltaYConsumed, deltaXUnconsumed, deltaYUnconsumed, offsetInWindow, type);
+    }
+
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
+        // Dispatch a nested pre-fling with the specified velocity, which lets a parent consume the fling if desired.
+        return nestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
+    }
+
+    // Method from NestedScrollingChild.
+    @Override
+    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
+        // Dispatch a nested fling with the specified velocity.
+        return nestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/WrapVerticalContentViewPager.java b/app/src/main/java/com/stoutner/privacybrowser/views/WrapVerticalContentViewPager.java
new file mode 100644 (file)
index 0000000..7e29725
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
+ *
+ * Privacy Browser is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Privacy Browser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.stoutner.privacybrowser.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.viewpager.widget.ViewPager;
+
+public class WrapVerticalContentViewPager extends ViewPager {
+    // Setup the default constructors.
+    public WrapVerticalContentViewPager(Context context) {
+        super(context);
+    }
+
+    public WrapVerticalContentViewPager(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // Perform an initial `super.onMeasure`, which populates `getChildCount`.
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        // Initialize `maximumHeight`.
+        int maximumHeight = 0;
+
+        // Find the maximum height of each of the child views.
+        for (int i = 0; i < getChildCount(); i++) {
+            View childView = getChildAt(i);
+
+            // Measure the child view height with no constraints.
+            childView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+
+            // Store the child's height if it is larger than `maximumHeight`.
+            if (childView.getMeasuredHeight() > maximumHeight) {
+                maximumHeight = childView.getMeasuredHeight();
+            }
+        }
+
+        // Perform a final `super.onMeasure` to set the `maximumHeight`.
+        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maximumHeight, MeasureSpec.EXACTLY));
+    }
+}
\ No newline at end of file
index 2b7073e..aafac66 100644 (file)
@@ -49,7 +49,7 @@
             android:dividerHeight="0dp" />
     </LinearLayout>
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.FloatingActionButton
         android:id="@+id/launch_bookmarks_activity_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
@@ -57,7 +57,7 @@
         android:layout_marginEnd="16dp"
         android:layout_marginBottom="155dp" />
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.FloatingActionButton
         android:id="@+id/create_bookmark_folder_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
@@ -65,7 +65,7 @@
         android:layout_marginEnd="16dp"
         android:layout_marginBottom="85dp" />
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.FloatingActionButton
         android:id="@+id/create_bookmark_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
index 43d0159..81284a9 100644 (file)
@@ -18,7 +18,7 @@
   along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>. -->
 
 <!-- `android:choiceMode="singleChoice"` allows a selected domain to be highlighted.-->
-<tools:ListView
+<ListView
     android:id="@+id/domains_listview"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
index 4c9c4ae..4d844be 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -21,7 +21,7 @@
 <!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
   When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
   to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/about_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
         android:orientation="vertical" >
 
         <!-- We need to set `android:background="?attr/colorPrimaryDark"` here or any space to the right of the `TabLayout` on large devices will be the theme background color. -->
-        <android.support.design.widget.AppBarLayout
+        <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/about_appbarlayout"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:background="?attr/colorPrimaryDark" >
 
             <!-- `android:theme="?attr/appBarTextTheme"` sets the color of the text and icons in the `AppBar`. -->
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/about_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
@@ -50,7 +50,7 @@
                 android:theme="?attr/appBarTextTheme" />
 
             <!-- For some reason `tabIndicatorColor` does not pull from the style unless specified explicitly here. -->
-            <android.support.design.widget.TabLayout
+            <com.google.android.material.tabs.TabLayout
                 android:id="@+id/about_tablayout"
                 xmlns:android.support.design="http://schemas.android.com/apk/res-auto"
                 android:layout_height="wrap_content"
                 android.support.design:tabMode="scrollable"
                 android.support.design:tabIndicatorColor="?attr/tabIndicatorColor"
                 android:theme="?attr/tabLayoutTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
         <!-- `android:layout_weight="1"` makes `about_viewpager` fill the rest of the screen. -->
-        <android.support.v4.view.ViewPager
+        <androidx.viewpager.widget.ViewPager
             android:id="@+id/about_viewpager"
             android:layout_height="0dp"
             android:layout_width="match_parent"
             android:layout_weight="1" />
     </LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
index dff393c..d69a448 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -24,8 +24,8 @@
     android:layout_width="match_parent"
     android:orientation="vertical" >
 
-    <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-    <android.support.design.widget.TextInputLayout
+    <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+    <com.google.android.material.textfield.TextInputLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_marginTop="12dp"
@@ -33,7 +33,7 @@
         android:layout_marginEnd="4dp" >
 
         <!-- `android:imeOptions="actionGo" sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-        <android.support.design.widget.TextInputEditText
+        <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/domain_name_edittext"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -41,7 +41,7 @@
             android:imeOptions="actionGo"
             android:inputType="textUri"
             android:selectAllOnFocus="true" />
-    </android.support.design.widget.TextInputLayout>
+    </com.google.android.material.textfield.TextInputLayout>
 
     <TextView
         android:id="@+id/domain_name_already_exists_textview"
index e974491..3afb8ac 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -20,7 +20,7 @@
 
 <!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
     When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/bookmarks_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <android.support.design.widget.AppBarLayout
+        <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/bookmarks_appbarlayout"
             android:layout_height="wrap_content"
             android:layout_width="match_parent" >
 
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/bookmarks_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:background="?attr/colorPrimaryDark"
                 android:theme="?attr/appBarTextTheme"
                 app:popupTheme="?attr/popupsTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
         <!-- `android:choiceMode="multipleChoiceModal"` allows the contextual action menu to select more than one item at a time.
             `android:dividerHeight` must be at least `1dp` or the `ListView` is inconsistent in calculating how many bookmarks are displayed. -->
@@ -59,7 +59,7 @@
             android:dividerHeight="1dp" />
     </LinearLayout>
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
         android:id="@+id/create_bookmark_folder_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_marginBottom="85dp"
         android:src="?attr/addFolderIcon" />
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
         android:id="@+id/create_bookmark_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_gravity="bottom|end"
         android:layout_margin="16dp"
         android:src="?attr/addBookmarkIcon" />
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
index 378a71e..298c579 100644 (file)
@@ -21,7 +21,7 @@
 <!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
     When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>`
     to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/bookmarks_databaseview_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <android.support.design.widget.AppBarLayout
+        <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/bookmarks_databaseview_appbarlayout"
             android:layout_height="wrap_content"
             android:layout_width="match_parent" >
 
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/bookmarks_databaseview_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:background="?attr/colorPrimaryDark"
                 android:theme="?attr/appBarTextTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
         <!-- `android:choiceMode="multipleChoiceModal"` allows the contextual action menu to select more than one item at a time. -->
         <ListView
@@ -54,4 +54,4 @@
             android:layout_width="match_parent"
             android:choiceMode="multipleChoiceModal" />
     </LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
index 7911f31..85031f9 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017, 2019 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
index 6b57478..cd6e198 100644 (file)
@@ -48,7 +48,7 @@
             android:dividerHeight="0dp" />
     </LinearLayout>
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
         android:id="@+id/launch_bookmarks_activity_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
@@ -56,7 +56,7 @@
         android:layout_marginEnd="16dp"
         android:layout_marginBottom="155dp" />
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
         android:id="@+id/create_bookmark_folder_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
@@ -64,7 +64,7 @@
         android:layout_marginEnd="16dp"
         android:layout_marginBottom="85dp" />
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
         android:id="@+id/create_bookmark_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
index c51df25..84dad7e 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -28,8 +28,8 @@
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="12dp"
@@ -38,7 +38,7 @@
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/create_bookmark_name_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-            </android.support.design.widget.TextInputLayout>
+            </com.google.android.material.textfield.TextInputLayout>
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="6dp"
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <EditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/create_bookmark_url_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:hint="@string/bookmark_url"
                 android:imeOptions="actionGo"
                 android:inputType="textUri" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
index 53bf6dc..f6cdc69 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -90,8 +90,8 @@
             </RadioGroup>
         </LinearLayout>
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="6dp"
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a "go" key instead of a "new line" key.
                 `android:inputType="textUri"` disables spell check in the EditText. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/create_folder_name_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:hint="@string/folder_name"
                 android:imeOptions="actionGo"
                 android:inputType="textUri" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
         <TextView
             android:layout_height="wrap_content"
index 29eb53e..5931361 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2015-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2015-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -28,7 +28,8 @@
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="16dp"
@@ -38,7 +39,7 @@
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.
                  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/shortcut_name_edittext"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -46,6 +47,6 @@
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
index 74e76de..1c706fb 100644 (file)
                     android:tint="?attr/domainSettingsIconTintColor"
                     tools:ignore="contentDescription" />
 
-                <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-                <android.support.design.widget.TextInputLayout
+                <!-- `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+                <com.google.android.material.textfield.TextInputLayout
                     android:layout_height="wrap_content"
                     android:layout_width="match_parent"
                     android:layout_marginStart="6dp" >
 
                     <!-- `android:inputType="textUri"` disables spell check in the `EditText`. -->
-                    <android.support.design.widget.TextInputEditText
+                    <com.google.android.material.textfield.TextInputEditText
                         android:id="@+id/domain_settings_name_edittext"
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
                         android:hint="@string/domain_name"
                         android:inputType="textUri" />
-                </android.support.design.widget.TextInputLayout>
+                </com.google.android.material.textfield.TextInputLayout>
             </LinearLayout>
 
             <TextView
             </LinearLayout>
 
             <!-- Saved Certificate -->
-            <android.support.v7.widget.CardView
+            <androidx.cardview.widget.CardView
                 android:id="@+id/saved_ssl_certificate_cardview"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                             android:layout_width="match_parent" />
                     </LinearLayout>
                 </LinearLayout>
-            </android.support.v7.widget.CardView>
+            </androidx.cardview.widget.CardView>
 
             <!-- Current Website Certificate -->
-            <android.support.v7.widget.CardView
+            <androidx.cardview.widget.CardView
                 android:id="@+id/current_website_certificate_cardview"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                             android:layout_width="match_parent" />
                     </LinearLayout>
                 </LinearLayout>
-            </android.support.v7.widget.CardView>
+            </androidx.cardview.widget.CardView>
 
             <!-- Load An Encrypted Website Instructions. -->
             <TextView
             </LinearLayout>
 
             <!-- Saved IP Addresses -->
-            <android.support.v7.widget.CardView
+            <androidx.cardview.widget.CardView
                 android:id="@+id/saved_ip_addresses_cardview"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                         android:layout_marginStart="32dp"
                         android:textColor="?attr/aboutText" />
                 </LinearLayout>
-            </android.support.v7.widget.CardView>
+            </androidx.cardview.widget.CardView>
 
-            <android.support.v7.widget.CardView
+            <androidx.cardview.widget.CardView
                 android:id="@+id/current_ip_addresses_cardview"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                         android:layout_marginStart="32dp"
                         android:textColor="?attr/aboutText" />
                 </LinearLayout>
-            </android.support.v7.widget.CardView>
+            </androidx.cardview.widget.CardView>
         </LinearLayout>
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
index c875f44..69aabd8 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -18,8 +18,9 @@
   You should have received a copy of the GNU General Public License
   along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.  When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
+    When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/domains_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <android.support.design.widget.AppBarLayout
+        <com.google.android.material.appbar.AppBarLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent" >
 
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/domains_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:background="?attr/colorPrimaryDark"
                 android:theme="?attr/appBarTextTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
         <include layout="@layout/domains_fragments" />
     </LinearLayout>
 
-    <android.support.design.widget.FloatingActionButton
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
         android:id="@+id/add_domain_fab"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
         android:layout_gravity="bottom|end"
         android:layout_margin="16dp"
         android:src="?attr/addIcon" />
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
index 01eddd9..d3812fc 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
     android:padding="6dp">
 
 
-    <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-    <android.support.design.widget.TextInputLayout
+    <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+    <com.google.android.material.textfield.TextInputLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent" >
 
-        <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key.
-            `android:inputType="textUri"` disables spell check in the `EditText`. -->
-        <android.support.design.widget.TextInputEditText
+        <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
+        <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/download_file_name"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:hint="@string/file_name"
             android:imeOptions="actionGo"
             android:inputType="textUri" />
-    </android.support.design.widget.TextInputLayout>
+    </com.google.android.material.textfield.TextInputLayout>
 
     <TextView
         android:id="@+id/download_file_size"
index c37dc7a..bbcde90 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
     android:padding="6dp">
 
 
-    <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-    <android.support.design.widget.TextInputLayout
+    <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+    <com.google.android.material.textfield.TextInputLayout
         android:layout_height="wrap_content"
         android:layout_width="match_parent" >
 
-        <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key.
-            `android:inputType="textUri"` disables spell check in the `EditText`. -->
-        <android.support.design.widget.TextInputEditText
+        <!-- `android:imeOptions="actionsGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
+        <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/download_image_name"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:hint="@string/image_name"
             android:imeOptions="actionGo"
             android:inputType="textUri" />
-    </android.support.design.widget.TextInputLayout>
+    </com.google.android.material.textfield.TextInputLayout>
 </LinearLayout>
\ No newline at end of file
index f690f9c..a03d009 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
             </RadioGroup>
         </LinearLayout>
 
-        <!-- Bookmark name.  `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- Bookmark name.  The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="12dp"
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/edit_bookmark_name_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
-        <!-- URL.  `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- URL.  The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="6dp"
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/edit_bookmark_url_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
         <!-- Folder. -->
         <LinearLayout
index 1184805..817ed9b 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -88,8 +88,8 @@
             </RadioGroup>
         </LinearLayout>
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="12dp"
@@ -98,7 +98,7 @@
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/edit_bookmark_name_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="6dp"
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <EditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/edit_bookmark_url_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
index 4b9cec3..bb59f8b 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
             </RadioGroup>
         </LinearLayout>
 
-        <!-- Folder name.  `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- Folder name.  The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="12dp"
             android:layout_marginEnd="4dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/edit_folder_name_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
         <!-- Folder. -->
         <LinearLayout
index 9bed6a4..997a8b4 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
             </RadioGroup>
         </LinearLayout>
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="6dp"
             android:layout_marginStart="4dp"
             android:layout_marginEnd="4dp" >
 
-            <!-- `android:imeOptions="actionGo"` sets the keyboard to have a "go" key instead of a "new line" key.
-                `android:inputType="textUri"` disables spell check in the EditText. -->
-            <android.support.design.widget.TextInputEditText
+            <!-- `android:imeOptions="actionGo"` sets the keyboard to have a "go" key instead of a "new line" key.  `android:inputType="textUri"` disables spell check in the EditText. -->
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/edit_folder_name_edittext"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
         <TextView
             android:layout_height="wrap_content"
index 247bb69..8b2a510 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -21,6 +21,7 @@
 <!-- `LinearLayout` is initially `visibility="gone"` so the `url_app_bar` is visible. -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/find_on_page_linearlayout"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
@@ -38,7 +39,8 @@
         android:hint="@string/find_on_page"
         android:lines="1"
         android:imeOptions="actionDone"
-        android:inputType="text" />
+        android:inputType="text"
+        tools:ignore="Autofill" />
 
     <TextView
         android:id="@+id/find_on_page_count_textview"
@@ -46,8 +48,7 @@
         android:layout_width="wrap_content"
         android:layout_marginStart="4dp"
         android:layout_marginEnd="4dp"
-        android:text="@string/zero_of_zero"
-        />
+        android:text="@string/zero_of_zero" />
 
     <ImageView
         android:id="@+id/find_previous"
index 885ec2e..645c453 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2016-2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2016-2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -19,9 +19,8 @@
   along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>. -->
 
 <!-- android:fitsSystemWindows="true" moves the AppBar below the status bar.
-  When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item>
-  to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+When it is specified the theme should include <item name="android:windowTranslucentStatus">true</item> to make the status bar a transparent, darkened overlay. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/guide_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <!-- We need to set `android:background="?attr/colorPrimaryDark"` here or any space to the right of the `TabLayout` on large devices will be the theme background color. -->
-        <android.support.design.widget.AppBarLayout
+        <!-- `android:background="?attr/colorPrimaryDark"` needs to be set here or any space to the right of the `TabLayout` on large devices will be the theme background color. -->
+        <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/guide_appbarlayout"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:background="?attr/colorPrimaryDark" >
 
             <!-- `android:theme="?attr/appBarTextTheme"` sets the color of the text and icons in the `AppBar`. -->
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/guide_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
@@ -50,7 +49,7 @@
                 android:theme="?attr/appBarTextTheme" />
 
             <!-- For some reason `tabIndicatorColor` does not pull from the style unless specified explicitly here. -->
-            <android.support.design.widget.TabLayout
+            <com.google.android.material.tabs.TabLayout
                 android:id="@+id/guide_tablayout"
                 xmlns:android.support.design="http://schemas.android.com/apk/res-auto"
                 android:layout_height="wrap_content"
                 android.support.design:tabMode="scrollable"
                 android.support.design:tabIndicatorColor="?attr/tabIndicatorColor"
                 android:theme="?attr/tabLayoutTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
         <!-- `android:layout_weight="1"` makes `about_viewpager` fill the rest of the screen. -->
-        <android.support.v4.view.ViewPager
+        <androidx.viewpager.widget.ViewPager
             android:id="@+id/guide_viewpager"
             android:layout_width="match_parent"
             android:layout_height="0dp"
             android:layout_weight="1" />
     </LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
index df262c5..52e543d 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2017 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017,2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
             android:layout_marginStart="4dp"
             android:layout_marginEnd="4dp" />
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
             android:layout_marginTop="6dp" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key.  `android:inputType="textUri"` disables spell check in the `EditText`. -->
-            <android.support.design.widget.TextInputEditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/http_authentication_username"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:imeOptions="actionGo"
                 android:inputType="textUri"
                 android:selectAllOnFocus="true" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
 
-        <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-        <android.support.design.widget.TextInputLayout
+        <!-- The `TextInputLayout` makes the `android:hint` float above the `EditText`. -->
+        <com.google.android.material.textfield.TextInputLayout
             android:layout_height="wrap_content"
             android:layout_width="match_parent" >
 
             <!-- `android:imeOptions="actionGo"` sets the keyboard to have a `go` key instead of a `new line` key. -->
-            <EditText
+            <com.google.android.material.textfield.TextInputEditText
                 android:id="@+id/http_authentication_password"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:hint="@string/password"
                 android:imeOptions="actionGo"
                 android:inputType="textPassword" />
-        </android.support.design.widget.TextInputLayout>
+        </com.google.android.material.textfield.TextInputLayout>
     </LinearLayout>
 </ScrollView>
\ No newline at end of file
index c7dbc81..a38850a 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2018-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
@@ -20,7 +20,7 @@
 
 <!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
     When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/import_export_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <android.support.design.widget.AppBarLayout
+        <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/import_export_appbarlayout"
             android:layout_height="wrap_content"
             android:layout_width="match_parent" >
 
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/import_export_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:background="?attr/colorPrimaryDark"
                 android:theme="?attr/appBarTextTheme"
                 app:popupTheme="?attr/popupsTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
         <ScrollView
             android:layout_height="match_parent"
@@ -59,7 +59,7 @@
                 android:orientation="vertical" >
 
                 <!-- The encryption card. -->
-                <android.support.v7.widget.CardView
+                <androidx.cardview.widget.CardView
                     android:layout_height="wrap_content"
                     android:layout_width="match_parent"
                     android:layout_marginTop="10dp"
                             android:layout_gravity="center_horizontal" />
 
                         <!-- The encryption password. -->
-                        <android.support.design.widget.TextInputLayout
+                        <com.google.android.material.textfield.TextInputLayout
                             android:id="@+id/password_encryption_textinputlayout"
                             android:layout_height="wrap_content"
                             android:layout_width="match_parent"
                             app:passwordToggleEnabled="true" >
 
-                            <android.support.design.widget.TextInputEditText
+                            <com.google.android.material.textfield.TextInputEditText
                                 android:id="@+id/password_encryption_edittext"
                                 android:layout_height="wrap_content"
                                 android:layout_width="match_parent"
                                 android:hint="@string/password"
                                 android:inputType="textPassword"/>
-                        </android.support.design.widget.TextInputLayout>
+                        </com.google.android.material.textfield.TextInputLayout>
 
                         <!-- KitKat password encryption message. -->
                         <TextView
                             android:textColor="?android:textColorPrimary"
                             android:textAlignment="center" />
                     </LinearLayout>
-                </android.support.v7.widget.CardView>
+                </androidx.cardview.widget.CardView>
 
                 <!-- The file location card. -->
-                <android.support.v7.widget.CardView
+                <androidx.cardview.widget.CardView
                     android:id="@+id/file_location_cardview"
                     android:layout_height="wrap_content"
                     android:layout_width="match_parent"
                             android:layout_marginTop="10dp">
 
                             <!-- `android.support.design.widget.TextInputLayout` makes the `android:hint` float above the `EditText`. -->
-                            <android.support.design.widget.TextInputLayout
+                            <com.google.android.material.textfield.TextInputLayout
                                 android:layout_height="wrap_content"
                                 android:layout_width="0dp"
                                 android:layout_weight="1" >
 
                                 <!-- `android:inputType="textUri" disables spell check and places an `/` on the main keyboard. -->
-                                <android.support.design.widget.TextInputEditText
+                                <com.google.android.material.textfield.TextInputEditText
                                     android:id="@+id/file_name_edittext"
                                     android:layout_height="wrap_content"
                                     android:layout_width="match_parent"
                                     android:hint="@string/file_name"
                                     android:inputType="textMultiLine|textUri" />
-                            </android.support.design.widget.TextInputLayout>
+                            </com.google.android.material.textfield.TextInputLayout>
 
                             <Button
                                 android:id="@+id/browse_button"
                             app:backgroundTint="?attr/buttonBackgroundColorSelector"
                             android:textColor="?attr/buttonTextColorSelector" />
                     </LinearLayout>
-                </android.support.v7.widget.CardView>
+                </androidx.cardview.widget.CardView>
 
                 <TextView
                     android:id="@+id/import_export_storage_permission_textview"
             </LinearLayout>
         </ScrollView>
     </LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
index ac2400a..b1800ff 100644 (file)
@@ -20,7 +20,7 @@
 
 <!-- `android:fitsSystemWindows="true"` moves the AppBar below the status bar.
     When it is specified the theme should include `<item name="android:windowTranslucentStatus">true</item>` to make the status bar a transparent, darkened overlay. -->
-<android.support.design.widget.CoordinatorLayout
+<androidx.coordinatorlayout.widget.CoordinatorLayout
     android:id="@+id/logcat_coordinatorlayout"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
         android:orientation="vertical" >
 
-        <android.support.design.widget.AppBarLayout
+        <com.google.android.material.appbar.AppBarLayout
             android:id="@+id/logcat_appbarlayout"
             android:layout_height="wrap_content"
             android:layout_width="match_parent" >
 
-            <android.support.v7.widget.Toolbar
+            <androidx.appcompat.widget.Toolbar
                 android:id="@+id/logcat_toolbar"
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
                 android:background="?attr/colorPrimaryDark"
                 android:theme="?attr/appBarTextTheme"
                 app:popupTheme="?attr/popupsTheme" />
-        </android.support.design.widget.AppBarLayout>
+        </com.google.android.material.appbar.AppBarLayout>
 
-        <android.support.v4.widget.SwipeRefreshLayout
+        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
             android:id="@+id/logcat_swiperefreshlayout"
             android:layout_height="match_parent"
             android:layout_width="match_parent" >
@@ -64,6 +64,6 @@
                     android:layout_margin="10dp"
                     android:textIsSelectable="true" />
             </ScrollView>
-        </android.support.v4.widget.SwipeRefreshLayout>
+        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
     </LinearLayout>
-</android.support.design.widget.CoordinatorLayout>
\ No newline at end of file
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file