为什么数据绑定没有给出适当的异常?
Why does Databinding is not giving proper exception?
error: package ViewModel does not exist
public abstract void setLoginViewModel(@Nullable ViewModel.LoginViewModel LoginViewModel);
error no: ActivityMainBinding.java16号显示错误。 "import com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel;"
行
如何在使用 DataBindings 时解决上述异常?
我尝试了什么:
- 使缓存无效/重新启动
- 重新检查 XML 个属性
- 重命名小写包名
- --debug --stacktrace 使用 gradle
构建
没有任何效果。 google、Whosebug 和 Youtube 上没有其他解决方案有效。
package com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel;
MainActivity:
import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.Model.LoginUser;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.R;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.databinding.ActivityMainBinding;
import java.util.Objects;
public class MainActivity extends AppCompatActivity implements Observer<LoginUser> {
private LoginViewModel loginViewModel;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loginViewModel = ViewModelProviders.of(MainActivity.this).get(LoginViewModel.class);
// Inflate view and obtain an instance of the binding class.
binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main);
// Specify the current activity as the lifecycle owner.
binding.setLifecycleOwner(this);
binding.setLoginViewModel(loginViewModel);
loginViewModel.getUser().observe(MainActivity.this, this);
}
@Override
public void onChanged(@Nullable LoginUser loginUser) {
if (TextUtils.isEmpty(Objects.requireNonNull(loginUser).getEmail())) {
binding.emailId.setError("Email Id can't be blank");
binding.emailId.requestFocus();
} else if (!loginUser.isEmailValid()) {
binding.emailId.setError("Please enter valid Email Id");
binding.emailId.requestFocus();
} else if (TextUtils.isEmpty(Objects.requireNonNull(loginUser).getPassword())) {
binding.password.setError("Password can't be blank");
binding.password.requestFocus();
} else if (!loginUser.isPasswordLengthGreaterThan5()) {
binding.password.setError("Password length must be at least 8 digit");
binding.password.requestFocus();
} else {
binding.fetchEmailId.setText(loginUser.getEmail());
binding.fetchPassword.setText(loginUser.getPassword());
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="LoginViewModel"
type="com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".View.MainActivity">
<TextView
android:id="@+id/heading"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:lineSpacingExtra="8sp"
android:text="Login Example Using MVVM, DataBinding with LiveData"
android:textAlignment="center"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/email_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:ems="10"
android:hint="E-Mail Address"
android:inputType="textEmailAddress"
android:text="@={LoginViewModel.email}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/heading" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:text="@={LoginViewModel.password}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/email_id" />
<Button
android:id="@+id/login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:onClick="@{(v) -> LoginViewModel.onClick(v)}"
android:text="Click to Login"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password" />
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="8dp"
android:gravity="center"
android:text="See the Results Below From LiveDataBinding"
android:textColor="@android:color/background_dark"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/login" />
<TextView
android:id="@+id/fetch_email_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="---"
android:textColor="@android:color/holo_blue_light"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/result" />
<TextView
android:id="@+id/fetch_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
android:text="---"
android:textColor="@android:color/holo_blue_light"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fetch_email_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
登录视图模型:
package com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel;
import android.view.View;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.Model.LoginUser;
public class LoginViewModel extends ViewModel {
public MutableLiveData<String> email = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
private MutableLiveData<LoginUser> userMutableLiveData;
public MutableLiveData<LoginUser> getUser() {
if (userMutableLiveData == null) {
userMutableLiveData = new MutableLiveData<>();
}
return userMutableLiveData;
}
public void onClick(View view) {
LoginUser loginUser = new LoginUser(email.getValue(), password.getValue());
userMutableLiveData.setValue(loginUser);
}
}
注意:
我会像这个视图模型一样将包名改为小写字母,它会给 ActivityMainImpl 带来错误,这不是我生成的
您收到此错误是因为您在 XML 文件中用大写字母定义了程序包名称。
<variable
name="LoginViewModel"
type="com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel" />
应该是com.jimmytrivedi.learning.mvvmloginsignupdemo.viewmodel.LoginViewModel
。 viewmodel
加上小写字母,还要确保你的包名是 viewmodel
。
问题出在这里type="com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel"
任何父包都必须以 lowercase
开头,但在您的情况下 package name
在 Uppercase
中
因此将您的 ViewModel
重命名为 viewmodel
你的 type
应该是这样的
type="com.jimmytrivedi.learning.mvvmloginsignupdemo.viewmodel.LoginViewModel"
error: package ViewModel does not exist
public abstract void setLoginViewModel(@Nullable ViewModel.LoginViewModel LoginViewModel);
error no: ActivityMainBinding.java16号显示错误。 "import com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel;"
行如何在使用 DataBindings 时解决上述异常?
我尝试了什么:
- 使缓存无效/重新启动
- 重新检查 XML 个属性
- 重命名小写包名
- --debug --stacktrace 使用 gradle 构建
没有任何效果。 google、Whosebug 和 Youtube 上没有其他解决方案有效。
package com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel;
MainActivity:
import android.os.Bundle;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.Model.LoginUser;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.R;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.databinding.ActivityMainBinding;
import java.util.Objects;
public class MainActivity extends AppCompatActivity implements Observer<LoginUser> {
private LoginViewModel loginViewModel;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loginViewModel = ViewModelProviders.of(MainActivity.this).get(LoginViewModel.class);
// Inflate view and obtain an instance of the binding class.
binding = DataBindingUtil.setContentView(MainActivity.this, R.layout.activity_main);
// Specify the current activity as the lifecycle owner.
binding.setLifecycleOwner(this);
binding.setLoginViewModel(loginViewModel);
loginViewModel.getUser().observe(MainActivity.this, this);
}
@Override
public void onChanged(@Nullable LoginUser loginUser) {
if (TextUtils.isEmpty(Objects.requireNonNull(loginUser).getEmail())) {
binding.emailId.setError("Email Id can't be blank");
binding.emailId.requestFocus();
} else if (!loginUser.isEmailValid()) {
binding.emailId.setError("Please enter valid Email Id");
binding.emailId.requestFocus();
} else if (TextUtils.isEmpty(Objects.requireNonNull(loginUser).getPassword())) {
binding.password.setError("Password can't be blank");
binding.password.requestFocus();
} else if (!loginUser.isPasswordLengthGreaterThan5()) {
binding.password.setError("Password length must be at least 8 digit");
binding.password.requestFocus();
} else {
binding.fetchEmailId.setText(loginUser.getEmail());
binding.fetchPassword.setText(loginUser.getPassword());
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="LoginViewModel"
type="com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".View.MainActivity">
<TextView
android:id="@+id/heading"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:lineSpacingExtra="8sp"
android:text="Login Example Using MVVM, DataBinding with LiveData"
android:textAlignment="center"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/email_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:ems="10"
android:hint="E-Mail Address"
android:inputType="textEmailAddress"
android:text="@={LoginViewModel.email}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/heading" />
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:ems="10"
android:hint="Password"
android:inputType="textPassword"
android:text="@={LoginViewModel.password}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/email_id" />
<Button
android:id="@+id/login"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:onClick="@{(v) -> LoginViewModel.onClick(v)}"
android:text="Click to Login"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/password" />
<TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="8dp"
android:gravity="center"
android:text="See the Results Below From LiveDataBinding"
android:textColor="@android:color/background_dark"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/login" />
<TextView
android:id="@+id/fetch_email_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="---"
android:textColor="@android:color/holo_blue_light"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/result" />
<TextView
android:id="@+id/fetch_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="32dp"
android:text="---"
android:textColor="@android:color/holo_blue_light"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fetch_email_id" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
登录视图模型:
package com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel;
import android.view.View;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.jimmytrivedi.learning.mvvmloginsignupdemo.Model.LoginUser;
public class LoginViewModel extends ViewModel {
public MutableLiveData<String> email = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
private MutableLiveData<LoginUser> userMutableLiveData;
public MutableLiveData<LoginUser> getUser() {
if (userMutableLiveData == null) {
userMutableLiveData = new MutableLiveData<>();
}
return userMutableLiveData;
}
public void onClick(View view) {
LoginUser loginUser = new LoginUser(email.getValue(), password.getValue());
userMutableLiveData.setValue(loginUser);
}
}
注意:
我会像这个视图模型一样将包名改为小写字母,它会给 ActivityMainImpl 带来错误,这不是我生成的
您收到此错误是因为您在 XML 文件中用大写字母定义了程序包名称。
<variable
name="LoginViewModel"
type="com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel" />
应该是com.jimmytrivedi.learning.mvvmloginsignupdemo.viewmodel.LoginViewModel
。 viewmodel
加上小写字母,还要确保你的包名是 viewmodel
。
问题出在这里type="com.jimmytrivedi.learning.mvvmloginsignupdemo.ViewModel.LoginViewModel"
任何父包都必须以 lowercase
开头,但在您的情况下 package name
在 Uppercase
因此将您的 ViewModel
重命名为 viewmodel
你的 type
应该是这样的
type="com.jimmytrivedi.learning.mvvmloginsignupdemo.viewmodel.LoginViewModel"