使用 Laravel API 进行滚动分页

Posted

技术标签:

【中文标题】使用 Laravel API 进行滚动分页【英文标题】:scroll pagination with Laravel API 【发布时间】:2018-06-15 00:01:39 【问题描述】:

我在 android 中使用带有分页数据的 Laravel API...

我想获取自动分页数据。 例如第一页上的数据首先加载,当我向下滚动时,下一页继续加载!

【问题讨论】:

也许这个链接可以帮助trinitytuts.com/android-listview-with-scrolload 这里也是androhub.com/load-more-items-on-scroll-android 【参考方案1】:

在 Laravel 方面

// Get Collection
$query = SomeModel::where('some_thing', "5")
->paginate(10);

return Response::json(array(
            'some_result' => $query,
        ));

在 Android 端(改造调用)

@FormUrlEncoded
@POST
Call<JsonObject> getActions(
        @Url String url);

在 Android 端(活动/片段)

public class NewTemplateActivity
        extends AppCompatActivity 

    // Recycler View
    private SomeActionListAdapter someActionsAdapter;
    private List<SomesomeActionListModel> listSomeActionModel;
    private RecyclerView rv;

    private Boolean isScrolling = false;
    private int currentItems, totalItems, scrollOutItems;
    private int pageNumber = 1;
    private Boolean firstLoad = true;
    private Boolean firstSearch = false;
    private LinearLayoutManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) 

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        // Init Recycler View
        rv = findViewById(R.id.f_list_rv_list);
        rv.setHasFixedSize(true);
        listSomeActionModel = new ArrayList<>();
        someActionsAdapter = new SomeActionListAdapter(
                mContext,
                listSomeActionModel);

        manager = new LinearLayoutManager(mContext);
        rv.setLayoutManager(manager);
        rv.setAdapter(someActionsAdapter);
    

    private void getSomeAction(
            String url) 

        if (firstLoad || firstSearch) 
            listSomeActionModel.clear();
        

        // Retrofit Call
        Call<JsonObject> call = RetrofitClientLaravel.getInstance(mContext)
                                                     .discussGetApi()
                                                     .getSomeAction(url);

        call.enqueue(new Callback<JsonObject>() 

            @Override
            public void onResponse(
                    Call<JsonObject> call,
                    Response<JsonObject> response) 

                JSONObject jsonObject;
                try 
                    jsonObject = new JSONObject(new Gson().toJson(response.body()));

                    // Get The Relevant Array
                    JSONObject jsonObject2 = jsonObject.getJSONObject("some_result");
                    JSONArray returnArray = jsonObject2.getJSONArray("data");

                    onScrolled();

                    if (!returnArray.isNull(0)) 

                        for (int l = 0; l < returnArray.length(); l++) 
                            if (returnArray.length() > 0) 

                                // Get The Json Object
                                JSONObject returnJSONObject = returnArray.getJSONObject(l);

                                // Get Details
                                String id = returnJSONObject.optString("SomesomeAction_id");

                                // Populate The Array List
                                listSomeActionModel.add(new SomesomeActionListModel(id));
                            
                        
                    

                    if (firstLoad || firstSearch) 

                        someActionsAdapter = new SomeActionListAdapter(
                                mContext,
                                listSomeActionModel);
                        rv.setAdapter(someActionsAdapter);
                    

                    someActionsAdapter.notifyDataSetChanged();
                 catch (JSONException e) 
                    e.printStackTrace();
                
            

            @Override
            public void onFailure(
                    Call<JsonObject> call,
                    Throwable t) 

            
        );
    

    public void onScrolled() 

        rv.addOnScrollListener(new RecyclerView.OnScrollListener() 
            @Override
            public void onScrollStateChanged(
                    RecyclerView recyclerView,
                    int newState) 
                super.onScrollStateChanged(
                        recyclerView,
                        newState);
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) 
                    isScrolling = true;
                
            

            @Override
            public void onScrolled(
                    RecyclerView recyclerView,
                    int dx,
                    int dy) 
                super.onScrolled(
                        recyclerView,
                        dx,
                        dy);

                currentItems = manager.getChildCount();
                totalItems = manager.getItemCount();
                scrollOutItems = manager.findFirstVisibleItemPosition();

                if (isScrolling && (currentItems + scrollOutItems == totalItems)) 
                    isScrolling = false;
                    firstLoad = false;
                    firstSearch = false;

                    Toast.makeText(
                            mContext,
                            "Loading More...",
                            Toast.LENGTH_SHORT)
                         .show();

                    pageNumber++;

                    getSomeAction(Env.LARAVEL_MAIN_URL +
                                  "/api/get_SomesomeActions" +
                                  "?page=" +
                                  pageNumber);
                
            
        );
    

【讨论】:

【参考方案2】:

您可以使用 LengthAwarePaginator 轻松做到这一点

protected function paginate(Collection $collection)

    $rules = [
        'per_page' => 'integer|min:2|max:50',
    ];

    Validator::validate(request()->all(), $rules);

    $page = LengthAwarePaginator::resolveCurrentPage();

    $perPage = 15;
    if (request()->has('per_page')) 
        $perPage = (int) request()->per_page;
    

    $results = $collection->slice(($page - 1) * $perPage, $perPage)->values();

    $paginated = new LengthAwarePaginator($results, $collection->count(), $perPage, $page, [
        'path' => LengthAwarePaginator::resolveCurrentPath(),
    ]);

    $paginated->appends(request()->all());

    return $paginated;


确保导入所有需要的命名空间, 您可以继续对集合进行分页

$collection = $this->paginate($collection);

希望对你有帮助

【讨论】:

【参考方案3】:

你可以在获取行的状态下使用 laravel 默认的分页方法。

例如我想显示用户列表:

//状态:

$users = User::get();

//使用:

$users = User::paginate();

更多信息:laravel 网站 https://laravel.com/docs/5.5/pagination

【讨论】:

我的查询与 android 而不是 laravel 有关。我的 API 已经有分页数据

以上是关于使用 Laravel API 进行滚动分页的主要内容,如果未能解决你的问题,请参考以下文章

在 laravel 中对数据数组进行分页并在 vuejs 中使用无限滚动的最佳方法

如何使用 Laravel API 资源对加载的关系进行分页

使用 Laravel 5.8 对没有数据库(计数)的 API 响应进行分页

使用 Laravel 进行分页

Laravel 5 分页 + 无限滚动 jQuery

Laravel使用无限滚动分页