Java DataIndig向布局返回错误的onFocusChangeListener
我有一个登录表单验证机制。电子邮件和密码有两个文本输入,都附加到各自的onFocusChangeListeners,使用数据绑定来设置它们,但数据绑定返回错误的侦听器 表格如下:Java DataIndig向布局返回错误的onFocusChangeListener,java,android,data-binding,android-databinding,Java,Android,Data Binding,Android Databinding,我有一个登录表单验证机制。电子邮件和密码有两个文本输入,都附加到各自的onFocusChangeListeners,使用数据绑定来设置它们,但数据绑定返回错误的侦听器 表格如下: <?xml version="1.0" encoding="utf-8"?> <layout> <data> <variable name="loginViewModel"
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="loginViewModel"
type="com.example.increaseyouriq.ui.forms.LoginFormViewModel" />
</data>
<LinearLayout
android:id="@+id/ll_login"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/parent.contentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="26dp">
<com.google.android.material.card.MaterialCardView
style="@style/cardOutline"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
style="@style/viewParent.headerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/login_title" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
style="@style/textInputStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/enter_email"
error="@{loginViewModel.loginForm.emailError}"
app:errorEnabled="@{loginViewModel.loginForm.isEmailError()}"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_login_email"
style="@style/textInputEditext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
onFocus="@{loginViewModel.onFocusEmailChangeListener}"
android:text="@={loginViewModel.loginFields.email}"
android:inputType="textNoSuggestions|textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/textInputStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/enter_password"
error="@{loginViewModel.loginForm.passwordError}"
app:errorEnabled="@{loginViewModel.loginForm.isPasswordError()}"
app:endIconMode="password_toggle">
<com.google.android.material.textfield.TextInputEditText
style="@style/textInputEditext"
android:id="@+id/et_login_password"
onFocus="@{loginViewModel.onFocusPasswordChangeListener}"
android:text="@={loginViewModel.loginFields.password}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</layout>
这是我的LoginActivity.java:
public class LoginFormViewModel extends ViewModel {
private static final String LOG_TAG = "LoginFormViewModel";
private View.OnFocusChangeListener onFocusEmail;
private View.OnFocusChangeListener onFocusPassword;
public void init() {
loginForm = new LoginForm();
onFocusPassword = (v, hasFocus) -> {
TextInputEditText et = (TextInputEditText) v;
MyUtilsApp.showLog(LOG_TAG,
String.format("%s password listener attached to :%d", String.valueOf(et.getText()), et.getId()));
if (et.getText().length() > 0 && !hasFocus) {
loginForm.isPasswordValid(true);
}
};
onFocusEmail = (v, hasFocus) -> {
TextInputEditText et = (TextInputEditText) v;
MyUtilsApp.showLog(LOG_TAG, "email listener attached");
if (et.getText().length() > 0 && !hasFocus) {
loginForm.isEmailValid(true);
}
};
}
public View.OnFocusChangeListener getOnFocusEmailChangeListener() {
return onFocusEmail;
}
public View.OnFocusChangeListener getOnFocusPasswordChangeListener() {
return onFocusPassword;
}
@BindingAdapter("onFocus")
public static void bindFocusChange(TextInputEditText editText, View.OnFocusChangeListener onFocusChangeListener) {
if (editText.getOnFocusChangeListener() == null) {
editText.setOnFocusChangeListener(onFocusChangeListener);
}
}
}
public class LoginActivity extends AppCompatActivity {
private static final String LOG_TAG = "LoginActivity";
ActivityLoginBinding binding;
private LoginRegisterViewModel loginRegisterViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,R.layout.activity_login);
setupBindings(savedInstanceState);
}
private void setupBindings(Bundle savedInstanceState) {
LoginFormViewModel loginFormViewModel = new ViewModelProvider(this).get(LoginFormViewModel.class);
if(savedInstanceState==null)
loginFormViewModel.init();
binding.setLoginViewModel(loginFormViewModel);
binding.setLifecycleOwner(this);
loginFormViewModel.getLoginFields().observe(this, loginFields -> {
Toast.makeText(LoginActivity.this,
"Email " + loginFields.getEmail() + ", Password " + loginFields.getPassword(),
Toast.LENGTH_SHORT).show();
});
binding.inLayoutLogin.btnLoginLogin.setOnClickListener(view -> {
binding.executePendingBindings();
loginFormViewModel.getLoginForm().onClick();
});
}
}
很明显,我已经将两个侦听器都设置为onFocusEmail类型,这只是因为onFocusPassword在运行时被附加到两个TextInputItems。
以下是日志:
com.example.increaseyouriq E/LoginFormViewModel: password listener attached to :2131296499
com.example.increaseyouriq E/LoginFormViewModel: ttf password listener attached to :2131296499
onFocusEmail在任何地方都看不到,它已在运行时附加。
有关代码的更多详细信息,请参见我对您的代码进行了一些实验,我相信我已经找到了根本原因 问题: 您的两个侦听器都没有附加到您的电子邮件字段(textinputtext“et_login_email”) 原因: 原因是这里有一个空检查
@BindingAdapter("onFocus")
public static void bindFocusChange(TextInputEditText editText, View.OnFocusChangeListener onFocusChangeListener) {
if (editText.getOnFocusChangeListener() == null) {
editText.setOnFocusChangeListener(onFocusChangeListener);
}
}
并且您的电子邮件字段已经有一个onFocusChangeListener,它是由属性设置的
<com.google.android.material.textfield.TextInputLayout
...
android:hint="@string/enter_email"
..."
app:endIconMode="clear_text">