改造调用不更新视图模型或视图模型不更新视图
The retrofit call not update viewmodel or viewmodel not update the view
我尝试从休息中获取用户 api 登录我的 android 应用程序以获取此信息 我有下一个代码
LoginActivity.java
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
binding.setLoginViewModel(loginViewModel);
binding.setLifecycleOwner(this);
loginViewModel.user.observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
Toast.makeText(getApplicationContext(), user.toString(), Toast.LENGTH_LONG).show();
}
});
}
}
LoginViewModel.java
public class LoginViewModel extends ViewModel {
private LoginRespository loginRespository = new LoginRespository();
public MutableLiveData<User> user = new MutableLiveData<>();
public MutableLiveData<String> email = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
public LoginViewModel() {}
public void onLoginClicked() {
user = loginRespository.doLogin(email.getValue(), password.getValue());
}
}
LoginRepository.java
@Singleton
public class LoginRespository {
private APIInterface apiInterface;
public LoginRespository(){
this.apiInterface = APIClient.getClient().create(APIInterface.class);
}
//private final APIInterface apiInterface;
/*@Inject
public LoginRespository(APIInterface apiInterface) {
this.apiInterface = apiInterface;
}*/
public MutableLiveData<User> doLogin(String email, String password) {
final MutableLiveData<User> data = new MutableLiveData<>();
Call<User> call = apiInterface.doGetLogin(email, password, APIClient.X_API_KEY, APIClient.X_CLIENT_ID);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User user = response.body();
Log.d("#####0", user.toString());
if (user.code.equals(APIClient.Codes.OK)){
Log.d("#####1", user.toString());
data.setValue(user);
Log.d("#####2", data.toString());
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
call.cancel();
}
});
return data;
}
}
User.java
public class User{
@SerializedName("code")
@Expose
public String code;
@SerializedName("data")
@Expose
public List<Datum> data = null;
@SerializedName("description")
@Expose
public String description;
@SerializedName("datetime")
@Expose
public String datetime;
/**
* No args constructor for use in serialization
*
*/
public User() {
}
/**
*
* @param description
* @param data
* @param code
* @param datetime
*/
public User(String code, List<Datum> data, String description, String datetime) {
super();
this.code = code;
this.data = data;
this.description = description;
this.datetime = datetime;
}
@Override
public String toString() {
return "User{" +
"code='" + code + '\'' +
", data=" + data +
", description='" + description + '\'' +
", datetime='" + datetime + '\'' +
'}';
}
}
在视图中,我有两个 EditText 用于登录并且工作完美,因为我可以将电子邮件和密码传递到 LoginRepositori.doLogin 并且我得到了用户的响应,但是当我想获得更新时activity 中的用户数据 loginViweMode.User.observe... 我从来没有收到通知。
那怎么办呢,因为loginViewModel.User.observe...在activity被调用了。
谢谢。
您正在下面的调用中创建一个新的 user
LiveData
实例(不同于您在 LoginActivity
.
中实际观察到的实例
public void onLoginClicked() {
user = loginRespository.doLogin(email.getValue(), password.getValue());
}
您错过了 activity 和视图模型之间的某些连接。由于存储库 returns 新的实时数据对象每次 user
将无法观察,因为它的值已被登录调用替换。
要解决这个问题,您可以将用户实时数据传递到存储库并从存储库更新其值,而不是在每次调用时创建新对象
或者你可以使用switchMap()转换函数将结果转换成user
变量
我尝试从休息中获取用户 api 登录我的 android 应用程序以获取此信息 我有下一个代码
LoginActivity.java
public class LoginActivity extends AppCompatActivity {
private LoginViewModel loginViewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityLoginBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_login);
loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
binding.setLoginViewModel(loginViewModel);
binding.setLifecycleOwner(this);
loginViewModel.user.observe(this, new Observer<User>() {
@Override
public void onChanged(@Nullable User user) {
Toast.makeText(getApplicationContext(), user.toString(), Toast.LENGTH_LONG).show();
}
});
}
}
LoginViewModel.java
public class LoginViewModel extends ViewModel {
private LoginRespository loginRespository = new LoginRespository();
public MutableLiveData<User> user = new MutableLiveData<>();
public MutableLiveData<String> email = new MutableLiveData<>();
public MutableLiveData<String> password = new MutableLiveData<>();
public LoginViewModel() {}
public void onLoginClicked() {
user = loginRespository.doLogin(email.getValue(), password.getValue());
}
}
LoginRepository.java
@Singleton
public class LoginRespository {
private APIInterface apiInterface;
public LoginRespository(){
this.apiInterface = APIClient.getClient().create(APIInterface.class);
}
//private final APIInterface apiInterface;
/*@Inject
public LoginRespository(APIInterface apiInterface) {
this.apiInterface = apiInterface;
}*/
public MutableLiveData<User> doLogin(String email, String password) {
final MutableLiveData<User> data = new MutableLiveData<>();
Call<User> call = apiInterface.doGetLogin(email, password, APIClient.X_API_KEY, APIClient.X_CLIENT_ID);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
User user = response.body();
Log.d("#####0", user.toString());
if (user.code.equals(APIClient.Codes.OK)){
Log.d("#####1", user.toString());
data.setValue(user);
Log.d("#####2", data.toString());
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
call.cancel();
}
});
return data;
}
}
User.java
public class User{
@SerializedName("code")
@Expose
public String code;
@SerializedName("data")
@Expose
public List<Datum> data = null;
@SerializedName("description")
@Expose
public String description;
@SerializedName("datetime")
@Expose
public String datetime;
/**
* No args constructor for use in serialization
*
*/
public User() {
}
/**
*
* @param description
* @param data
* @param code
* @param datetime
*/
public User(String code, List<Datum> data, String description, String datetime) {
super();
this.code = code;
this.data = data;
this.description = description;
this.datetime = datetime;
}
@Override
public String toString() {
return "User{" +
"code='" + code + '\'' +
", data=" + data +
", description='" + description + '\'' +
", datetime='" + datetime + '\'' +
'}';
}
}
在视图中,我有两个 EditText 用于登录并且工作完美,因为我可以将电子邮件和密码传递到 LoginRepositori.doLogin 并且我得到了用户的响应,但是当我想获得更新时activity 中的用户数据 loginViweMode.User.observe... 我从来没有收到通知。
那怎么办呢,因为loginViewModel.User.observe...在activity被调用了。
谢谢。
您正在下面的调用中创建一个新的 user
LiveData
实例(不同于您在 LoginActivity
.
public void onLoginClicked() {
user = loginRespository.doLogin(email.getValue(), password.getValue());
}
您错过了 activity 和视图模型之间的某些连接。由于存储库 returns 新的实时数据对象每次 user
将无法观察,因为它的值已被登录调用替换。
要解决这个问题,您可以将用户实时数据传递到存储库并从存储库更新其值,而不是在每次调用时创建新对象
或者你可以使用switchMap()转换函数将结果转换成user
变量