0

I am fetching data from api and showing them into recyclerview.

I am using InfiniteScroll to load more data on scroll.

It works fine if I scroll smoothly but if I scroll fast I get NullPointerException as data is not being fetched on time even after I am checking if model data is not null in Adapter class.

How to avoid this situation?

Please find the code below:

 @NonNull
private InfiniteScrollListener createInfiniteScrollListener() {
    return new InfiniteScrollListener(10, linearLayoutManager) {
        @Override public void onScrolledToEnd(final int firstVisibleItemPosition) {
                offset += 10;

                final List<Purchase2> itemsLocal = loadMore(offset);
                refreshView(recyclerView, new PurchaseMainTestAdapter(itemsLocal, R.layout.list_orders_layout, getApplicationContext(), emptyView), firstVisibleItemPosition);
        }
    };
}

private List<Purchase2> loadMore(int index){
    progressBar.setVisibility(View.VISIBLE);
    //add loading progress view
    purchases.add(new Purchase2());
    adapter.notifyItemInserted(purchases.size()-1);

    OneViewApi apiService =
            ApiClient.getClient().create(OneViewApi.class);
    Call<Orders> call;
    call = apiService.getPurchaseData(auth_token,index,10);
    Log.d("Called url is:", call.request().url().toString());
    call.enqueue(new Callback<Orders>() {
        @Override
        public void onResponse(Call<Orders> call, Response<Orders> response) {
            if(response.isSuccessful()){

                //remove loading view
                purchases.remove(purchases.size()-1);

                List<Purchase2> result = response.body().getPurchases();
                if(result.size()>0){
                    //add loaded data
                    purchases.addAll(result);
                }else{//result size 0 means there is no more data available at server
                    adapter.setMoreDataAvailable(false);

                    Toast.makeText(getApplicationContext(),"No More Data Available",Toast.LENGTH_LONG).show();
                }

                progressBar.setVisibility(View.GONE);
                //should call the custom method adapter.notifyDataChanged here to get the correct loading status
            }else{
                Log.e("Item list"," Load More Response Error "+String.valueOf(response.code()));
            }
        }

        @Override
        public void onFailure(Call<Orders> call, Throwable t) {
            Log.e("Item list"," Load More Response Error "+t.getMessage());
        }
    });
    return purchases;
}
amit srivastava
  • 743
  • 6
  • 25

2 Answers2

1

at first use try{} catch{} then trace your code via break point to fine where exception happened

but i guess exception occur in here :purchases.remove(purchases.size()-1); that your list is null and you are trying to remove an item.(in first time) or about adding and removing items.

but for detect showing load more or not you can add null to purchases list then handle it in adapter - it's too better

Saeid
  • 2,261
  • 4
  • 27
  • 59
0

Got the fix for this null pointer Exception:

1.) Added adapter code inside

try{} catch{} block

2.) Has set the flag so that on scroll it could not call the service again until last one is executed

if(!isLoading) {
                isLoading = true;

                    final List<Purchase2> itemsLocal = loadMorePurchaseData(offset, null, null, null);
                    refreshView(recyclerView, new PurchaseMainAdapter(itemsLocal, R.layout.list_orders_layout, getApplicationContext(), emptyView), firstVisibleItemPosition);}

And in network call set the appropriate flag:

     public void onResponse(Call<Orders> call, Response<Orders> response) {
            if(response.isSuccessful()){



                List<Purchase2> result = response.body().getPurchases();
                if(result.size()>0){
                    //add loaded data
                    purchases.addAll(result);
                }else{//result size 0 means there is no more data available at server
                    purchase_adapter.setMoreDataAvailable(false);
                    //telling adapter to stop calling load more as no more server data available
                    Toast.makeText(getApplicationContext(),"No More Data Available",Toast.LENGTH_LONG).show();
                }

                progressBar.setVisibility(View.GONE);
                isLoading = false;
                //should call the custom method adapter.notifyDataChanged here to get the correct loading status
            }else{
                Log.e("Item list"," Load More Response Error "+String.valueOf(response.code()));
            }

Thanks everyone for giving the hint.

amit srivastava
  • 743
  • 6
  • 25