无法从ViewModel观察Livedata

时间:2019-11-21 06:31:36

标签: android mvvm retrofit

我已经在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”不会调用可观察的。

2 个答案:

答案 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);
        }
}