android - 改造调用不更新 View 模型或 View 模型不更新 View

标签 android retrofit2 android-viewmodel android-mvvm

我尝试从rest 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;
    }
}

用户.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 + '\'' +
                '}';
    }
}

在 View 中,我有两个用于登录的 EditText 并且工作完美,因为我可以将电子邮件和密码传递到 LoginRepositori.doLogin 中,并且我得到了用户的响应,但是当我想获取有关用户数据的更新时具有 loginViweMode.User.observe 的 Activity ...我从未收到通知。

那么如何才能做到这一点,因为 Activity 中的loginViewModel.User.observe...被调用。

谢谢。

最佳答案

您错过了 Activity 和 View 模型之间的一些联系。由于存储库每次都会返回新的实时数据对象,用户将无法观察到它的值被登录调用替换。

要解决此问题,您可以将用户实时数据传递到存储库并从存储库更新其值,而不是在每次调用中创建新对象

或者您可以使用 switchMap() 转换函数将结果转换为 user 变量

关于android - 改造调用不更新 View 模型或 View 模型不更新 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54196820/

相关文章:

Android 数据绑定(bind)和 LiveData : Can't bind to value in LiveData property

android - 在 Google map 中测量步行距离

android - Flutter:在彼此相邻的两列中显示内容

android-recyclerview - 如何使用另一个 Room-DAO 查询刷新我的 RecyclerView

android - 如何在 Android 中使用 retrofit 2 以 JSON 格式上传多部分图像数据?

java - 可以使用 Retrofit 进行 SOAP web 服务调用吗?

android - Kotlin:不同 fragment 之间的通信

android - 如何使用加速度计为 View 设置动画?

android - 如何让一个简单的 Android (Studio) Proguard 配置正常工作

Android Retrofit - POST 请求不起作用,但在 Postman 中它有效