如何使用 JSON API 在 recyclerview 滚动上加载更多数据

Posted

技术标签:

【中文标题】如何使用 JSON API 在 recyclerview 滚动上加载更多数据【英文标题】:How to load more data on recyclerview scroll with JSON API 【发布时间】:2021-08-29 02:57:59 【问题描述】:

我想在 Recyclerview 滚动条上加载下一页数据(当用户滚动到底部时)。我再次调用 API 以获取下一页数据并通知适配器,但似乎我做错了什么。请帮我看看这段代码有什么问题。

This is my previous question where all code pasted

这是片段类。

public class LeadsFragment extends Fragment 

    boolean isLoading = false;
    RecyclerView recyclerView;
    LeadsAdapter leadsAdapter;
    ArrayList<LeadModel> rowsArrayList = new ArrayList<>();
    RecyclerView.LayoutManager layoutManager;
    private static final String url = "myurl";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 

        View view = inflater.inflate(R.layout.fragment_leads, container, false);

        StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() 
            @Override
            public void onResponse(String response) 

                GsonBuilder gsonBuilder = new GsonBuilder();
                Gson gson = gsonBuilder.create();

                LeadModel leadModelList = gson.fromJson(response, LeadModel.class);
                for (int i = 0; i < leadModelList.getData().size(); i++) 
                    rowsArrayList.add(leadModelList);
                

                recyclerView.setHasFixedSize(true);
                layoutManager = new LinearLayoutManager(getActivity());
                recyclerView.setLayoutManager(layoutManager);
                leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView);
                recyclerView.setAdapter(leadsAdapter);

            
        , new Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 

                Toast.makeText(getContext(), error.toString(), Toast.LENGTH_SHORT).show();

            
        );

        RequestQueue queue = Volley.newRequestQueue(getContext());
        queue.add(stringRequest);

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() 
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) 
                super.onScrolled(recyclerView, dx, dy);
                LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
                if (!isLoading) 
                    if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == 10 - 1) 
                        // Last item reached
                        loadMore(); // Note this method
                        isLoading = true;
                    
                
            
        );

        return view;

    

    private void loadMore() 

        StringRequest stringRequest = new StringRequest(url + "?page=2", new Response.Listener<String>() 
            @Override
            public void onResponse(String response) 

                GsonBuilder gsonBuilder = new GsonBuilder();
                Gson gson = gsonBuilder.create();

                LeadModel leadModelList = gson.fromJson(response, LeadModel.class);
                for (int i = 0; i < leadModelList.getData().size(); i++) 
                    rowsArrayList.add(leadModelList);
                
                leadsAdapter.notifyDataSetChanged();
                isLoading = false;
            
        , new Response.ErrorListener() 
            @Override
            public void onErrorResponse(VolleyError error) 

                Toast.makeText(getContext(), error.toString(), Toast.LENGTH_SHORT).show();

            
        );

        RequestQueue queue = Volley.newRequestQueue(getContext());
        queue.add(stringRequest);
    


【问题讨论】:

你这样做是错误的。请观看此video。这不是实现分页的正确方法,但它可以帮助您了解如何实现它。顺便说一句,它在改造中 帮助了一点。但没有解决我的问题。你有凌空库的例子吗。 【参考方案1】:

这是更好的工作,因为自从我开始使用 android 以来,我就没有使用过 Volley 库。但这是一个如何实现分页的示例

在您的 XML 中

<androidx.core.widget.NestedScrollView
            android:id="@+id/NestedScroll"
            android:layout_
            android:layout_
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <LinearLayout
                android:layout_
                android:layout_
                android:gravity="center"
                android:orientation="vertical">


                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/HomeRecycler"
                    android:layout_
                    android:layout_
                    android:nestedScrollingEnabled="true"
                    tools:listitem="@layout/home_recycler_list_layout" />

                <ProgressBar
                    android:id="@+id/ProgressBar"
                    android:layout_
                    android:layout_
                    android:visibility="gone"/>

            </LinearLayout>
        </androidx.core.widget.NestedScrollView>

在你的班级里

ArrayList<LeadModel> rowsArrayList = new ArrayList<>();
SwipeRefreshLayout SwipeDown;
ProgressBar progressBar;
NestedScrollView nestedScrollView;
int Page = 0;
LeadsAdapter leadsAdapter;
RecyclerView recyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);
    nestedScrollView = findViewById(R.id.NestedScroll);
    progressBar = findViewById(R.id.ProgressBar);
    recyclerView= findViewById(R.id.HomeRecycler);

    nestedScrollView.setOnScrollChangeListener(new 
    NestedScrollView.OnScrollChangeListener() 
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) 
            if (scrollY == v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight()) 
                Page++;
                progressBar.setVisibility(View.VISIBLE);
                getData(Page);
            
        
    );
 
    recyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);
    leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView);
    recyclerView.setAdapter(leadsAdapter);

    getData(Page);


private void getData(int Page) 

    StringRequest stringRequest = new StringRequest(url + "?page="+Page, new Response.Listener<String>() 
        @Override
        public void onResponse(String response) 
            progressBar.setVisibility(View.INVISIBLE);
            // set Progress dialog Visibility to INVISIBLE or GONE if response is success
            GsonBuilder gsonBuilder = new GsonBuilder();
            Gson gson = gsonBuilder.create();

            LeadModel leadModelList = gson.fromJson(response, LeadModel.class);
            for (int i = 0; i < leadModelList.getData().size(); i++) 
                rowsArrayList.add(leadModelList);
            
            leadsAdapter.notifyDataSetChanged();
        
    , new Response.ErrorListener() 
        @Override
        public void onErrorResponse(VolleyError error) 

            Toast.makeText(getContext(), error.toString(), Toast.LENGTH_SHORT).show();

        
    );

    RequestQueue queue = Volley.newRequestQueue(getContext());
    queue.add(stringRequest);

【讨论】:

我在 [这里] (***.com/questions/67950692/…) 做同样的事情,但得到 java.lang.IndexOutOfBoundsException: Index: 10, Size: 10 error 是的,我试过了,得到同样的错误:索引:10,大小:10 错误 请分享您的 api 响应 Here is my all class and api data 我正在获取关于滚动和更新适配器的第二页数据,但我认为 onBindView 位置没有更新。

以上是关于如何使用 JSON API 在 recyclerview 滚动上加载更多数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter中使用API​​调用嵌套的json数据?

模拟 API 响应时如何在单元测试中使用 JSON 文件

如何使用 JS API 查询 JSON 以返回 JSON 属性?

如何使用 Alamofire SWIFT 在 post api 中发送 JSON

如何在 Alamofire 中使用相同的 API 函数 .PUT 请求更新 JSON

Twitter API - 如何将 JSON 存储在数组中?