【问题标题】:How to integrate Android Paging Library with NetworkBoundResource如何将 Android 分页库与 NetworkBoundResource 集成
【发布时间】:2018-05-12 05:08:41
【问题描述】:

我的应用正在使用 Android 的 Architecture components 库,并显示从具有无限滚动效果的分页 REST api 获取的项目列表。

我想要做的是将Paging LibraryNetworkBoundResource 结合使用,这样当用户向下滚动列表时,会从数据库中获取下一个项目并显示它们(如果存在),并且同时调用 API 来更新 DB 中的项目。

我找不到这两种模式同居的任何例子。

这是 DAO:

@Query("SELECT * FROM items ORDER BY id DESC")
LivePagedListProvider<Integer,MyItem> loadListPaginated();

这是我的NetworkBoundResource 实现:

public class PagedListNetworkBoundResource extends NetworkBoundResource<PagedList<MyItem>, List<MyItem>> {

    @Override
    protected void saveCallResult(@NonNull List<MyItem> items) {
        // Inserting new items into DB
        dao.insertAll(items);
    }

    @Override
    protected boolean shouldFetch(@Nullable PagedList<MyItem> data) {
        return true;
    }

    @NonNull
    @Override
    protected LiveData<PagedList<MyItem>> loadFromDb() {
        return Transformations.switchMap(dao.loadListPaginated().create(INITIAL_LOAD_KEY, PAGE_SIZE),
                new Function<PagedList<MyItem>, LiveData<List<MyItem>>>() {

            @Override
            public LiveData<PagedList<MyItem>> apply(final PagedList<MyItem> input) {
                // Here I must load nested objects, attach them, 
                // and return the fully loaded items
            }
        });
    }

    @NonNull
    @Override
    protected LiveData<ApiResponse<List<MyItem>>> createCall() {
        // I don't get the current paged list offset to perform a call to the API
        return ...;
    }
}

【问题讨论】:

    标签: android paging android-architecture-components android-paging


    【解决方案1】:

    我还搜索了很多关于 NetworkBoundResource 的信息,我得出的结论是 NetworkBoundResource 和 Paging Lib 彼此不相关。它们都有自己的功能

    根据谷歌给出的关于分页库的文章 https://developer.android.com/topic/libraries/architecture/paging.html

    1.从本地数据库加载数据需要使用 DataSource 我的道

    @Dao
    public interface UserDao {
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        void insert(User... user);
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        void insert(List<User> users);
    
        @Query("Select * from User ")
        public abstract DataSource.Factory<Integer,User> getList();
    }
    

    2.然后从网络请求数据我们需要用LivePagedListBuilder实现BoundaryCallback类

    public class UserBoundaryCallback extends PagedList.BoundaryCallback<User> {
        public static final String TAG = "ItemKeyedUserDataSource";
        GitHubService gitHubService;
        AppExecutors executors;
        private MutableLiveData networkState;
        private MutableLiveData initialLoading;
        public UserBoundaryCallback(AppExecutors executors) {
            super();
            gitHubService = GitHubApi.createGitHubService();
            this.executors = executors;
            networkState = new MutableLiveData();
            initialLoading = new MutableLiveData();
        }
        public MutableLiveData getNetworkState() {
            return networkState;
        }
    
        public MutableLiveData getInitialLoading() {
            return initialLoading;
        }
    
        @Override
        public void onZeroItemsLoaded() {
            //super.onZeroItemsLoaded();
            fetchFromNetwork(null);
        }
    
        @Override
        public void onItemAtFrontLoaded(@NonNull User itemAtFront) {
            //super.onItemAtFrontLoaded(itemAtFront);
        }
    
        @Override
        public void onItemAtEndLoaded(@NonNull User itemAtEnd) {
            // super.onItemAtEndLoaded(itemAtEnd);
            fetchFromNetwork(itemAtEnd);
        }
        public void fetchFromNetwork(User user) {
            if(user==null) {
                user = new User();
                user.userId = 1;
            }
            networkState.postValue(NetworkState.LOADING);
            gitHubService.getUser(user.userId,20).enqueue(new Callback<List<User>>() {
                @Override
                public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                    executors.diskIO().execute(()->{
                        if(response.body()!=null)
                            userDao.insert(response.body());
                            networkState.postValue(NetworkState.LOADED);
                    });
                }
    
                @Override
                public void onFailure(Call<List<User>> call, Throwable t) {
                    String errorMessage;
                    errorMessage = t.getMessage();
                    if (t == null) {
                        errorMessage = "unknown error";
                    }
                    Log.d(TAG,errorMessage);
                    networkState.postValue(new NetworkState(Status.FAILED, errorMessage));
                }
            });
        }
    
    }
    

    3.My VM Code 从 DB + Network 加载数据

    public class UserViewModel extends ViewModel {
    
        public LiveData<PagedList<User>> userList;
        public LiveData<NetworkState> networkState;
        AppExecutors executor;
        UserBoundaryCallback userBoundaryCallback;
    
        public UserViewModel() {
            executor = new AppExecutors();
        }
        public void init(UserDao userDao)
        {
            PagedList.Config pagedListConfig =
                    (new PagedList.Config.Builder()).setEnablePlaceholders(true)
                            .setPrefetchDistance(10)
                            .setPageSize(20).build();
            userBoundaryCallback = new UserBoundaryCallback(executor);
            networkState = userBoundaryCallback.getNetworkState();
            userList = (new LivePagedListBuilder(userDao.getList(), pagedListConfig).setBoundaryCallback(userBoundaryCallback))
                    .build();
        }
    }
    

    【讨论】:

      【解决方案2】:

      这假定回调中的每个项目都包含一个索引/偏移量。通常情况并非如此 - 项目可能只包含 ID。

      【讨论】:

        猜你喜欢
        • 2015-11-26
        • 2013-05-06
        • 2013-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 2015-02-14
        相关资源
        最近更新 更多