I have implemented simple a mobile number login on MVVM design pattern.But the Onchanged function is not called when the response is returned from the server.
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();
}
}
LoginRepository
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);
}
});
}
}
I can see from the log that the data is posted success and the response too is perfect. But assigning value to the livedata "loginresponse" doesn't call observable.
From the documents
You must call the setValue(T) method to update the LiveData object from the main thread. If the code is executed in a worker thread, you can use the postValue(T) method instead to update the LiveData object.
use
loginResponse.postValue(response.body());
more detail refer LiveData Overview
Edit:
In LoginRepository remove
final MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
set value to viewmodel LoginResponse then only new value pass viemodel to activity
Remove loginResponse
from ViewModel
and create it in Repository
then pass repository loginResponse
to your activity. Check below
public class LoginRepository {
public MutableLiveData<LoginResponse> loginResponse = new MutableLiveData<>();
...
//getter
public MutableLiveData<LoginResponse> getLoginResponse() {
return loginResponse
}
}
then in 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);
}
}
...
}
Change your login function in Repository like below:
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);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.