0

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: Index: 10, Size: 10

This is my Fragment Class:

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;
                    }
                }
            }
        });

    }
}

My Adapter Class:

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 Answers1

0

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.

Brendon
  • 1,368
  • 1
  • 12
  • 28