我在 MVVM 设计模式上实现了一个简单的手机号码登录。但是当从服务器返回响应时,不会调用 Onchanged 函数。
登录 View 模型
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;
}
}
登录 Activity
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”赋值并不调用 observable。
最佳答案
从 ViewModel
中删除 loginResponse
并在 Repository
中创建它,然后将存储库 loginResponse
传递给您的 Activity 。检查下面
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);
}
}
...
}
像下面这样更改您在 Repository 中的登录功能:
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);
}
}
关于android - 无法从 ViewModel 观察实时数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58968611/