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