搜索查询的Android分页

搜索查询的Android分页,android,android-recyclerview,pagination,retrofit2,android-paging,Android,Android Recyclerview,Pagination,Retrofit2,Android Paging,我是android开发新手,正在尝试为我的应用程序构建UI。 该应用程序与REST后端集成,后者接受搜索查询和项目列表作为响应 interface RetrofitEndpoint { @GET("paged/list/endpoint") Call<PagedList<Object>> getPagedList(@Query("query") String query, @Query("pageSize

我是android开发新手,正在尝试为我的应用程序构建UI。 该应用程序与REST后端集成,后者接受搜索查询和项目列表作为响应

interface RetrofitEndpoint {

    @GET("paged/list/endpoint")
    Call<PagedList<Object>> getPagedList(@Query("query") String query, @Query("pageSize") int pageSize, Query("pageOffset") int pageOffset);
}
接口端点{
@获取(“分页/列表/端点”)
调用getPagedList(@Query(“Query”)字符串查询、@Query(“pageSize”)int pageSize、Query(“pageOffset”)int pageOffset);
}
UI一次向用户显示一个项目

我正在将列表加载到recyclerview中

public class SomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Object> list;


    // .. other overridden members

    public void setList(List<Object> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    public void addAll(List<Object> newList) {
        int lastIndex = list.size() - 1;
        list.addAll(newList);
        notifyItemRangeInserted(lastIndex, newList.size());
    }
}
公共类SomeAdapter扩展了RecyclerView.Adapter{ 私人名单; //…其他被否决的成员 公共无效集合列表(列表){ this.list=列表; notifyDataSetChanged(); } 公共void addAll(列表newList){ int lastIndex=list.size()-1; list.addAll(newList); notifyItemRangeInserted(lastIndex,newList.size()); } }
我无法弄清楚的是,当我到达recyclerview的末尾(或之前)时,如何加载更多数据以避免延迟,是否有任何库/API可以这样做?

您可以将
onScrollStateChanged
侦听器添加到recyclerview,以检测recyclerview的当前位置,然后添加逻辑以获取所需的特定条件

,以便分页列表正常工作。它需要在应用程序中添加更多内容。此实现使用视图模型、实时数据和房间持久性,因此可以脱机工作

你的build.gradle:

// ViewModel
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"

def room_version = "2.2.5"

implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"

def paging_version = "2.1.2"
implementation "androidx.paging:paging-runtime:$paging_version"    
改装空气污染指数:

interface RetrofitEndpoint {

    @GET("paged/list/endpoint")
    Call<List<YourObject>> getYourObjectList(@Query("query") String query, @Query("pageSize") int pageSize, Query("pageOffset") int pageOffset);
}
道:

YourObjectBoundaryCallback:

public class YourObjectBoundaryCallback extends PagedList.BoundaryCallback<YourObject> {
    private AppExecutors executors;
    private Database database;
    private YourObjectDao dao;
    private Integer page_number;

    public YourObjectBoundaryCallback (Application application, AppExecutors executors) {
        //super();
        this.executors = executors;
        database = Database.getInstance(application);
        dao = database.get_your_object_dao();
        page_number=1;
    }

    @Override
    public void onZeroItemsLoaded() {
        super.onZeroItemsLoaded();
        Log.d("log", "yourObjects onzeroitemsloaded");
        fetchYourObjects(page_number);
    }

    @Override
    public void onItemAtFrontLoaded(@NonNull YourObject itemAtFront) {
        super.onItemAtFrontLoaded(itemAtFront);
        Log.d("log", "yourObjects onItemAtFrontLoaded");
    }

    @Override
    public void onItemAtEndLoaded(@NonNull YourObject itemAtEnd) {
        super.onItemAtEndLoaded(itemAtEnd);
        Log.d("log", "yourObjects onItemAtEndLoaded");
        page_number=page_number+1;
        fetchYourObjects(page_number);
    }

    public void fetchYourObjects(int pageNumber) {
        RetrofitApi retrofitApi = RetrofitInstance.getRetrofitEndpoint();
        Call<List<YourObject>> call = retrofitApi.getYourObjectList(query, pageSize,pageNumber);
        call.enqueue(new Callback<List<YourObject>>() {
            @Override
            public void onResponse(Call<List<YourObject>> call, Response<List<YourObject>> response) {
                if (!response.isSuccessful()) {
                    Log.d("log", "YourObjects Response unsuccesful: " + response.code());
                    return;
                }
                Log.d("log", "YourObjects Response ok: " + response.code());
                List<YourObject> yourObjectsList = response.body();
                insertListToDb(yourObjectsList );
            }

            @Override
            public void onFailure(Call<List<YourObject>> call, Throwable t) {
                Log.d("log", "yourObjects onFailure: " + t.getMessage());
            }
        });
    }


    public void insertListToDb(List<YourObject> list) {
        Runnable runnable = () -> {
            dao.insertList(list);
        };
        Runnable diskRunnable = () -> database.runInTransaction(runnable);
        executors.diskIO().execute(diskRunnable);
    }
    }
在您的活动/片段中:

yourObjectsViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(YourObjectsViewModel.class);
yourObjectsViewModel.getYourObjectPagedList().observe(getViewLifecycleOwner(), new Observer<PagedList<TopRatedMovie>>() {
        @Override
        public void onChanged(PagedList<YourObject> results) {
            Log.d("log", "  onChanged list size: " + results.size());
            yourAdapter.submitList(results);
           
        }
    });
yourObjectsViewModel=new ViewModelProvider(这是ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication()).get(yourObjectsViewModel.class);
yourObjectsViewModel.getYourObjectPagedList().observe(getViewLifecycleOwner(),new Observer()){
@凌驾
更改后的公共作废(页面列表结果){
d(“Log”,“onChanged列表大小:”+results.size());
yourAdapter.submitList(结果);
}
});
在适配器中:

 public class YourPagedListAdapter extends PagedListAdapter<YourObject, 
 RecyclerView.ViewHolder> {
public类YourPagedListAdapter扩展了PagedListAdapter{

如果您有任何问题,请随时提问。

您希望仅使用网络还是使用数据库+网络进行回答?我最近已经完成了这两项工作,因此我可以帮助您……您可以分享这两项吗?Srdoc也可以看看我的问题。
public class YourObjectBoundaryCallback extends PagedList.BoundaryCallback<YourObject> {
    private AppExecutors executors;
    private Database database;
    private YourObjectDao dao;
    private Integer page_number;

    public YourObjectBoundaryCallback (Application application, AppExecutors executors) {
        //super();
        this.executors = executors;
        database = Database.getInstance(application);
        dao = database.get_your_object_dao();
        page_number=1;
    }

    @Override
    public void onZeroItemsLoaded() {
        super.onZeroItemsLoaded();
        Log.d("log", "yourObjects onzeroitemsloaded");
        fetchYourObjects(page_number);
    }

    @Override
    public void onItemAtFrontLoaded(@NonNull YourObject itemAtFront) {
        super.onItemAtFrontLoaded(itemAtFront);
        Log.d("log", "yourObjects onItemAtFrontLoaded");
    }

    @Override
    public void onItemAtEndLoaded(@NonNull YourObject itemAtEnd) {
        super.onItemAtEndLoaded(itemAtEnd);
        Log.d("log", "yourObjects onItemAtEndLoaded");
        page_number=page_number+1;
        fetchYourObjects(page_number);
    }

    public void fetchYourObjects(int pageNumber) {
        RetrofitApi retrofitApi = RetrofitInstance.getRetrofitEndpoint();
        Call<List<YourObject>> call = retrofitApi.getYourObjectList(query, pageSize,pageNumber);
        call.enqueue(new Callback<List<YourObject>>() {
            @Override
            public void onResponse(Call<List<YourObject>> call, Response<List<YourObject>> response) {
                if (!response.isSuccessful()) {
                    Log.d("log", "YourObjects Response unsuccesful: " + response.code());
                    return;
                }
                Log.d("log", "YourObjects Response ok: " + response.code());
                List<YourObject> yourObjectsList = response.body();
                insertListToDb(yourObjectsList );
            }

            @Override
            public void onFailure(Call<List<YourObject>> call, Throwable t) {
                Log.d("log", "yourObjects onFailure: " + t.getMessage());
            }
        });
    }


    public void insertListToDb(List<YourObject> list) {
        Runnable runnable = () -> {
            dao.insertList(list);
        };
        Runnable diskRunnable = () -> database.runInTransaction(runnable);
        executors.diskIO().execute(diskRunnable);
    }
    }
public class YourObjectsRepository {
private LiveData<PagedList<YourObject>> yourObjectsPagedList;
private YourObjectBoundaryCallback yourObjectsBoundaryCallback;
private AppExecutors executors;


public YourObjectsRepository (Application application, AppExecutors executors) {
    this.executors = executors;
    Database database = Database.getInstance(application);
    YourObjectDao dao = database.get_your_object_dao();
    yourObjectsBoundaryCallback= new YourObjectBoundaryCallback (application, executors);
    createYourObjectsPagedList(dao );

}

//this is configuration for your paged list, adjust per your requirements
private PagedList.Config getPagedListConfig(){
    return  (new PagedList.Config.Builder())
            .setEnablePlaceholders(false)
            .setPrefetchDistance(40)
            .setInitialLoadSizeHint(60)
            .setPageSize(20).build();
}

private void createYourObjectsPagedList(YourObjectDao dao){
    yourObjectsPagedList= new LivePagedListBuilder<>(dao.getAllResults(), getPagedListConfig())
      .setBoundaryCallback(yourObjectsBoundaryCallback).setFetchExecutor(executors.networkIO())
            .build();
}

public LiveData<PagedList<YourObject>> getYourObjectsPagedList() {
    return yourObjectsPagedList;
}
}
public class YourObjectsViewModel extends AndroidViewModel {

    private YourObjectsRepository repo;

    public YourObjectsViewModel (@NonNull Application application) {
        super(application);
        AppExecutors  executors = new AppExecutors();
        repo= new YourObjectsRepository (application, executors);
    }


    public LiveData<PagedList<YourObject>> getYourObjectsPagedList() {
        return repo.getYourObjectsPagedList();
    }
}
public class AppExecutors {
private final Executor diskIO;
private final Executor networkIO;
private final Executor mainThread;
private final Executor others;
private final Executor paging;

    public AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread, Executor others, Executor paging) {
        this.diskIO = diskIO;
        this.networkIO = networkIO;
        this.mainThread = mainThread;
        this.others = others;
        this.paging = paging;
    }
    public AppExecutors() {
        this(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3),
                new MainThreadExecutor(), Executors.newSingleThreadExecutor(),
                Executors.newFixedThreadPool(4));
    }

    public Executor diskIO() {
        return diskIO;
    }

    public Executor networkIO() {
        return networkIO;
    }

    public Executor mainThread() {
        return mainThread;
    }

    public Executor others() {
        return others;
    }

    public Executor paging() {
        return paging;
    }

    private static class MainThreadExecutor implements Executor {
        private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
        @Override
        public void execute(@NonNull Runnable command) {
            mainThreadHandler.post(command);
        }
    }
}
yourObjectsViewModel = new ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(YourObjectsViewModel.class);
yourObjectsViewModel.getYourObjectPagedList().observe(getViewLifecycleOwner(), new Observer<PagedList<TopRatedMovie>>() {
        @Override
        public void onChanged(PagedList<YourObject> results) {
            Log.d("log", "  onChanged list size: " + results.size());
            yourAdapter.submitList(results);
           
        }
    });
 public class YourPagedListAdapter extends PagedListAdapter<YourObject, 
 RecyclerView.ViewHolder> {