【问题标题】:Refreshing livedata with Retrofit request response使用 Retrofit 请求响应刷新 livedata
【发布时间】:2019-01-08 08:01:06
【问题描述】:

我有一个简单的应用程序,它显示电影列表。当用户单击一个按钮时,它应该刷新列表,这意味着再次进入 Retrofit 并获取新列表。 问题是,这种刷新不起作用。当我打开应用程序时,它只会获取一次列表。

public class MoviesViewModel extends AndroidViewModel {
    private MutableLiveData<Resource<List<Movie>>> mLastdMovieListObservable;
    private Repository mRepository;

    public MoviesViewModel(Application application) {
        super(application);
        mRepository = new Repository();
    }

    public LiveData<Resource<List<Movie>>> getMovieListLiveData() {
        if (mLastdMovieListObservable == null) {
            mLastdMovieListObservable = mRepository.getMovieList();
        }
        return mLastdMovieListObservable;
    }
}

和存储库:

public MutableLiveData<Resource<List<Movie>>> getMovieList() {
    final MutableLiveData<Resource<List<Movie>>> data = new MutableLiveData<>();
    data.setValue(Resource.loading(null));

    mInterface.getMovies(.....).enqueue(new Callback<MovieListResponse>() {
        @Override
        public void onResponse(Call<MovieListResponse> call, Response<MovieListResponse> response) {
            if (response.isSuccessful()) {
                data.postValue(Resource.success(response.body().getResult()));
            } else {
                data.postValue(Resource.error(response.message(), null));
            }
        }
        @Override
        public void onFailure(Call<MovieListResponse> call, Throwable t) {
            data.postValue(Resource.error(t.getMessage(), null));
        }
    });

    return data;
}   

然后在片段中它只是:

mMoviesViewModel.getMovieListLiveData().observe(this, moviesResource -> {
    if (moviesResource.status == Status.SUCCESS) {
       .....
       .....

然后是按钮点击部分,当我需要再次获取列表时,我不确定如何实现它。 我尝试过的任何东西都不起作用。存储库立即将数据返回为空。

【问题讨论】:

    标签: java android retrofit android-viewmodel


    【解决方案1】:

    您可以使用重试方法,我快速更改了您的代码作为重试示例,并检查此源以获得更好的代码。LINK

    Transformations.switchMap 监听重试,当它改变时,将再次调用 swithMap。在 UI ViewModel 中应该像下面这样配置,但在按钮中你只需要调用重试。

    mMoviesViewModel.getMovieListLiveData().observe(this, moviesResource -> {
    if (moviesResource.status == Status.SUCCESS) {
       .....
       .....
    

    在按钮中:

    mMoviesViewModel.retry()
    

    还有 ViewModel:

    public class MoviesViewModel extends AndroidViewModel {
    private MutableLiveData<Resource<List<Movie>>> mLastdMovieListObservable;
    private Repository mRepository;
    private Boolean mRetry = false;
    
    public MoviesViewModel(Application application) {
        super(application);
        mRepository = new Repository();
        mLastdMovieListObservable = Transformations.switchMap(mRetry){
            mLastdMovieListObservable = mRepository.getMovieList()
        }
    }
    
    public LiveData<Resource<List<Movie>>> getMovieListLiveData() {
        return mLastdMovieListObservable;
    }
    
    public void retry(){
        mRetry.setValue(true)
    }}
    

    【讨论】:

    • 谢谢,但是如果请求基于一个枚举调用不同类型的电影,你会怎么做?例如,我想要 getMovies(enum.Latest) 或 getMovies(enum.Popular).. 它变得更加复杂,并且用布尔值处理这一切似乎有点牵强
    • 我贴了另一个例子,并不复杂。
    【解决方案2】:

    电影类型的变化如下:

    public class MoviesViewModel extends AndroidViewModel {
    private MutableLiveData<Resource<List<Movie>>> mLastdMovieListObservable;
    private Repository mRepository;
    private Int mMovieType = 0;
    
    public MoviesViewModel(Application application) {
        super(application);
        mRepository = new Repository();
        mLastdMovieListObservable = Transformations.switchMap(mMovieType, type->
            mLastdMovieListObservable = mRepository.getMovieList(type)
        );
    }
    
    public LiveData<Resource<List<Movie>>> getMovieListLiveData() {
        return mLastdMovieListObservable;
    }
    
    public void setMovieType(Int movieType){
        mMovieType.setValue(movieType)
    }
    

    }

    【讨论】:

    • 谢谢,但正如您在我的存储库中看到的,我使用资源,它首先更新为加载状态,然后我再次为响应本身执行 setValue。我不确定会不会奏效。当你点击 setMovieType 时,它​​会发送 Loading,但是当响应返回时,它会“忽略”它。
    • 您可以更改您的加载解决方案并获得成功和失败,但在 UI 中首先通过显示指示器处理加载,并在响应成功时禁用它。您可以找到两种资源方法,加载和不加载。在资源中使用加载不是确定的方法,我认为您需要使用代码来获得结果。
    猜你喜欢
    • 2017-11-07
    • 2014-03-20
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    相关资源
    最近更新 更多