Skip to content

Commit 861d2b9

Browse files
authored
Removed butterknife from login activity (#5380)
* Removed butterknife view bindings * Migrated click listeners to view binding * Migrate onEditorAction to use ViewBinding * Finally, removed butterknife
1 parent 9620f6e commit 861d2b9

File tree

2 files changed

+56
-110
lines changed

2 files changed

+56
-110
lines changed

app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java

+52-79
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414
import android.view.View;
1515
import android.view.ViewGroup;
1616
import android.view.inputmethod.InputMethodManager;
17-
import android.widget.Button;
18-
import android.widget.EditText;
19-
import android.widget.TextView;
2017

18+
import android.widget.TextView;
2119
import androidx.annotation.ColorRes;
2220
import androidx.annotation.NonNull;
2321
import androidx.annotation.Nullable;
@@ -27,8 +25,7 @@
2725
import androidx.core.app.NavUtils;
2826
import androidx.core.content.ContextCompat;
2927

30-
import com.google.android.material.textfield.TextInputLayout;
31-
28+
import fr.free.nrw.commons.databinding.ActivityLoginBinding;
3229
import fr.free.nrw.commons.utils.ActivityUtils;
3330
import java.util.Locale;
3431
import org.wikipedia.AppAdapter;
@@ -42,15 +39,9 @@
4239
import javax.inject.Inject;
4340
import javax.inject.Named;
4441

45-
import butterknife.BindView;
46-
import butterknife.ButterKnife;
47-
import butterknife.OnClick;
48-
import butterknife.OnEditorAction;
49-
import butterknife.OnFocusChange;
5042
import fr.free.nrw.commons.BuildConfig;
5143
import fr.free.nrw.commons.R;
5244
import fr.free.nrw.commons.Utils;
53-
import fr.free.nrw.commons.WelcomeActivity;
5445
import fr.free.nrw.commons.contributions.MainActivity;
5546
import fr.free.nrw.commons.di.ApplicationlessInjection;
5647
import fr.free.nrw.commons.kvstore.JsonKvStore;
@@ -87,30 +78,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
8778
@Inject
8879
SystemThemeUtils systemThemeUtils;
8980

90-
@BindView(R.id.login_button)
91-
Button loginButton;
92-
93-
@BindView(R.id.login_username)
94-
EditText usernameEdit;
95-
96-
@BindView(R.id.login_password)
97-
EditText passwordEdit;
98-
99-
@BindView(R.id.login_two_factor)
100-
EditText twoFactorEdit;
101-
102-
@BindView(R.id.error_message_container)
103-
ViewGroup errorMessageContainer;
104-
105-
@BindView(R.id.error_message)
106-
TextView errorMessage;
107-
108-
@BindView(R.id.login_credentials)
109-
TextView loginCredentials;
110-
111-
@BindView(R.id.two_factor_container)
112-
TextInputLayout twoFactorContainer;
113-
81+
private ActivityLoginBinding binding;
11482
ProgressDialog progressDialog;
11583
private AppCompatDelegate delegate;
11684
private LoginTextWatcher textWatcher = new LoginTextWatcher();
@@ -120,6 +88,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
12088
final String saveErrorMessage ="errorMessage";
12189
final String saveUsername="username";
12290
final String savePassword="password";
91+
12392
@Override
12493
public void onCreate(Bundle savedInstanceState) {
12594
super.onCreate(savedInstanceState);
@@ -133,35 +102,41 @@ public void onCreate(Bundle savedInstanceState) {
133102
getDelegate().installViewFactory();
134103
getDelegate().onCreate(savedInstanceState);
135104

136-
setContentView(R.layout.activity_login);
105+
binding = ActivityLoginBinding.inflate(getLayoutInflater());
106+
setContentView(binding.getRoot());
107+
108+
binding.loginUsername.addTextChangedListener(textWatcher);
109+
binding.loginPassword.addTextChangedListener(textWatcher);
110+
binding.loginTwoFactor.addTextChangedListener(textWatcher);
137111

138-
ButterKnife.bind(this);
112+
binding.skipLogin.setOnClickListener(view -> skipLogin());
113+
binding.forgotPassword.setOnClickListener(view -> forgotPassword());
114+
binding.aboutPrivacyPolicy.setOnClickListener(view -> onPrivacyPolicyClicked());
115+
binding.signUpButton.setOnClickListener(view -> signUp());
116+
binding.loginButton.setOnClickListener(view -> performLogin());
139117

140-
usernameEdit.addTextChangedListener(textWatcher);
141-
passwordEdit.addTextChangedListener(textWatcher);
142-
twoFactorEdit.addTextChangedListener(textWatcher);
118+
binding.loginPassword.setOnEditorActionListener(this::onEditorAction);
119+
binding.loginPassword.setOnFocusChangeListener(this::onPasswordFocusChanged);
143120

144121
if (ConfigUtils.isBetaFlavour()) {
145-
loginCredentials.setText(getString(R.string.login_credential));
122+
binding.loginCredentials.setText(getString(R.string.login_credential));
146123
} else {
147-
loginCredentials.setVisibility(View.GONE);
124+
binding.loginCredentials.setVisibility(View.GONE);
148125
}
149126
}
150127
/**
151128
* Hides the keyboard if the user's focus is not on the password (hasFocus is false).
152129
* @param view The keyboard
153130
* @param hasFocus Set to true if the keyboard has focus
154131
*/
155-
@OnFocusChange(R.id.login_password)
156132
void onPasswordFocusChanged(View view, boolean hasFocus) {
157133
if (!hasFocus) {
158134
ViewUtil.hideKeyboard(view);
159135
}
160136
}
161137

162-
@OnEditorAction(R.id.login_password)
163-
boolean onEditorAction(int actionId, KeyEvent keyEvent) {
164-
if (loginButton.isEnabled()) {
138+
boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
139+
if (binding.loginButton.isEnabled()) {
165140
if (actionId == IME_ACTION_DONE) {
166141
performLogin();
167142
return true;
@@ -174,8 +149,7 @@ boolean onEditorAction(int actionId, KeyEvent keyEvent) {
174149
}
175150

176151

177-
@OnClick(R.id.skip_login)
178-
void skipLogin() {
152+
protected void skipLogin() {
179153
new AlertDialog.Builder(this).setTitle(R.string.skip_login_title)
180154
.setMessage(R.string.skip_login_message)
181155
.setCancelable(false)
@@ -187,18 +161,15 @@ void skipLogin() {
187161
.show();
188162
}
189163

190-
@OnClick(R.id.forgot_password)
191-
void forgotPassword() {
164+
protected void forgotPassword() {
192165
Utils.handleWebUrl(this, Uri.parse(BuildConfig.FORGOT_PASSWORD_URL));
193166
}
194167

195-
@OnClick(R.id.about_privacy_policy)
196-
void onPrivacyPolicyClicked() {
168+
protected void onPrivacyPolicyClicked() {
197169
Utils.handleWebUrl(this, Uri.parse(BuildConfig.PRIVACY_POLICY_URL));
198170
}
199171

200-
@OnClick(R.id.sign_up_button)
201-
void signUp() {
172+
protected void signUp() {
202173
Intent intent = new Intent(this, SignupActivity.class);
203174
startActivity(intent);
204175
}
@@ -236,23 +207,23 @@ protected void onDestroy() {
236207
} catch (Exception e) {
237208
e.printStackTrace();
238209
}
239-
usernameEdit.removeTextChangedListener(textWatcher);
240-
passwordEdit.removeTextChangedListener(textWatcher);
241-
twoFactorEdit.removeTextChangedListener(textWatcher);
210+
binding.loginUsername.removeTextChangedListener(textWatcher);
211+
binding.loginPassword.removeTextChangedListener(textWatcher);
212+
binding.loginTwoFactor.removeTextChangedListener(textWatcher);
242213
delegate.onDestroy();
243214
if(null!=loginClient) {
244215
loginClient.cancel();
245216
}
217+
binding = null;
246218
super.onDestroy();
247219
}
248220

249-
@OnClick(R.id.login_button)
250221
public void performLogin() {
251222
Timber.d("Login to start!");
252-
final String username = usernameEdit.getText().toString();
253-
final String rawUsername = usernameEdit.getText().toString().trim();
254-
final String password = passwordEdit.getText().toString();
255-
String twoFactorCode = twoFactorEdit.getText().toString();
223+
final String username = binding.loginUsername.getText().toString();
224+
final String rawUsername = binding.loginUsername.getText().toString().trim();
225+
final String password = binding.loginPassword.getText().toString();
226+
String twoFactorCode = binding.loginTwoFactor.getText().toString();
256227

257228
showLoggingProgressBar();
258229
doLogin(username, password, twoFactorCode);
@@ -389,9 +360,9 @@ public MenuInflater getMenuInflater() {
389360

390361
public void askUserForTwoFactorAuth() {
391362
progressDialog.dismiss();
392-
twoFactorContainer.setVisibility(VISIBLE);
393-
twoFactorEdit.setVisibility(VISIBLE);
394-
twoFactorEdit.requestFocus();
363+
binding.twoFactorContainer.setVisibility(VISIBLE);
364+
binding.loginTwoFactor.setVisibility(VISIBLE);
365+
binding.loginTwoFactor.requestFocus();
395366
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
396367
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
397368
showMessageAndCancelDialog(R.string.login_failed_2fa_needed);
@@ -422,15 +393,15 @@ public void startMainActivity() {
422393
}
423394

424395
private void showMessage(@StringRes int resId, @ColorRes int colorResId) {
425-
errorMessage.setText(getString(resId));
426-
errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
427-
errorMessageContainer.setVisibility(VISIBLE);
396+
binding.errorMessage.setText(getString(resId));
397+
binding.errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
398+
binding.errorMessageContainer.setVisibility(VISIBLE);
428399
}
429400

430401
private void showMessage(String message, @ColorRes int colorResId) {
431-
errorMessage.setText(message);
432-
errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
433-
errorMessageContainer.setVisibility(VISIBLE);
402+
binding.errorMessage.setText(message);
403+
binding.errorMessage.setTextColor(ContextCompat.getColor(this, colorResId));
404+
binding.errorMessageContainer.setVisibility(VISIBLE);
434405
}
435406

436407
private AppCompatDelegate getDelegate() {
@@ -451,9 +422,11 @@ public void onTextChanged(CharSequence charSequence, int start, int count, int a
451422

452423
@Override
453424
public void afterTextChanged(Editable editable) {
454-
boolean enabled = usernameEdit.getText().length() != 0 && passwordEdit.getText().length() != 0
455-
&& (BuildConfig.DEBUG || twoFactorEdit.getText().length() != 0 || twoFactorEdit.getVisibility() != VISIBLE);
456-
loginButton.setEnabled(enabled);
425+
boolean enabled = binding.loginUsername.getText().length() != 0 &&
426+
binding.loginPassword.getText().length() != 0 &&
427+
(BuildConfig.DEBUG || binding.loginTwoFactor.getText().length() != 0 ||
428+
binding.loginTwoFactor.getVisibility() != VISIBLE);
429+
binding.loginButton.setEnabled(enabled);
457430
}
458431
}
459432

@@ -471,22 +444,22 @@ protected void onSaveInstanceState(Bundle outState) {
471444
} else {
472445
outState.putBoolean(saveProgressDailog,false);
473446
}
474-
outState.putString(saveErrorMessage,errorMessage.getText().toString()); //Save the errorMessage
447+
outState.putString(saveErrorMessage,binding.errorMessage.getText().toString()); //Save the errorMessage
475448
outState.putString(saveUsername,getUsername()); // Save the username
476449
outState.putString(savePassword,getPassword()); // Save the password
477450
}
478451
private String getUsername() {
479-
return usernameEdit.getText().toString();
452+
return binding.loginUsername.getText().toString();
480453
}
481454
private String getPassword(){
482-
return passwordEdit.getText().toString();
455+
return binding.loginPassword.getText().toString();
483456
}
484457

485458
@Override
486459
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
487460
super.onRestoreInstanceState(savedInstanceState);
488-
usernameEdit.setText(savedInstanceState.getString(saveUsername));
489-
passwordEdit.setText(savedInstanceState.getString(savePassword));
461+
binding.loginUsername.setText(savedInstanceState.getString(saveUsername));
462+
binding.loginPassword.setText(savedInstanceState.getString(savePassword));
490463
if(savedInstanceState.getBoolean(saveProgressDailog)) {
491464
performLogin();
492465
}

app/src/test/kotlin/fr/free/nrw/commons/auth/LoginActivityUnitTests.kt

+4-31
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import android.view.View
1010
import android.view.ViewGroup
1111
import android.view.inputmethod.EditorInfo
1212
import android.widget.Button
13+
import android.widget.TextView
1314
import androidx.test.core.app.ApplicationProvider
1415
import fr.free.nrw.commons.R
1516
import fr.free.nrw.commons.TestAppAdapter
@@ -55,7 +56,7 @@ class LoginActivityUnitTests {
5556
private lateinit var keyEvent: KeyEvent
5657

5758
@Mock
58-
private lateinit var loginButton: Button
59+
private lateinit var textView: TextView
5960

6061
@Mock
6162
private lateinit var bundle: Bundle
@@ -95,40 +96,12 @@ class LoginActivityUnitTests {
9596
fun testOnEditorActionCaseDefault() {
9697
val method: Method = LoginActivity::class.java.getDeclaredMethod(
9798
"onEditorAction",
99+
TextView::class.java,
98100
Int::class.java,
99101
KeyEvent::class.java
100102
)
101103
method.isAccessible = true
102-
method.invoke(activity, 0, keyEvent)
103-
}
104-
105-
@Test
106-
@Throws(Exception::class)
107-
fun testOnEditorActionCaseLoginEnabledFirstCase() {
108-
Whitebox.setInternalState(activity, "loginButton", loginButton)
109-
`when`(loginButton.isEnabled).thenReturn(true)
110-
val method: Method = LoginActivity::class.java.getDeclaredMethod(
111-
"onEditorAction",
112-
Int::class.java,
113-
KeyEvent::class.java
114-
)
115-
method.isAccessible = true
116-
method.invoke(activity, EditorInfo.IME_ACTION_DONE, keyEvent)
117-
}
118-
119-
@Test
120-
@Throws(Exception::class)
121-
fun testOnEditorActionCaseLoginEnabledSecondCase() {
122-
Whitebox.setInternalState(activity, "loginButton", loginButton)
123-
`when`(loginButton.isEnabled).thenReturn(true)
124-
`when`(keyEvent.keyCode).thenReturn(KeyEvent.KEYCODE_ENTER)
125-
val method: Method = LoginActivity::class.java.getDeclaredMethod(
126-
"onEditorAction",
127-
Int::class.java,
128-
KeyEvent::class.java
129-
)
130-
method.isAccessible = true
131-
method.invoke(activity, 0, keyEvent)
104+
method.invoke(activity, textView, 0, keyEvent)
132105
}
133106

134107
@Test

0 commit comments

Comments
 (0)