如何在Android分页库中维护列表、筛选和搜索的相同数据源

如何在Android分页库中维护列表、筛选和搜索的相同数据源,android,retrofit2,android-search,android-paging,android-paging-library,Android,Retrofit2,Android Search,Android Paging,Android Paging Library,我有一个活动,显示项目列表,也有过滤器和搜索选项。我正在使用android分页库显示项目。第一次加载项目列表时,当我滚动到底部时,下一组项目将被加载,工作正常。但我还想筛选项目并搜索项目。在筛选或搜索项目时,我正在使现有源无效。如果我没有使数据源无效,则不会启动筛选和搜索api。我想使用数据源加载基于筛选和搜索键的新项目列表 executor = Executors.newFixedThreadPool(5); celebrityDataFactory = new CelebrityDa

我有一个活动,显示项目列表,也有过滤器和搜索选项。我正在使用android分页库显示项目。第一次加载项目列表时,当我滚动到底部时,下一组项目将被加载,工作正常。但我还想筛选项目并搜索项目。在筛选或搜索项目时,我正在使现有源无效。如果我没有使数据源无效,则不会启动筛选和搜索api。我想使用数据源加载基于筛选和搜索键的新项目列表

executor = Executors.newFixedThreadPool(5);
    celebrityDataFactory = new CelebrityDataFactory(apicallInterface,         mFansismParam);
    networkState =  Transformations.switchMap(celebrityDataFactory.getCelebrityData(),
            dataSource -> dataSource.getNetworkState());

    PagedList.Config pagedListConfig =
            (new PagedList.Config.Builder())
                    .setEnablePlaceholders(false)
                    .setPrefetchDistance(8)
                    .setInitialLoadSizeHint(10)
                    .setPageSize(20).build();
    if (!mFansismParam.getCategoryId().isEmpty()) {
        celebrityDetails = new LivePagedListBuilder(celebrityDataFactory, pagedListConfig)
                .setFetchExecutor(executor)
                .build();
    } else(!mFansismParam.getProfessionId().isEmpty()) {
        celebrityDetails = new LivePagedListBuilder(celebrityDataFactory, pagedListConfig)
                .setFetchExecutor(executor)
                .build();
    }
创建数据源的数据工厂

@Override
public DataSource create() {
    celebrityDataSource = new CelebrityDataSource(apicallInterface,   params);
    celebrityData.postValue(celebrityDataSource);
    return celebrityDataSource;
}
改型API调用:

 Call<CelebrityList> getCelebrityList(@Query("categoryId") String categoryId,
                                     @Query("professionId") String professionId,
                                     @Query("page") String pageNumber,
                                     @Query("name") String searchKey);
apicallInterface.getCelebrityList(requestParams.getCategoryId(), "", "1", "").enqueue(new Callback<CelebrityList>() {
        @Override
        public void onResponse(Call<CelebrityList> call, Response<CelebrityList> response) {
            if (response.isSuccessful()) {
                initialLoading.postValue(NetworkState.LOADED);
                networkState.postValue(NetworkState.LOADED);
                if (!response.body().getData().isEmpty()) {
                    callback.onResult(response.body().getData(), null, "2");
                } else {
                    networkState.postValue(new NetworkState(NetworkState.Status.SUCCESS, "No more results"));
                }
            } else {
                initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
                networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
            }
        }
调用getCelebrityList(@Query(“categoryId”)字符串categoryId,
@查询(“professionId”)字符串professionId,
@查询(“页面”)字符串页码,
@查询(“名称”)字符串搜索键);
数据源Api回调:

 Call<CelebrityList> getCelebrityList(@Query("categoryId") String categoryId,
                                     @Query("professionId") String professionId,
                                     @Query("page") String pageNumber,
                                     @Query("name") String searchKey);
apicallInterface.getCelebrityList(requestParams.getCategoryId(), "", "1", "").enqueue(new Callback<CelebrityList>() {
        @Override
        public void onResponse(Call<CelebrityList> call, Response<CelebrityList> response) {
            if (response.isSuccessful()) {
                initialLoading.postValue(NetworkState.LOADED);
                networkState.postValue(NetworkState.LOADED);
                if (!response.body().getData().isEmpty()) {
                    callback.onResult(response.body().getData(), null, "2");
                } else {
                    networkState.postValue(new NetworkState(NetworkState.Status.SUCCESS, "No more results"));
                }
            } else {
                initialLoading.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
                networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
            }
        }
apicallInterface.getCellebrityList(requestParams.getCategoryId(),“”,“,”1“,“”)。排队(新回调(){
@凌驾
公共void onResponse(调用、响应){
if(response.issusccessful()){
initialLoading.postValue(NetworkState.LOADED);
networkState.postValue(networkState.LOADED);
如果(!response.body().getData().isEmpty()){
onResult(response.body().getData(),null,“2”);
}否则{
networkState.postValue(新的networkState(networkState.Status.SUCCESS,“无更多结果”);
}
}否则{
initialLoading.postValue(新的网络状态(NetworkState.Status.FAILED,response.message());
networkState.postValue(新的networkState(networkState.Status.FAILED,response.message());
}
}

您需要在实时数据中保留搜索键,以便页面列表可以随时更改。因此,在viewmodel中,定义:

public MutableLiveData<String> filterTextAll = new MutableLiveData<>();
您可以更改DataSourceFactory和DataSource构造函数以添加searchKey参数:

public class MyDataSourceFactory extends DataSource.Factory {

  MutableLiveData<MyDataSource> myDataSourceMutableLiveData;
  private MyDataSource myDataSource;
  private Executor executor;
  private String searchKey;

  public MyDataSourceFactory(Executor executor , String searchKey) {
    this.executor= executor;
    this.searchKey= searchKey;
    this.myDataSourceMutableLiveData= new MutableLiveData<>();
  }

  @Override
  public DataSource create() {
    //*notice: It's important that everytime a DataSource factory create() is invoked a new DataSource instance is created
    myDataSource= new MyDataSource(executor, searchKey);
    myDataSourceMutableLiveData.postValue(myDataSource);
    return myDataSource;
  }

  public MutableLiveData<MyDataSource> getMyDataSourceMutableLiveData() {
    return myDataSourceMutableLiveData;
  }

  public MyDataSource getMyDataSource() {
    return myDataSource;
  }

}
公共类MyDataSourceFactory扩展DataSource.Factory{
MutableLiveData myDataSourceMutableLiveData;
私有MyDataSource MyDataSource;
私人遗嘱执行人;
私有字符串搜索密钥;
公共MyDataSourceFactory(Executor Executor,字符串搜索键){
这个。执行者=执行者;
this.searchKey=searchKey;
this.myDataSourceMutableLiveData=new MutableLiveData();
}
@凌驾
公共数据源创建(){
//*注意:每次调用DataSource factory create()时,都会创建一个新的DataSource实例,这一点很重要
myDataSource=新的myDataSource(executor,searchKey);
myDataSourceMutableLiveData.postValue(myDataSource);
返回myDataSource;
}
公共可变LiveData getMyDataSourceMutableLiveData(){
返回myDataSourceMutableLiveData;
}
公共MyDataSource getMyDataSource(){
返回myDataSource;
}
}
对DataSource构造函数执行上述操作,以传递searchKey以在api调用中使用。 还有一件事,在您的Activity/Fragment(lifeCycleOwner)中,每当触发searchkey更改时,都会设置filterTextAll mutableLiveData的值,比如触发QueryTextChange上的searchview或任何您喜欢的事件

private void performSearch(String searchKey) {
        // TODO: Perform the search and update the UI to display the results.
            myViewModel.filterTextAll.setValue(searchKey);
            myViewModel.pagedListLiveData.observe(owner, new Observer<PagedList<MyItem>>() {
            @Override
            public void onChanged(PagedList<MyItem> myItems) {
              myAdapter.submitList(myItems);
            }
          }); 
            myViewModel.networkState.observe(owner, new Observer<NetworkState>() {
               @Override
               public void onChanged(NetworkState networkState) {
                  myAdapter.setNetworkState(networkState);
               }
           });

            myRecyclerView.setAdapter(myAdapter);
          }
private void性能搜索(字符串搜索键){
//TODO:执行搜索并更新UI以显示结果。
myViewModel.filterTextAll.setValue(搜索键);
myViewModel.pagedListLiveData.observe(所有者,新观察者(){
@凌驾
更改后的公共作废(页面列表myItems){
myAdapter.submitList(myItems);
}
}); 
myViewModel.networkState.observe(所有者,新观察者(){
@凌驾
更改后的公共无效(NetworkState NetworkState){
myAdapter.setNetworkState(networkState);
}
});
myRecyclerView.setAdapter(myAdapter);
}

它工作得很好。我知道我们也必须将input param用作实时数据。因此,每当输入发生更改时,Transformations.Switchmap()就会触发拉取新的数据源。没错。换句话说,每次更改searchKey(当调用filterTextAll.setValue(searchKey)方法时)都会触发Switchmap()调用转换并根据searchKey使用新值更新pagedListLiveData实例。如果我使用dagger注入DataSourceFactory和DataSource,如何实现这一点?我是否使用setter方法在DataSourceFactory和DataSource之间传播searchKey?