如何在Android分页库中为列表,过滤器和搜索维护相同的数据源 [英] How to maintain same DataSource for List,Filter and Search in Android Paging Library

查看:115
本文介绍了如何在Android分页库中为列表,过滤器和搜索维护相同的数据源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在进行显示项目列表的活动,并且还具有过滤器和搜索选项。我正在使用android分页库显示项目。第一次滚动项目列表时,当我滚动到要加载的下一组项目的底部时,它的工作正常。但我也想过滤项目并搜索项目。在筛选或搜索项目上,我使现有资源无效。如果没有使数据源无效,则过滤器和Search api无法触发。我想使用数据源基于我的过滤器和搜索键加载新项目列表。

I am having activity that displays list of items and also having filter and search option. I am displaying the items using android paging library. First time the List of items will be loaded its working fine when I am Scrolling to bottom next set of items getting loaded. But I also want to filter the items and Search the items. On Filtering or Searching item I am invalidating the existing source.if am not invalidate the Data Source the filter and Search api is not firing.I want to load list of new items based on my filter and Search key using Data Source.

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;
}

Retrofit API调用:

 Call<CelebrityList> getCelebrityList(@Query("categoryId") String categoryId,
                                     @Query("professionId") String professionId,
                                     @Query("page") String pageNumber,
                                     @Query("name") String searchKey);

数据源Api回调:

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()));
            }
        }


推荐答案

您需要在实时数据中按住搜索键,以便页面列表可以随时更改。因此,在您的视图模型中,定义:

You need to hold your search key in live data so that pagedlist can be changed whenever it changes. So in your viewmodel, define:

public MutableLiveData<String> filterTextAll = new MutableLiveData<>();

由于分页列表也被定义为LiveData,因此可以在Transformation的帮助下完成。 Transformations类为您提供了可以更改LiveData对象中的值的函数。 swithMap函数返回一个新的LiveData对象而不是一个值,在您的情况下,通过在后台创建新的数据源,将searchkey切换为获取与searchkey相对应的pagedList对象。

Since the pagedlist is defined as a LiveData too, this can be done with the help of Transformation. Transformations class provide you with functions with which you can change the value in your LiveData object. swithMap function returns a new LiveData object rather than a value, in your case, searchkey is switched to get the pagedList object corresponding to the searchkey by create new datasource under the hood.

pagedListLiveData = Transformations.switchMap(filterTextAll, input -> {
        MyDataSourceFactory myDataSourceFactory = new MyDataSourceFactory(executor,input);
        myDataSource = myDataSourceFactory.getMyDataSourceMutableLiveData();
        networkState = Transformations.switchMap(myDataSource,
        dataSource -> dataSource.getNetworkState());
        return (new LivePagedListBuilder(myDataSourceFactory, pagedListConfig))
          .setFetchExecutor(executor)
          .build();
      });

您可以更改DataSourceFactory和DataSource构造函数以添加searchKey参数:

You can to change your DataSourceFactory and DataSource constructor to add searchKey param:

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;
  }

}

对于DataSource构造函数执行与上述相同的操作传递可在api调用中使用的searchKey。
还有一件事,只要触发搜索键更改(例如触发searchview onQueryTextChange或您喜欢的任何事件),就在您的Activity / Fragment(lifeCycleOwner)中设置filterTextAll mutableLiveData的值。

do same like above for DataSource constructor to pass searchKey to use in api call. And one thing remains, in your Activity/Fragment (lifeCycleOwner) set value of filterTextAll mutableLiveData whenever searchkey change fired, like trigger searchview onQueryTextChange or any event you like.

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);
          }

这篇关于如何在Android分页库中为列表,过滤器和搜索维护相同的数据源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆