代码之家  ›  专栏  ›  技术社区  ›  Soon Santos

刷新MVVM体系结构数据

  •  0
  • Soon Santos  · 技术社区  · 6 年前

    我有一个mvvm实现,使用retrofit2、rxjava和rxandroid从Internet获取数据。

    我的目标是当用户在 SwipeRefreshLayout . 这就是实现。

    newsfeedfragment.java

    @Inject
    ViewModelFactory viewModelFactory;
    RandomVideosViewModel viewModel;
    
    
    @Override
    public void onAttach(Context context) {
        ((BaseApplication) context.getApplicationContext())
                .getAppComponent()
                .inject(this);
        super.onAttach(context);
    }
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
        ... 
    
        viewModel = ViewModelProviders.of(this, viewModelFactory).get(RandomVideosViewModel.class);
    
        VideoCardAdapter videoCardAdapter = new VideoCardAdapter(getActivity());
    
        viewModel.videosList.observe(this, videoCardAdapter::submitList);
        viewModel.networkState.observe(this, videoCardAdapter::setNetworkState);
    
        mRecyclerView.setAdapter(videoCardAdapter);
    
        ...
    }
    

    randomvideosview模型.java

    public class RandomVideosViewModel extends ViewModel {
    
        public LiveData<PagedList<Video>> videosList;
        public LiveData<NetworkState> networkState;
    
        public RandomVideosViewModel(RandomVideosDataSourceFactory randomVideosDataSourceFactory) {
    
            networkState = Transformations.switchMap(randomVideosDataSourceFactory.getMutableLiveData(),
                    PageKeyedRandomVideosDataSource::getNetworkState);
    
            PagedList.Config pagedListConfig = (new PagedList.Config.Builder()
                    .setEnablePlaceholders(false)
                    .setInitialLoadSizeHint(10)
                    .setPageSize(10))
                    .build();
    
            videosList = (new LivePagedListBuilder(randomVideosDataSourceFactory, pagedListConfig)).build();
        }
    
    }
    

    随机录像数据源工厂

    public class RandomVideosDataSourceFactory extends DataSource.Factory {
    
        private MutableLiveData<PageKeyedRandomVideosDataSource> mutableLiveData = new MutableLiveData<>();
        private PageKeyedRandomVideosDataSource pageKeyedRandomVideosDataSource;
    
        public RandomVideosDataSourceFactory(PageKeyedRandomVideosDataSource pageKeyedRandomVideosDataSource) {
            this.pageKeyedRandomVideosDataSource = pageKeyedRandomVideosDataSource;
        }
    
        public MutableLiveData<PageKeyedRandomVideosDataSource> getMutableLiveData() {
            return mutableLiveData;
        }
    
        @Override
        public DataSource create() {
            mutableLiveData.postValue(pageKeyedRandomVideosDataSource);
            return pageKeyedRandomVideosDataSource;
        }
    }
    

    页面键和视频数据源

    public class PageKeyedRandomVideosDataSource extends PageKeyedDataSource<Integer, Video> {
    
        private static final String TAG = "Refresh - PageKeyedRand";
    
        private CompositeDisposable disposable = new CompositeDisposable();
        private MutableLiveData<NetworkState> networkState = new MutableLiveData<>();
        private MutableLiveData<NetworkState> initialLoading = new MutableLiveData<>();
        private Repository repository;
        private Random random = new Random();
        private int firstPage;
        private List<Integer> usedNumbers = new ArrayList<>();
        private int numbOfTimes = 0;
    
        public PageKeyedRandomVideosDataSource(Repository repository) {
            this.repository = repository;
        }
    
        public MutableLiveData<NetworkState> getNetworkState() {
            return networkState;
        }
    
        public MutableLiveData<NetworkState> getInitialLoading() {
            return initialLoading;
        }
    
        @Override
        public void
        loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, Video> callback) {
            List<Video> videoList = new ArrayList<>();
            networkState.postValue(NetworkState.LOADING);
            initialLoading.postValue(NetworkState.LOADING);
    
            firstPage = getFirstPage();
            usedNumbers.add(firstPage);
            numbOfTimes++;
    
            Log.i(TAG, "loadInitial: Loading page: " + firstPage + " - Size: " + params.requestedLoadSize);
    
            disposable.add(RxHelper.getObservable(repository.getHomeVideosObservable(params.requestedLoadSize, firstPage))
                    .subscribe(requestVideo -> {
                        if (requestVideo != null) {
                            int lastPage = requestVideo.getLastPage();
                            int nextPage = getRandomPage(lastPage);
                            Log.i(TAG, "loadInitial: NextPage: " + nextPage);
    
                            videoList.addAll(requestVideo.getVideoList());
                            callback.onResult(videoList, null, nextPage);
                            networkState.postValue(NetworkState.LOADED);
                            initialLoading.postValue(NetworkState.LOADED);
                        }
                    }, throwable -> {
                        throwable.printStackTrace();
                        networkState.postValue(NetworkState.failed(throwable.getMessage()));
                        initialLoading.postValue(NetworkState.failed(throwable.getMessage()));
                    }));
        }
    
        @Override
        public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Video> callback) {
    
        }
    
        @Override
        public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, Video> callback) {
            Log.i(TAG, "loadAfter: Loading page: " + params.key + " - Size: " + params.requestedLoadSize);
            List<Video> videoList = new ArrayList<>();
            networkState.postValue(NetworkState.LOADING);
    
            disposable.add(RxHelper.getObservable(repository.getHomeVideosObservable(params.requestedLoadSize, params.key))
                    .subscribe(requestVideo -> {
                        if (requestVideo != null) {
                            int lastPage = requestVideo.getLastPage();
                            int nextPage = getRandomPage(lastPage);
                            Log.i(TAG, "loadAfter: NextPage: " + nextPage);
    
                            videoList.addAll(requestVideo.getVideoList());
                            callback.onResult(videoList, nextPage);
                            networkState.postValue(NetworkState.LOADED);
                        }
                    }, throwable -> {
                        throwable.printStackTrace();
                        networkState.postValue(NetworkState.failed(throwable.getMessage()));
                    }));
        }
    

    randomvideosdatasource工厂只检索pagekeyedRandomvideosdatasource,最后一个将数据加载到多个页面中。

    问题

    加载此数据后,当用户使用 滑动刷新布局 . 有什么线索吗?

    我试过的

    我试图重新创建ViewModel,但它似乎一直在检索同一个实例。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Knossos    6 年前

    通常,最好的方法是将ViewModel中的抽象数据收集放到存储库中。

    存储库是单一的。它有一个viewmodel观察到的livedata。

    存储库最初从缓存(例如room)获取数据。它还观察到这些数据。

    当您需要一组新的数据(第一次加载、刷新时刷卡,甚至是工作人员)时,您可以调用存储库来开始更新缓存。它将自动更新视图模型中的数据(以及观察该视图模型的任何其他内容)。