如何使用 JSON API 在滚动时在 recyclerview 中加载更多数据 [英] How to load more data in recyclerview on scroll using JSON API
问题描述
我正在滚动的 recyclerview 中实现分页.我正在从 JSON API 获取数据.下面是片段类的代码.第 1 页在 recyclerview 中成功加载,但是当我滚动到底部时,第 2 页未加载并引发以下错误:
I am implementing pagination in recyclerview on scroll. I am fetching data from JSON API. Below is the code of Fragment Class. 1st page is loading successfully in recyclerview, but when I scroll to bottom 2nd page is not loading and throws the following error:
java.lang.IndexOutOfBoundsException:索引:10,大小:10
java.lang.IndexOutOfBoundsException: Index: 10, Size: 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();
}
}
推荐答案
每当调用 getApi 方法发送新响应并将数据再次添加到列表时,但该列表不会发送到适配器以更新新列表.而不是这样LeadAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView);在adapter中创建一个以list为参数的方法,并将arraylist传递给method,并在有新数据响应时通知.
Whenever calling getApi method sends new response and adding data again to the list, but that list not sent to adapter to update new list. Instead of like this leadsAdapter = new LeadsAdapter(getContext(), rowsArrayList, recyclerView); Create a method in adapter with list as a parameter and pass the arraylist to method and notify when new data response.
这篇关于如何使用 JSON API 在滚动时在 recyclerview 中加载更多数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!