From 3d578ef2ef110ca01e07ba64f1a0808fcd279e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ros=C3=A1rio=20Pereira=20Fernandes?= Date: Wed, 7 Apr 2021 15:47:45 +0200 Subject: [PATCH] refactor(app): replace ButterKnife with View Binding (#1930) --- app/build.gradle.kts | 11 +- .../com/firebase/uidemo/ChooserActivity.java | 17 +- .../uidemo/auth/AnonymousUpgradeActivity.java | 94 +++---- .../firebase/uidemo/auth/AuthUiActivity.java | 231 ++++++++---------- .../uidemo/auth/SignedInActivity.java | 52 ++-- .../firestore/FirestoreChatActivity.java | 57 ++--- .../firestore/FirestorePagingActivity.java | 34 +-- .../realtime/FirebaseDbPagingActivity.java | 34 +-- .../realtime/RealtimeDbChatActivity.java | 51 ++-- .../realtime/RealtimeDbChatIndexActivity.java | 2 +- .../uidemo/storage/ImageActivity.java | 61 +++-- auth/build.gradle.kts | 1 - .../ui/auth/viewmodel/AuthViewModelBase.java | 2 - buildSrc/src/main/kotlin/Config.kt | 4 - common/build.gradle.kts | 1 - database/build.gradle.kts | 1 - firestore/build.gradle.kts | 1 - internal/lintchecks/build.gradle.kts | 1 - library/build.gradle.kts | 1 - proguard-tests/build.gradle.kts | 1 - storage/build.gradle.kts | 1 - 21 files changed, 294 insertions(+), 364 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9ec9590f0..50aab92bd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -40,7 +40,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds @@ -58,8 +57,12 @@ android { } compileOptions { - setSourceCompatibility(JavaVersion.VERSION_1_8) - setTargetCompatibility(JavaVersion.VERSION_1_8) + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + buildFeatures { + viewBinding = true } } @@ -87,9 +90,7 @@ dependencies { // They are used to make some aspects of the demo app implementation simpler for // demonstrative purposes, and you may find them useful in your own apps; YMMV. implementation(Config.Libs.Misc.permissions) - implementation(Config.Libs.Misc.butterKnife) implementation(Config.Libs.Androidx.constraint) - annotationProcessor(Config.Libs.Misc.butterKnifeCompiler) debugImplementation(Config.Libs.Misc.leakCanary) debugImplementation(Config.Libs.Misc.leakCanaryFragments) releaseImplementation(Config.Libs.Misc.leakCanaryNoop) diff --git a/app/src/main/java/com/firebase/uidemo/ChooserActivity.java b/app/src/main/java/com/firebase/uidemo/ChooserActivity.java index e1cdb02aa..4f7504299 100644 --- a/app/src/main/java/com/firebase/uidemo/ChooserActivity.java +++ b/app/src/main/java/com/firebase/uidemo/ChooserActivity.java @@ -29,6 +29,7 @@ import com.firebase.uidemo.database.firestore.FirestorePagingActivity; import com.firebase.uidemo.database.realtime.FirebaseDbPagingActivity; import com.firebase.uidemo.database.realtime.RealtimeDbChatActivity; +import com.firebase.uidemo.databinding.ActivityChooserBinding; import com.firebase.uidemo.storage.ImageActivity; import androidx.annotation.Nullable; @@ -36,12 +37,9 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; public class ChooserActivity extends AppCompatActivity { - @BindView(R.id.activities) - RecyclerView mActivities; + private ActivityChooserBinding mBinding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -55,13 +53,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { finish(); return; } + mBinding = ActivityChooserBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); - setContentView(R.layout.activity_chooser); - ButterKnife.bind(this); - - mActivities.setLayoutManager(new LinearLayoutManager(this)); - mActivities.setAdapter(new ActivityChooserAdapter()); - mActivities.setHasFixedSize(true); + mBinding.activities.setLayoutManager(new LinearLayoutManager(this)); + mBinding.activities.setAdapter(new ActivityChooserAdapter()); + mBinding.activities.setHasFixedSize(true); } private static class ActivityChooserAdapter diff --git a/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java b/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java index d31b69845..a3426b91b 100644 --- a/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java +++ b/app/src/main/java/com/firebase/uidemo/auth/AnonymousUpgradeActivity.java @@ -4,14 +4,14 @@ import android.os.Bundle; import android.text.TextUtils; import android.util.Log; -import android.widget.Button; -import android.widget.TextView; +import android.view.View; import android.widget.Toast; import com.firebase.ui.auth.AuthUI; import com.firebase.ui.auth.ErrorCodes; import com.firebase.ui.auth.IdpResponse; import com.firebase.uidemo.R; +import com.firebase.uidemo.databinding.ActivityAnonymousUpgradeBinding; import com.firebase.uidemo.util.ConfigurationUtils; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; @@ -25,9 +25,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; public class AnonymousUpgradeActivity extends AppCompatActivity { @@ -35,28 +32,15 @@ public class AnonymousUpgradeActivity extends AppCompatActivity { private static final int RC_SIGN_IN = 123; - @BindView(R.id.status_text) - TextView mStatus; - - @BindView(R.id.anon_sign_in) - Button mAnonSignInButton; - - @BindView(R.id.begin_flow) - Button mLaunchUIButton; - - @BindView(R.id.resolve_merge) - Button mResolveMergeButton; - - @BindView(R.id.sign_out) - Button mSignOutButton; + private ActivityAnonymousUpgradeBinding mBinding; private AuthCredential mPendingCredential; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_anonymous_upgrade); - ButterKnife.bind(this); + mBinding = ActivityAnonymousUpgradeBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); updateUI(); @@ -67,9 +51,36 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, getIntent()); } + + mBinding.anonSignIn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + signInAnonymously(); + } + }); + + mBinding.beginFlow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startAuthUI(); + } + }); + + mBinding.resolveMerge.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + resolveMerge(); + } + }); + + mBinding.signOut.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + signOut(); + } + }); } - @OnClick(R.id.anon_sign_in) public void signInAnonymously() { FirebaseAuth.getInstance().signInAnonymously() .addOnCompleteListener(this, new OnCompleteListener() { @@ -87,7 +98,6 @@ public void onComplete(@NonNull Task task) { }); } - @OnClick(R.id.begin_flow) public void startAuthUI() { List providers = ConfigurationUtils.getConfiguredProviders(this); Intent intent = AuthUI.getInstance().createSignInIntentBuilder() @@ -98,7 +108,6 @@ public void startAuthUI() { startActivityForResult(intent, RC_SIGN_IN); } - @OnClick(R.id.resolve_merge) public void resolveMerge() { if (mPendingCredential == null) { Toast.makeText(this, "Nothing to resolve.", Toast.LENGTH_SHORT).show(); @@ -125,7 +134,6 @@ public void onComplete(@NonNull Task task) { }); } - @OnClick(R.id.sign_out) public void signOut() { AuthUI.getInstance().signOut(this) .addOnCompleteListener(new OnCompleteListener() { @@ -156,7 +164,7 @@ private void handleSignInResult(int requestCode, int resultCode, Intent data) { } else if (response.getError().getErrorCode() == ErrorCodes .ANONYMOUS_UPGRADE_MERGE_CONFLICT) { setStatus("Merge conflict: user already exists."); - mResolveMergeButton.setEnabled(true); + mBinding.resolveMerge.setEnabled(true); mPendingCredential = response.getCredentialForLinking(); } else { Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show(); @@ -172,33 +180,33 @@ private void updateUI() { if (currentUser == null) { // Not signed in - mAnonSignInButton.setEnabled(true); - mLaunchUIButton.setEnabled(false); - mResolveMergeButton.setEnabled(false); - mSignOutButton.setEnabled(false); + mBinding.anonSignIn.setEnabled(true); + mBinding.beginFlow.setEnabled(false); + mBinding.resolveMerge.setEnabled(false); + mBinding.signOut.setEnabled(false); } else if (mPendingCredential == null && currentUser.isAnonymous()) { // Anonymous user, waiting for linking - mAnonSignInButton.setEnabled(false); - mLaunchUIButton.setEnabled(true); - mResolveMergeButton.setEnabled(false); - mSignOutButton.setEnabled(true); + mBinding.anonSignIn.setEnabled(false); + mBinding.beginFlow.setEnabled(true); + mBinding.resolveMerge.setEnabled(false); + mBinding.signOut.setEnabled(true); } else if (mPendingCredential == null && !currentUser.isAnonymous()) { // Fully signed in - mAnonSignInButton.setEnabled(false); - mLaunchUIButton.setEnabled(false); - mResolveMergeButton.setEnabled(false); - mSignOutButton.setEnabled(true); + mBinding.anonSignIn.setEnabled(false); + mBinding.beginFlow.setEnabled(false); + mBinding.resolveMerge.setEnabled(false); + mBinding.signOut.setEnabled(true); } else if (mPendingCredential != null) { // Signed in anonymous, awaiting merge conflict - mAnonSignInButton.setEnabled(false); - mLaunchUIButton.setEnabled(false); - mResolveMergeButton.setEnabled(true); - mSignOutButton.setEnabled(true); + mBinding.anonSignIn.setEnabled(false); + mBinding.beginFlow.setEnabled(false); + mBinding.resolveMerge.setEnabled(true); + mBinding.signOut.setEnabled(true); } } private void setStatus(String message) { - mStatus.setText(message); + mBinding.statusText.setText(message); } private String getUserIdentifier(FirebaseUser user) { diff --git a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java index adab4512f..945cd100d 100644 --- a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java +++ b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java @@ -20,11 +20,8 @@ import android.os.Bundle; import android.util.Log; import android.view.View; -import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.RadioButton; -import android.widget.TextView; import com.firebase.ui.auth.AuthMethodPickerLayout; import com.firebase.ui.auth.AuthUI; @@ -33,6 +30,7 @@ import com.firebase.ui.auth.IdpResponse; import com.firebase.ui.auth.util.ExtraConstants; import com.firebase.uidemo.R; +import com.firebase.uidemo.databinding.AuthUiLayoutBinding; import com.firebase.uidemo.util.ConfigurationUtils; import com.google.android.gms.common.Scopes; import com.google.android.gms.tasks.OnCompleteListener; @@ -52,9 +50,6 @@ import androidx.annotation.StyleRes; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatDelegate; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; public class AuthUiActivity extends AppCompatActivity { private static final String TAG = "AuthUiActivity"; @@ -68,48 +63,7 @@ public class AuthUiActivity extends AppCompatActivity { private static final int RC_SIGN_IN = 100; - @BindView(R.id.root) View mRootView; - - @BindView(R.id.google_provider) CheckBox mUseGoogleProvider; - @BindView(R.id.facebook_provider) CheckBox mUseFacebookProvider; - @BindView(R.id.twitter_provider) CheckBox mUseTwitterProvider; - @BindView(R.id.email_provider) CheckBox mUseEmailProvider; - @BindView(R.id.email_link_provider) CheckBox mUseEmailLinkProvider; - @BindView(R.id.phone_provider) CheckBox mUsePhoneProvider; - @BindView(R.id.anonymous_provider) CheckBox mUseAnonymousProvider; - @BindView(R.id.apple_provider) CheckBox mUseAppleProvider; - @BindView(R.id.microsoft_provider) CheckBox mUseMicrosoftProvider; - @BindView(R.id.yahoo_provider) CheckBox mUseYahooProvider; - @BindView(R.id.github_provider) CheckBox mUseGitHubProvider; - - @BindView(R.id.default_layout) RadioButton mDefaultLayout; - @BindView(R.id.custom_layout) RadioButton mCustomLayout; - - @BindView(R.id.default_theme) RadioButton mDefaultTheme; - @BindView(R.id.green_theme) RadioButton mGreenTheme; - @BindView(R.id.purple_theme) RadioButton mPurpleTheme; - @BindView(R.id.dark_theme) RadioButton mDarkTheme; - - @BindView(R.id.firebase_logo) RadioButton mFirebaseLogo; - @BindView(R.id.google_logo) RadioButton mGoogleLogo; - @BindView(R.id.no_logo) RadioButton mNoLogo; - - @BindView(R.id.google_tos_privacy) RadioButton mUseGoogleTosPp; - @BindView(R.id.firebase_tos_privacy) RadioButton mUseFirebaseTosPp; - - @BindView(R.id.google_scopes_header) TextView mGoogleScopesHeader; - @BindView(R.id.google_scope_drive_file) CheckBox mGoogleScopeDriveFile; - @BindView(R.id.google_scope_youtube_data) CheckBox mGoogleScopeYoutubeData; - - @BindView(R.id.facebook_permissions_header) TextView mFacebookPermissionsHeader; - @BindView(R.id.facebook_permission_friends) CheckBox mFacebookPermissionFriends; - @BindView(R.id.facebook_permission_photos) CheckBox mFacebookPermissionPhotos; - - @BindView(R.id.credential_selector_enabled) CheckBox mEnableCredentialSelector; - @BindView(R.id.hint_selector_enabled) CheckBox mEnableHintSelector; - @BindView(R.id.allow_new_email_accounts) CheckBox mAllowNewEmailAccounts; - @BindView(R.id.require_name) CheckBox mRequireName; - @BindView(R.id.use_auth_emulator) CheckBox mUseEmulator; + private AuthUiLayoutBinding mBinding; @NonNull public static Intent createIntent(@NonNull Context context) { @@ -119,17 +73,17 @@ public static Intent createIntent(@NonNull Context context) { @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.auth_ui_layout); - ButterKnife.bind(this); + mBinding = AuthUiLayoutBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); if (ConfigurationUtils.isGoogleMisconfigured(this)) { - mUseGoogleProvider.setChecked(false); - mUseGoogleProvider.setEnabled(false); - mUseGoogleProvider.setText(R.string.google_label_missing_config); + mBinding.googleProvider.setChecked(false); + mBinding.googleProvider.setEnabled(false); + mBinding.googleProvider.setText(R.string.google_label_missing_config); setGoogleScopesEnabled(false); } else { - setGoogleScopesEnabled(mUseGoogleProvider.isChecked()); - mUseGoogleProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { + setGoogleScopesEnabled(mBinding.googleProvider.isChecked()); + mBinding.googleProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { setGoogleScopesEnabled(checked); @@ -138,13 +92,13 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { } if (ConfigurationUtils.isFacebookMisconfigured(this)) { - mUseFacebookProvider.setChecked(false); - mUseFacebookProvider.setEnabled(false); - mUseFacebookProvider.setText(R.string.facebook_label_missing_config); + mBinding.facebookProvider.setChecked(false); + mBinding.facebookProvider.setEnabled(false); + mBinding.facebookProvider.setText(R.string.facebook_label_missing_config); setFacebookPermissionsEnabled(false); } else { - setFacebookPermissionsEnabled(mUseFacebookProvider.isChecked()); - mUseFacebookProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { + setFacebookPermissionsEnabled(mBinding.facebookProvider.isChecked()); + mBinding.facebookProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { setFacebookPermissionsEnabled(checked); @@ -152,65 +106,84 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { }); } - mUseEmailLinkProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { + mBinding.emailLinkProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { flipPasswordProviderCheckbox(isChecked); } }); - mUseEmailProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { + mBinding.emailProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { flipEmailLinkProviderCheckbox(isChecked); } }); - mUseEmailLinkProvider.setChecked(false); - mUseEmailProvider.setChecked(true); + mBinding.emailLinkProvider.setChecked(false); + mBinding.emailProvider.setChecked(true); // The custom layout in this app only supports Email and Google providers. - mCustomLayout.setOnCheckedChangeListener(new OnCheckedChangeListener() { + mBinding.customLayout.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { if (checked) { - mUseGoogleProvider.setChecked(true); - mUseEmailProvider.setChecked(true); - - mUseFacebookProvider.setChecked(false); - mUseTwitterProvider.setChecked(false); - mUseEmailLinkProvider.setChecked(false); - mUsePhoneProvider.setChecked(false); - mUseAnonymousProvider.setChecked(false); - mUseMicrosoftProvider.setChecked(false); - mUseYahooProvider.setChecked(false); - mUseAppleProvider.setChecked(false); - mUseGitHubProvider.setChecked(false); + mBinding.googleProvider.setChecked(true); + mBinding.emailProvider.setChecked(true); + + mBinding.facebookProvider.setChecked(false); + mBinding.twitterProvider.setChecked(false); + mBinding.emailLinkProvider.setChecked(false); + mBinding.phoneProvider.setChecked(false); + mBinding.anonymousProvider.setChecked(false); + mBinding.microsoftProvider.setChecked(false); + mBinding.yahooProvider.setChecked(false); + mBinding.appleProvider.setChecked(false); + mBinding.githubProvider.setChecked(false); } } }); // useEmulator can't be reversed until the FirebaseApp is cleared, so we make this // checkbox "sticky" until the app is restarted - mUseEmulator.setOnCheckedChangeListener(new OnCheckedChangeListener() { + mBinding.useAuthEmulator.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { - mUseEmulator.setEnabled(false); + mBinding.useAuthEmulator.setEnabled(false); } } }); + mBinding.signIn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + signIn(); + } + }); + + mBinding.signInSilent.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + silentSignIn(); + } + }); + if (ConfigurationUtils.isGoogleMisconfigured(this) || ConfigurationUtils.isFacebookMisconfigured(this)) { showSnackbar(R.string.configuration_required); } if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) { - mDarkTheme.setChecked(true); + mBinding.darkTheme.setChecked(true); } catchEmailLinkSignIn(); + + mBinding.defaultTheme.setOnClickListener(toggleDarkThemeListener); + mBinding.greenTheme.setOnClickListener(toggleDarkThemeListener); + mBinding.purpleTheme.setOnClickListener(toggleDarkThemeListener); + mBinding.darkTheme.setOnClickListener(toggleDarkThemeListener); } public void catchEmailLinkSignIn() { @@ -225,17 +198,16 @@ public void catchEmailLinkSignIn() { public void flipPasswordProviderCheckbox(boolean emailLinkProviderIsChecked) { if (emailLinkProviderIsChecked) { - mUseEmailProvider.setChecked(false); + mBinding.emailProvider.setChecked(false); } } public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) { if (passwordProviderIsChecked) { - mUseEmailLinkProvider.setChecked(false); + mBinding.emailLinkProvider.setChecked(false); } } - @OnClick(R.id.sign_in) public void signIn() { startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN); } @@ -247,7 +219,7 @@ public void signInWithEmailLink(@Nullable String link) { @NonNull public AuthUI getAuthUI() { AuthUI authUI = AuthUI.getInstance(); - if (mUseEmulator.isChecked()) { + if (mBinding.useAuthEmulator.isChecked()) { authUI.useEmulator("10.0.2.2", 9099); } @@ -260,10 +232,10 @@ public Intent buildSignInIntent(@Nullable String link) { .setTheme(getSelectedTheme()) .setLogo(getSelectedLogo()) .setAvailableProviders(getSelectedProviders()) - .setIsSmartLockEnabled(mEnableCredentialSelector.isChecked(), - mEnableHintSelector.isChecked()); + .setIsSmartLockEnabled(mBinding.credentialSelectorEnabled.isChecked(), + mBinding.hintSelectorEnabled.isChecked()); - if (mCustomLayout.isChecked()) { + if (mBinding.customLayout.isChecked()) { AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout .Builder(R.layout.auth_method_picker_custom_layout) .setGoogleButtonId(R.id.custom_google_signin_button) @@ -294,7 +266,6 @@ public Intent buildSignInIntent(@Nullable String link) { return builder.build(); } - @OnClick(R.id.sign_in_silent) public void silentSignIn() { getAuthUI().silentSignIn(this, getSelectedProviders()) .addOnCompleteListener(this, new OnCompleteListener() { @@ -367,23 +338,25 @@ private void startSignedInActivity(@Nullable IdpResponse response) { startActivity(SignedInActivity.createIntent(this, response)); } - @OnClick({R.id.default_theme, R.id.purple_theme, R.id.green_theme, R.id.dark_theme}) - public void toggleDarkTheme() { - int mode = mDarkTheme.isChecked() ? - AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; - if (Build.VERSION.SDK_INT >= 17) { - AppCompatDelegate.setDefaultNightMode(mode); - getDelegate().setLocalNightMode(mode); + private View.OnClickListener toggleDarkThemeListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + int mode = mBinding.darkTheme.isChecked() ? + AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; + if (Build.VERSION.SDK_INT >= 17) { + AppCompatDelegate.setDefaultNightMode(mode); + getDelegate().setLocalNightMode(mode); + } } - } + }; @StyleRes private int getSelectedTheme() { - if (mGreenTheme.isChecked()) { + if (mBinding.greenTheme.isChecked()) { return R.style.GreenTheme; } - if (mPurpleTheme.isChecked()) { + if (mBinding.purpleTheme.isChecked()) { return R.style.PurpleTheme; } @@ -392,9 +365,9 @@ private int getSelectedTheme() { @DrawableRes private int getSelectedLogo() { - if (mFirebaseLogo.isChecked()) { + if (mBinding.firebaseLogo.isChecked()) { return R.drawable.firebase_auth_120dp; - } else if (mGoogleLogo.isChecked()) { + } else if (mBinding.googleLogo.isChecked()) { return R.drawable.ic_googleg_color_144dp; } return AuthUI.NO_LOGO; @@ -403,25 +376,25 @@ private int getSelectedLogo() { private List getSelectedProviders() { List selectedProviders = new ArrayList<>(); - if (mUseGoogleProvider.isChecked()) { + if (mBinding.googleProvider.isChecked()) { selectedProviders.add( new IdpConfig.GoogleBuilder().setScopes(getGoogleScopes()).build()); } - if (mUseFacebookProvider.isChecked()) { + if (mBinding.facebookProvider.isChecked()) { selectedProviders.add(new IdpConfig.FacebookBuilder() .setPermissions(getFacebookPermissions()) .build()); } - if (mUseEmailProvider.isChecked()) { + if (mBinding.emailProvider.isChecked()) { selectedProviders.add(new IdpConfig.EmailBuilder() - .setRequireName(mRequireName.isChecked()) - .setAllowNewAccounts(mAllowNewEmailAccounts.isChecked()) + .setRequireName(mBinding.requireName.isChecked()) + .setAllowNewAccounts(mBinding.allowNewEmailAccounts.isChecked()) .build()); } - if (mUseEmailLinkProvider.isChecked()) { + if (mBinding.emailLinkProvider.isChecked()) { ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder() .setAndroidPackageName("com.firebase.uidemo", true, null) .setHandleCodeInApp(true) @@ -429,37 +402,37 @@ private List getSelectedProviders() { .build(); selectedProviders.add(new IdpConfig.EmailBuilder() - .setAllowNewAccounts(mAllowNewEmailAccounts.isChecked()) + .setAllowNewAccounts(mBinding.allowNewEmailAccounts.isChecked()) .setActionCodeSettings(actionCodeSettings) .enableEmailLinkSignIn() .build()); } - if (mUsePhoneProvider.isChecked()) { + if (mBinding.phoneProvider.isChecked()) { selectedProviders.add(new IdpConfig.PhoneBuilder().build()); } - if (mUseAnonymousProvider.isChecked()) { + if (mBinding.anonymousProvider.isChecked()) { selectedProviders.add(new IdpConfig.AnonymousBuilder().build()); } - if (mUseTwitterProvider.isChecked()) { + if (mBinding.twitterProvider.isChecked()) { selectedProviders.add(new IdpConfig.TwitterBuilder().build()); } - if (mUseMicrosoftProvider.isChecked()) { + if (mBinding.microsoftProvider.isChecked()) { selectedProviders.add(new IdpConfig.MicrosoftBuilder().build()); } - if (mUseYahooProvider.isChecked()) { + if (mBinding.yahooProvider.isChecked()) { selectedProviders.add(new IdpConfig.YahooBuilder().build()); } - if (mUseAppleProvider.isChecked()) { + if (mBinding.appleProvider.isChecked()) { selectedProviders.add(new IdpConfig.AppleBuilder().build()); } - if (mUseGitHubProvider.isChecked()) { + if (mBinding.githubProvider.isChecked()) { selectedProviders.add(new IdpConfig.GitHubBuilder().build()); } @@ -468,11 +441,11 @@ private List getSelectedProviders() { @Nullable private String getSelectedTosUrl() { - if (mUseGoogleTosPp.isChecked()) { + if (mBinding.googleTosPrivacy.isChecked()) { return GOOGLE_TOS_URL; } - if (mUseFirebaseTosPp.isChecked()) { + if (mBinding.firebaseTosPrivacy.isChecked()) { return FIREBASE_TOS_URL; } @@ -481,11 +454,11 @@ private String getSelectedTosUrl() { @Nullable private String getSelectedPrivacyPolicyUrl() { - if (mUseGoogleTosPp.isChecked()) { + if (mBinding.googleTosPrivacy.isChecked()) { return GOOGLE_PRIVACY_POLICY_URL; } - if (mUseFirebaseTosPp.isChecked()) { + if (mBinding.firebaseTosPrivacy.isChecked()) { return FIREBASE_PRIVACY_POLICY_URL; } @@ -493,23 +466,23 @@ private String getSelectedPrivacyPolicyUrl() { } private void setGoogleScopesEnabled(boolean enabled) { - mGoogleScopesHeader.setEnabled(enabled); - mGoogleScopeDriveFile.setEnabled(enabled); - mGoogleScopeYoutubeData.setEnabled(enabled); + mBinding.googleScopesHeader.setEnabled(enabled); + mBinding.googleScopeDriveFile.setEnabled(enabled); + mBinding.googleScopeYoutubeData.setEnabled(enabled); } private void setFacebookPermissionsEnabled(boolean enabled) { - mFacebookPermissionsHeader.setEnabled(enabled); - mFacebookPermissionFriends.setEnabled(enabled); - mFacebookPermissionPhotos.setEnabled(enabled); + mBinding.facebookPermissionsHeader.setEnabled(enabled); + mBinding.facebookPermissionFriends.setEnabled(enabled); + mBinding.facebookPermissionPhotos.setEnabled(enabled); } private List getGoogleScopes() { List result = new ArrayList<>(); - if (mGoogleScopeYoutubeData.isChecked()) { + if (mBinding.googleScopeYoutubeData.isChecked()) { result.add("https://www.googleapis.com/auth/youtube.readonly"); } - if (mGoogleScopeDriveFile.isChecked()) { + if (mBinding.googleScopeDriveFile.isChecked()) { result.add(Scopes.DRIVE_FILE); } return result; @@ -517,16 +490,16 @@ private List getGoogleScopes() { private List getFacebookPermissions() { List result = new ArrayList<>(); - if (mFacebookPermissionFriends.isChecked()) { + if (mBinding.facebookPermissionFriends.isChecked()) { result.add("user_friends"); } - if (mFacebookPermissionPhotos.isChecked()) { + if (mBinding.facebookPermissionPhotos.isChecked()) { result.add("user_photos"); } return result; } private void showSnackbar(@StringRes int errorMessageRes) { - Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show(); + Snackbar.make(mBinding.getRoot(), errorMessageRes, Snackbar.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java b/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java index f666c849e..ac97462a1 100644 --- a/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java +++ b/app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java @@ -21,13 +21,13 @@ import android.text.TextUtils; import android.util.Log; import android.view.View; -import android.widget.ImageView; import android.widget.TextView; import com.firebase.ui.auth.AuthUI; import com.firebase.ui.auth.IdpResponse; import com.firebase.ui.auth.util.ExtraConstants; import com.firebase.uidemo.R; +import com.firebase.uidemo.databinding.SignedInLayoutBinding; import com.firebase.uidemo.storage.GlideApp; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; @@ -50,23 +50,13 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; import static com.firebase.ui.auth.AuthUI.EMAIL_LINK_PROVIDER; public class SignedInActivity extends AppCompatActivity { private static final String TAG = "SignedInActivity"; - @BindView(android.R.id.content) View mRootView; - - @BindView(R.id.user_profile_picture) ImageView mUserProfilePicture; - @BindView(R.id.user_email) TextView mUserEmail; - @BindView(R.id.user_display_name) TextView mUserDisplayName; - @BindView(R.id.user_phone_number) TextView mUserPhoneNumber; - @BindView(R.id.user_enabled_providers) TextView mEnabledProviders; - @BindView(R.id.user_is_new) TextView mIsNewUser; + private SignedInLayoutBinding mBinding; @NonNull public static Intent createIntent(@NonNull Context context, @Nullable IdpResponse response) { @@ -87,13 +77,26 @@ public void onCreate(@Nullable Bundle savedInstanceState) { IdpResponse response = getIntent().getParcelableExtra(ExtraConstants.IDP_RESPONSE); - setContentView(R.layout.signed_in_layout); - ButterKnife.bind(this); + mBinding = SignedInLayoutBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); populateProfile(response); populateIdpToken(response); + + mBinding.deleteAccount.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + deleteAccountClicked(); + } + }); + + mBinding.signOut.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + signOut(); + } + }); } - @OnClick(R.id.sign_out) public void signOut() { AuthUI.getInstance() .signOut(this) @@ -111,7 +114,6 @@ public void onComplete(@NonNull Task task) { }); } - @OnClick(R.id.delete_account) public void deleteAccountClicked() { new AlertDialog.Builder(this) .setMessage("Are you sure you want to delete this account?") @@ -147,21 +149,21 @@ private void populateProfile(@Nullable IdpResponse response) { GlideApp.with(this) .load(user.getPhotoUrl()) .fitCenter() - .into(mUserProfilePicture); + .into(mBinding.userProfilePicture); } - mUserEmail.setText( + mBinding.userEmail.setText( TextUtils.isEmpty(user.getEmail()) ? "No email" : user.getEmail()); - mUserPhoneNumber.setText( + mBinding.userPhoneNumber.setText( TextUtils.isEmpty(user.getPhoneNumber()) ? "No phone number" : user.getPhoneNumber()); - mUserDisplayName.setText( + mBinding.userDisplayName.setText( TextUtils.isEmpty(user.getDisplayName()) ? "No display name" : user.getDisplayName()); if (response == null) { - mIsNewUser.setVisibility(View.GONE); + mBinding.userIsNew.setVisibility(View.GONE); } else { - mIsNewUser.setVisibility(View.VISIBLE); - mIsNewUser.setText(response.isNewUser() ? "New user" : "Existing user"); + mBinding.userIsNew.setVisibility(View.VISIBLE); + mBinding.userIsNew.setText(response.isNewUser() ? "New user" : "Existing user"); } List providers = new ArrayList<>(); @@ -197,7 +199,7 @@ private void populateProfile(@Nullable IdpResponse response) { } } - mEnabledProviders.setText(getString(R.string.used_providers, providers)); + mBinding.userEnabledProviders.setText(getString(R.string.used_providers, providers)); } private void populateIdpToken(@Nullable IdpResponse response) { @@ -226,6 +228,6 @@ private void populateIdpToken(@Nullable IdpResponse response) { } private void showSnackbar(@StringRes int errorMessageRes) { - Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show(); + Snackbar.make(mBinding.getRoot(), errorMessageRes, Snackbar.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java b/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java index 650da275b..509257316 100644 --- a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java +++ b/app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java @@ -6,9 +6,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; import android.widget.Toast; import com.firebase.ui.auth.util.ui.ImeHelper; @@ -16,6 +13,7 @@ import com.firebase.ui.firestore.FirestoreRecyclerOptions; import com.firebase.uidemo.R; import com.firebase.uidemo.database.ChatHolder; +import com.firebase.uidemo.databinding.ActivityChatBinding; import com.firebase.uidemo.util.SignInResultNotifier; import com.google.android.gms.tasks.OnFailureListener; import com.google.firebase.auth.FirebaseAuth; @@ -28,9 +26,6 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; /** * Class demonstrating how to setup a {@link RecyclerView} with an adapter while taking sign-in @@ -55,52 +50,49 @@ public class FirestoreChatActivity extends AppCompatActivity FirebaseFirestore.setLoggingEnabled(true); } - @BindView(R.id.messagesList) - RecyclerView mRecyclerView; - - @BindView(R.id.sendButton) - Button mSendButton; - - @BindView(R.id.messageEdit) - EditText mMessageEdit; - - @BindView(R.id.emptyTextView) - TextView mEmptyListMessage; + private ActivityChatBinding mBinding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_chat); - ButterKnife.bind(this); + mBinding = ActivityChatBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); LinearLayoutManager manager = new LinearLayoutManager(this); manager.setReverseLayout(true); manager.setStackFromEnd(true); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(manager); + mBinding.messagesList.setHasFixedSize(true); + mBinding.messagesList.setLayoutManager(manager); - mRecyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + mBinding.messagesList.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { if (bottom < oldBottom) { - mRecyclerView.postDelayed(new Runnable() { + mBinding.messagesList.postDelayed(new Runnable() { @Override public void run() { - mRecyclerView.smoothScrollToPosition(0); + mBinding.messagesList.smoothScrollToPosition(0); } }, 100); } } }); - ImeHelper.setImeOnDoneListener(mMessageEdit, new ImeHelper.DonePressedListener() { + ImeHelper.setImeOnDoneListener(mBinding.messageEdit, new ImeHelper.DonePressedListener() { @Override public void onDonePressed() { onSendClick(); } }); + + mBinding.sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onSendClick(); + } + }); } @Override @@ -120,8 +112,8 @@ protected void onStop() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth auth) { - mSendButton.setEnabled(isSignedIn()); - mMessageEdit.setEnabled(isSignedIn()); + mBinding.sendButton.setEnabled(isSignedIn()); + mBinding.messageEdit.setEnabled(isSignedIn()); if (isSignedIn()) { attachRecyclerViewAdapter(); @@ -142,21 +134,20 @@ private void attachRecyclerViewAdapter() { adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override public void onItemRangeInserted(int positionStart, int itemCount) { - mRecyclerView.smoothScrollToPosition(0); + mBinding.messagesList.smoothScrollToPosition(0); } }); - mRecyclerView.setAdapter(adapter); + mBinding.messagesList.setAdapter(adapter); } - @OnClick(R.id.sendButton) public void onSendClick() { String uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); String name = "User " + uid.substring(0, 6); - onAddMessage(new Chat(name, mMessageEdit.getText().toString(), uid)); + onAddMessage(new Chat(name, mBinding.messageEdit.getText().toString(), uid)); - mMessageEdit.setText(""); + mBinding.messageEdit.setText(""); } @NonNull @@ -183,7 +174,7 @@ protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNu @Override public void onDataChanged() { // If there are no chat messages, show a view that invites the user to add a message. - mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); + mBinding.emptyTextView.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); } }; } diff --git a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java b/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java index 80725995f..ee8c41707 100644 --- a/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java +++ b/app/src/main/java/com/firebase/uidemo/database/firestore/FirestorePagingActivity.java @@ -14,6 +14,7 @@ import com.firebase.ui.firestore.paging.FirestorePagingOptions; import com.firebase.ui.firestore.paging.LoadingState; import com.firebase.uidemo.R; +import com.firebase.uidemo.databinding.ActivityFirestorePagingBinding; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.firestore.CollectionReference; @@ -30,18 +31,12 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import butterknife.BindView; -import butterknife.ButterKnife; public class FirestorePagingActivity extends AppCompatActivity { private static final String TAG = "FirestorePagingActivity"; - @BindView(R.id.paging_recycler) - RecyclerView mRecycler; - - @BindView(R.id.swipe_refresh_layout) - SwipeRefreshLayout mSwipeRefreshLayout; + private ActivityFirestorePagingBinding mBinding; private FirebaseFirestore mFirestore; private CollectionReference mItemsCollection; @@ -49,8 +44,8 @@ public class FirestorePagingActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_firestore_paging); - ButterKnife.bind(this); + mBinding = ActivityFirestorePagingBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); mFirestore = FirebaseFirestore.getInstance(); mItemsCollection = mFirestore.collection("items"); @@ -95,13 +90,13 @@ protected void onLoadingStateChanged(@NonNull LoadingState state) { switch (state) { case LOADING_INITIAL: case LOADING_MORE: - mSwipeRefreshLayout.setRefreshing(true); + mBinding.swipeRefreshLayout.setRefreshing(true); break; case LOADED: - mSwipeRefreshLayout.setRefreshing(false); + mBinding.swipeRefreshLayout.setRefreshing(false); break; case FINISHED: - mSwipeRefreshLayout.setRefreshing(false); + mBinding.swipeRefreshLayout.setRefreshing(false); showToast("Reached end of data set."); break; case ERROR: @@ -113,15 +108,15 @@ protected void onLoadingStateChanged(@NonNull LoadingState state) { @Override protected void onError(@NonNull Exception e) { - mSwipeRefreshLayout.setRefreshing(false); + mBinding.swipeRefreshLayout.setRefreshing(false); Log.e(TAG, e.getMessage(), e); } }; - mRecycler.setLayoutManager(new LinearLayoutManager(this)); - mRecycler.setAdapter(adapter); + mBinding.pagingRecycler.setLayoutManager(new LinearLayoutManager(this)); + mBinding.pagingRecycler.setAdapter(adapter); - mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + mBinding.swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { adapter.refresh(); @@ -191,16 +186,13 @@ public Item(@Nullable String text, int value) { } public static class ItemViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.item_text) TextView mTextView; - - @BindView(R.id.item_value) TextView mValueView; ItemViewHolder(@NonNull View itemView) { super(itemView); - ButterKnife.bind(this, itemView); + mTextView = itemView.findViewById(R.id.item_text); + mValueView = itemView.findViewById(R.id.item_value); } void bind(@NonNull Item item) { diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java b/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java index 6eef9fb2e..0201017cb 100644 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java +++ b/app/src/main/java/com/firebase/uidemo/database/realtime/FirebaseDbPagingActivity.java @@ -14,6 +14,7 @@ import com.firebase.ui.database.paging.FirebaseRecyclerPagingAdapter; import com.firebase.ui.database.paging.LoadingState; import com.firebase.uidemo.R; +import com.firebase.uidemo.databinding.ActivityDatabasePagingBinding; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.Query; @@ -27,18 +28,12 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import butterknife.BindView; -import butterknife.ButterKnife; public class FirebaseDbPagingActivity extends AppCompatActivity { private static final String TAG = "PagingActivity"; - @BindView(R.id.paging_recycler) - RecyclerView mRecycler; - - @BindView(R.id.swipe_refresh_layout) - SwipeRefreshLayout mSwipeRefreshLayout; + private ActivityDatabasePagingBinding mBinding; private FirebaseDatabase mDatabase; private Query mQuery; @@ -46,8 +41,8 @@ public class FirebaseDbPagingActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_database_paging); - ButterKnife.bind(this); + mBinding = ActivityDatabasePagingBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); mDatabase = FirebaseDatabase.getInstance(); mQuery = mDatabase.getReference().child("items"); @@ -94,13 +89,13 @@ protected void onLoadingStateChanged(@NonNull LoadingState state) { switch (state) { case LOADING_INITIAL: case LOADING_MORE: - mSwipeRefreshLayout.setRefreshing(true); + mBinding.swipeRefreshLayout.setRefreshing(true); break; case LOADED: - mSwipeRefreshLayout.setRefreshing(false); + mBinding.swipeRefreshLayout.setRefreshing(false); break; case FINISHED: - mSwipeRefreshLayout.setRefreshing(false); + mBinding.swipeRefreshLayout.setRefreshing(false); showToast(getString(R.string.paging_finished_message)); break; case ERROR: @@ -111,16 +106,16 @@ protected void onLoadingStateChanged(@NonNull LoadingState state) { @Override protected void onError(DatabaseError databaseError) { - mSwipeRefreshLayout.setRefreshing(false); + mBinding.swipeRefreshLayout.setRefreshing(false); Log.e(TAG, databaseError.getDetails(), databaseError.toException()); } }; - mRecycler.setLayoutManager(new LinearLayoutManager(this)); - mRecycler.setAdapter(mAdapter); + mBinding.pagingRecycler.setLayoutManager(new LinearLayoutManager(this)); + mBinding.pagingRecycler.setAdapter(mAdapter); // Reload data on swipe - mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + mBinding.swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { //Reload Data @@ -179,16 +174,13 @@ public Item(@Nullable String text, int value) { public static class ItemViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.item_text) TextView mTextView; - - @BindView(R.id.item_value) TextView mValueView; ItemViewHolder(@NonNull View itemView) { super(itemView); - ButterKnife.bind(this, itemView); + mTextView = itemView.findViewById(R.id.item_text); + mValueView = itemView.findViewById(R.id.item_value); } void bind(@NonNull Item item) { diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java b/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java index 9bba008bf..59948bc65 100644 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java +++ b/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatActivity.java @@ -6,9 +6,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; import android.widget.Toast; import com.firebase.ui.auth.util.ui.ImeHelper; @@ -16,6 +13,7 @@ import com.firebase.ui.database.FirebaseRecyclerOptions; import com.firebase.uidemo.R; import com.firebase.uidemo.database.ChatHolder; +import com.firebase.uidemo.databinding.ActivityChatBinding; import com.firebase.uidemo.util.SignInResultNotifier; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DatabaseError; @@ -28,9 +26,6 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; /** * Class demonstrating how to setup a {@link RecyclerView} with an adapter while taking sign-in @@ -52,33 +47,30 @@ public class RealtimeDbChatActivity extends AppCompatActivity protected final Query sChatQuery = FirebaseDatabase.getInstance().getReference().child("chats").limitToLast(50); - @BindView(R.id.messagesList) - RecyclerView mRecyclerView; - - @BindView(R.id.sendButton) - Button mSendButton; - - @BindView(R.id.messageEdit) - EditText mMessageEdit; - - @BindView(R.id.emptyTextView) - TextView mEmptyListMessage; + private ActivityChatBinding mBinding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_chat); - ButterKnife.bind(this); + mBinding = ActivityChatBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + mBinding.messagesList.setHasFixedSize(true); + mBinding.messagesList.setLayoutManager(new LinearLayoutManager(this)); - ImeHelper.setImeOnDoneListener(mMessageEdit, new ImeHelper.DonePressedListener() { + ImeHelper.setImeOnDoneListener(mBinding.messageEdit, new ImeHelper.DonePressedListener() { @Override public void onDonePressed() { onSendClick(); } }); + + mBinding.sendButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + onSendClick(); + } + }); } @Override @@ -98,8 +90,8 @@ protected void onStop() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth auth) { - mSendButton.setEnabled(isSignedIn()); - mMessageEdit.setEnabled(isSignedIn()); + mBinding.sendButton.setEnabled(isSignedIn()); + mBinding.messageEdit.setEnabled(isSignedIn()); if (isSignedIn()) { attachRecyclerViewAdapter(); @@ -120,21 +112,20 @@ private void attachRecyclerViewAdapter() { adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override public void onItemRangeInserted(int positionStart, int itemCount) { - mRecyclerView.smoothScrollToPosition(adapter.getItemCount()); + mBinding.messagesList.smoothScrollToPosition(adapter.getItemCount()); } }); - mRecyclerView.setAdapter(adapter); + mBinding.messagesList.setAdapter(adapter); } - @OnClick(R.id.sendButton) public void onSendClick() { String uid = FirebaseAuth.getInstance().getCurrentUser().getUid(); String name = "User " + uid.substring(0, 6); - onAddMessage(new Chat(name, mMessageEdit.getText().toString(), uid)); + onAddMessage(new Chat(name, mBinding.messageEdit.getText().toString(), uid)); - mMessageEdit.setText(""); + mBinding.messageEdit.setText(""); } @NonNull @@ -160,7 +151,7 @@ protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNu @Override public void onDataChanged() { // If there are no chat messages, show a view that invites the user to add a message. - mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); + mBinding.emptyTextView.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); } }; } diff --git a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java b/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java index 2956781dd..c55b2cd24 100644 --- a/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java +++ b/app/src/main/java/com/firebase/uidemo/database/realtime/RealtimeDbChatIndexActivity.java @@ -48,7 +48,7 @@ protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNu @Override public void onDataChanged() { // If there are no chat messages, show a view that invites the user to add a message. - mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); + findViewById(R.id.emptyTextView).setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE); } }; } diff --git a/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java b/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java index 4ca88d93c..add52b665 100644 --- a/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java +++ b/app/src/main/java/com/firebase/uidemo/storage/ImageActivity.java @@ -7,13 +7,12 @@ import android.provider.MediaStore; import android.util.Log; import android.view.View; -import android.widget.Button; -import android.widget.ImageView; import android.widget.Toast; import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; import com.firebase.uidemo.BuildConfig; import com.firebase.uidemo.R; +import com.firebase.uidemo.databinding.ActivityImageBinding; import com.firebase.uidemo.util.SignInResultNotifier; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; @@ -29,9 +28,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; import pub.devrel.easypermissions.AfterPermissionGranted; import pub.devrel.easypermissions.AppSettingsDialog; import pub.devrel.easypermissions.EasyPermissions; @@ -45,20 +41,33 @@ public class ImageActivity extends AppCompatActivity implements EasyPermissions. private StorageReference mImageRef; - @BindView(R.id.button_choose_photo) - Button mUploadButton; - - @BindView(R.id.button_download_direct) - Button mDownloadDirectButton; - - @BindView(R.id.first_image) - ImageView mImageView; + private ActivityImageBinding mBinding; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_image); - ButterKnife.bind(this); + mBinding = ActivityImageBinding.inflate(getLayoutInflater()); + setContentView(mBinding.getRoot()); + + mBinding.buttonDownloadDirect.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + // Download directly from StorageReference using Glide + // (See MyAppGlideModule for Loader registration) + GlideApp.with(ImageActivity.this) + .load(mImageRef) + .centerCrop() + .transition(DrawableTransitionOptions.withCrossFade()) + .into(mBinding.firstImage); + } + }); + + mBinding.buttonChoosePhoto.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + choosePhoto(); + } + }); // By default, Cloud Storage files require authentication to read or write. // For this sample to function correctly, enable Anonymous Auth in the Firebase console: @@ -85,7 +94,6 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d } } - @OnClick(R.id.button_choose_photo) @AfterPermissionGranted(RC_IMAGE_PERMS) protected void choosePhoto() { if (!EasyPermissions.hasPermissions(this, PERMS)) { @@ -130,28 +138,17 @@ public void onFailure(@NonNull Exception e) { }); } - @OnClick(R.id.button_download_direct) - protected void downloadDirect() { - // Download directly from StorageReference using Glide - // (See MyAppGlideModule for Loader registration) - GlideApp.with(this) - .load(mImageRef) - .centerCrop() - .transition(DrawableTransitionOptions.withCrossFade()) - .into(mImageView); - } - private void hideDownloadUI() { - mDownloadDirectButton.setEnabled(false); + mBinding.buttonDownloadDirect.setEnabled(false); - mImageView.setImageResource(0); - mImageView.setVisibility(View.INVISIBLE); + mBinding.firstImage.setImageResource(0); + mBinding.firstImage.setVisibility(View.INVISIBLE); } private void showDownloadUI() { - mDownloadDirectButton.setEnabled(true); + mBinding.buttonDownloadDirect.setEnabled(true); - mImageView.setVisibility(View.VISIBLE); + mBinding.firstImage.setVisibility(View.VISIBLE); } @Override diff --git a/auth/build.gradle.kts b/auth/build.gradle.kts index 26d2abc99..b321d7138 100644 --- a/auth/build.gradle.kts +++ b/auth/build.gradle.kts @@ -29,7 +29,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/auth/src/main/java/com/firebase/ui/auth/viewmodel/AuthViewModelBase.java b/auth/src/main/java/com/firebase/ui/auth/viewmodel/AuthViewModelBase.java index 772e64920..8169e5781 100644 --- a/auth/src/main/java/com/firebase/ui/auth/viewmodel/AuthViewModelBase.java +++ b/auth/src/main/java/com/firebase/ui/auth/viewmodel/AuthViewModelBase.java @@ -2,7 +2,6 @@ import android.app.Application; -import com.firebase.ui.auth.AuthUI; import com.firebase.ui.auth.data.model.FlowParameters; import com.firebase.ui.auth.data.model.Resource; import com.firebase.ui.auth.util.GoogleApiUtils; @@ -28,7 +27,6 @@ protected AuthViewModelBase(Application application) { protected void onCreate() { FirebaseApp app = FirebaseApp.getInstance(getArguments().appName); mAuth = FirebaseAuth.getInstance(app); - mCredentialsClient = GoogleApiUtils.getCredentialsClient(getApplication()); } diff --git a/buildSrc/src/main/kotlin/Config.kt b/buildSrc/src/main/kotlin/Config.kt index 267c290e4..84acc60e3 100644 --- a/buildSrc/src/main/kotlin/Config.kt +++ b/buildSrc/src/main/kotlin/Config.kt @@ -60,7 +60,6 @@ object Config { object Misc { private const val leakCanaryVersion = "1.6.1" private const val glideVersion = "4.11.0" - private const val butterVersion = "10.1.0" const val leakCanary = "com.squareup.leakcanary:leakcanary-android:$leakCanaryVersion" const val leakCanaryFragments = @@ -71,9 +70,6 @@ object Config { const val glide = "com.github.bumptech.glide:glide:$glideVersion" const val glideCompiler = "com.github.bumptech.glide:compiler:$glideVersion" - const val butterKnife = "com.jakewharton:butterknife:$butterVersion" - const val butterKnifeCompiler = "com.jakewharton:butterknife-compiler:$butterVersion" - const val permissions = "pub.devrel:easypermissions:3.0.0" const val materialProgress = "me.zhanghai.android.materialprogressbar:library:1.6.1" } diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 05a07c10f..787b14bc1 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -20,7 +20,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/database/build.gradle.kts b/database/build.gradle.kts index ce8fc29cb..0219606d6 100644 --- a/database/build.gradle.kts +++ b/database/build.gradle.kts @@ -22,7 +22,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/firestore/build.gradle.kts b/firestore/build.gradle.kts index 212f0fa92..8cfe2dbcb 100644 --- a/firestore/build.gradle.kts +++ b/firestore/build.gradle.kts @@ -23,7 +23,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/internal/lintchecks/build.gradle.kts b/internal/lintchecks/build.gradle.kts index cd801ced8..694439c68 100644 --- a/internal/lintchecks/build.gradle.kts +++ b/internal/lintchecks/build.gradle.kts @@ -21,7 +21,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 79705f5b9..da4271088 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -20,7 +20,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/proguard-tests/build.gradle.kts b/proguard-tests/build.gradle.kts index b1f3b41e8..3f2844ddd 100644 --- a/proguard-tests/build.gradle.kts +++ b/proguard-tests/build.gradle.kts @@ -43,7 +43,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds diff --git a/storage/build.gradle.kts b/storage/build.gradle.kts index abadf84b4..4d90cb61a 100644 --- a/storage/build.gradle.kts +++ b/storage/build.gradle.kts @@ -20,7 +20,6 @@ android { lintOptions { // Common lint options across all modules disable( - "ObsoleteLintCustomCheck", // ButterKnife will fix this in v9.0 "IconExpectedSize", "InvalidPackage", // Firestore uses GRPC which makes lint mad "NewerVersionAvailable", "GradleDependency", // For reproducible builds