我已经在MVVM设计模式上实现了简单的手机号码登录,但是从服务器返回响应时不会调用Onchanged函数。
LoginViewModel
public class LoginViewModel extends ViewModel {
private LoginModel login;
private MutableLiveData<LoginResponse> loginresponse = new MutableLiveData<>();
private LoginRepository loginrepository;
public void init() {
login = new LoginModel();
}
public LoginModel getLogin() {
return login;
}
public void onLoginClick() {
if(login.isPhonevalid()){
HashMap<String,Object> loginObject = new HashMap<>();
loginObject.put("phonenumber",login.getMobileNumber());
loginObject.put("apimethod","beatme");
loginresponse = LoginRepository.getInstance().login(loginObject);
// loginClick.setValue(login);
}
}
@BindingAdapter("error")
public static void setError(EditText editText, String errormessage) {
editText.setError(errormessage);
}
public MutableLiveData<LoginResponse> getLoginresponse() {
return loginresponse;
}
public String getMobileNo(){
return login.getMobileNumber();
}
}
登录库
public class LoginRepository {
private static LoginRepository loginRepository;
private Api api;
public static LoginRepository getInstance() {
if (loginRepository == null) {
loginRepository = new LoginRepository();
}
return loginRepository;
}
public LoginRepository() {
api = RetrofitService.createService(Api.class);
}
public MutableLiveData<LoginResponse> login(HashMap<String, Object> body) {
final MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
api.login(body).enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) {
loginResponse.setValue(response.body());
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
loginResponse.setValue(null);
}
});
return loginResponse;
}
}
LoginActivity
public class LoginActivity extends AppCompatActivity {
private LoginViewModel viewModel;
ActivityLoginBinding activityLoginBinding;
boolean doubleBackToExitPressedOnce = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
getSupportActionBar().hide();
activityLoginBinding = DataBindingUtil.setContentView(LoginActivity.this, R.layout.activity_login);
viewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
if (savedInstanceState == null) {
viewModel.init();
}
activityLoginBinding.setLoginViewModel(viewModel);
setuploginclick();
}
public void setuploginclick() {
viewModel.getLoginresponse().observe(this, new Observer<LoginResponse>() {
@Override
public void onChanged(LoginResponse loginResponse) {
Toast.makeText(LoginActivity.this,viewModel.getMobileNo(),Toast.LENGTH_SHORT).show();
Intent i = new Intent(LoginActivity.this, OTPVerify.class);
i.putExtra("mobileno",viewModel.getMobileNo());
startActivity(i);
}
});
}
}
我从日志中看到数据已成功发布,并且响应也很完美。但是将值分配给实时数据“ loginresponse”不会调用可观察的。
答案 0 :(得分:2)
来自文档
您必须调用setValue(T)方法来更新LiveData对象 从主线程。如果代码在工作线程中执行,则您 可以改用postValue(T)方法更新LiveData对象。
使用
loginResponse.postValue(response.body());
更多详细信息,请参见LiveData Overview
编辑:
在LoginRepository中删除
final MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
将值设置为viewmodel LoginResponse,然后只有新值将viemodel传递给活动
答案 1 :(得分:2)
从loginResponse
中删除ViewModel
并在Repository
中创建它,然后将存储库loginResponse
传递到您的活动中。检查下面
public class LoginRepository {
public MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
...
//getter
public MutableLiveData<LoginResponse> getLoginResponse() {
return loginResponse
}
}
然后在ViewModel中
public class LoginViewModel extends ViewModel {
...
public MutableLiveData<LoginResponse> getLoginResponse() {
return LoginRepository.getInstance().getLoginResponse()
}
...
public void onLoginClick() {
if(login.isPhonevalid()){
HashMap<String,Object> loginObject = new HashMap<>();
loginObject.put("phonenumber",login.getMobileNumber());
loginObject.put("apimethod","beatme");
LoginRepository.getInstance().login(loginObject);
// loginClick.setValue(login);
}
}
...
}
更改存储库中的登录功能,如下所示:
public void login(HashMap<String, Object> body) {
api.login(body).enqueue(new Callback<LoginResponse>() {
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if (response.isSuccessful()) {
loginResponse.postValue(response.body());
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
loginResponse.postValue(null);
}
}