如何使用 JSON API 在滚动时在 recyclerview 中加载更多数据
Posted
技术标签:
【中文标题】如何使用 JSON API 在滚动时在 recyclerview 中加载更多数据【英文标题】:How to load more data in recyclerview on scroll using JSON API 【发布时间】:2021-08-29 04:55:37 【问题描述】:我正在滚动的 recyclerview 中实现分页。我正在从 JSON API 获取数据。下面是片段类的代码。第一页在 recyclerview 中成功加载,但是当我滚动到底部时,第二页没有加载并引发以下错误:
java.lang.IndexOutOfBoundsException:索引:10,大小:10
这是我的片段类:
public class LeadsFragment extends Fragment
RecyclerView recyclerView;
LeadsAdapter leadsAdapter;
List<LeadModel> rowsArrayList = new ArrayList<>();
private LinearLayoutManager layoutManager;
Toolbar toolbar;
private int page = 1;
private int totalItemCount;
private int firstVisibleItem;
private int visibleItemCount;
private int previousTotal;
private boolean isLoad=true;
String url;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_leads, container, false);
toolbar = view.findViewById(R.id.toolbar);
( (AppCompatActivity) getActivity() ).setSupportActionBar(toolbar);
( (AppCompatActivity) getActivity() ).getSupportActionBar().setTitle("");
url = "myurl?page="+page;
recyclerView = view.findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView);
recyclerView.setAdapter(leadsAdapter);
getAPIData();
pagination();
return view;
private void getAPIData()
StringRequest stringRequest = new StringRequest(Request.Method.GET, 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);
leadsAdapter.setItems(rowsArrayList);
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);
private void pagination()
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState)
super.onScrollStateChanged(recyclerView, newState);
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
if (dy > 0)
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
Log.e("visibleItemCount", "." + visibleItemCount);
Log.e("totalItemCount", "." + totalItemCount);
Log.e("firstVisibleItem", "." + firstVisibleItem);
if (isLoad)
if (totalItemCount > previousTotal)
previousTotal = totalItemCount;
page++;
isLoad = false;
Log.e("previousTotal", "." + previousTotal);
Log.e("Pageeeee", "." + page);
if (!isLoad && ( firstVisibleItem + visibleItemCount ) >= totalItemCount)
Log.e("Checking", "." + page);
getAPIData();
isLoad = true;
);
我的适配器类:
public class LeadsAdapter extends RecyclerView.Adapter<LeadsAdapter.ViewHolder>
Context context;
List<LeadModel> leadsModelList;
LeadsMeta leadsMetaList;
RecyclerView recyclerView;
final View.OnClickListener onClickListener = new MyOnClickListener();
public LeadsAdapter(Context context, List<LeadModel> leadsModelList, RecyclerView recyclerView)
this.context = context;
this.leadsModelList = leadsModelList;
this.recyclerView = recyclerView;
public void setItems(List<LeadModel> leadsModelList)
this.leadsModelList= new ArrayList<>(leadsModelList);
public static class ViewHolder extends RecyclerView.ViewHolder
TextView name, topic, sub_topic, city, credits, quotes;
public ViewHolder(@NonNull View itemView)
super(itemView);
name = itemView.findViewById(R.id.tvName);
topic = itemView.findViewById(R.id.tvTopic);
sub_topic = itemView.findViewById(R.id.tvSubTopic);
city = itemView.findViewById(R.id.tvLocation);
credits = itemView.findViewById(R.id.tvCredits);
quotes = itemView.findViewById(R.id.tvQuotes);
@NonNull
@Override
public LeadsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType)
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.lead_card, viewGroup, false);
view.setOnClickListener(onClickListener);
LeadsAdapter.ViewHolder viewHolder = new LeadsAdapter.ViewHolder(view);
return viewHolder;
@Override
public void onBindViewHolder(@NonNull LeadsAdapter.ViewHolder viewHolder, int position)
LeadModel leadsModel = leadsModelList.get(position);
viewHolder.name.setText(leadsModel.getData().get(position).getName());
@Override
public int getItemCount()
return leadsModelList.size();
【问题讨论】:
【参考方案1】:每当调用 getApi 方法发送新响应并将数据再次添加到列表时,但该列表未发送到适配器以更新新列表。 而不是这样 leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView); 在adapter中创建一个以list为参数的方法,并将arraylist传递给方法,并在有新数据响应时通知。
【讨论】:
我正在调用leadsAdapter.notifyDataSetChanged(); 请再次阅读我的回答。您必须再次将数组列表发送到适配器。 你能再解释一下吗 不是在适配器构造函数中发送arraylist,而是在适配器中创建一个公共方法并在notifydatasetchanged之前传递arraylist。 参考这个***.com/questions/35147466/…以上是关于如何使用 JSON API 在滚动时在 recyclerview 中加载更多数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在远程访问其 JSON API 时在 Jenkins 中进行身份验证?
如何使用 JSON API 在 recyclerview 滚动上加载更多数据
在 400 HTTP 响应时在警报视图上显示 API 响应 JSON 格式的错误结果