Endless Scroll RecyclerView always return to top

2.5k views Asked by At

I have a problem with the endless scroll. Every time it loads more data, it returns to the top view. What I want is the RecyclerView to stay in the last position when it loads new data. I am trying to implement this code https://github.com/codepath/android_guides/wiki/Endless-Scrolling-with-AdapterViews-and-RecyclerView

here is the endless scroll code

public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener{
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 30;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;

RecyclerView.LayoutManager mLayoutManager;

public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
    this.mLayoutManager = layoutManager;
}

public int getLastVisibleItem(int[] lastVisibleItemPositions) {
    int maxSize = 0;
    for (int i = 0; i < lastVisibleItemPositions.length; i++) {
        if (i == 0) {
            maxSize = lastVisibleItemPositions[i];
        }
        else if (lastVisibleItemPositions[i] > maxSize) {
            maxSize = lastVisibleItemPositions[i];
        }
    }
    return maxSize;
}

// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScrolled(RecyclerView view, int dx, int dy) {
    int lastVisibleItemPosition = 0;
    int totalItemCount = mLayoutManager.getItemCount();

    if (mLayoutManager instanceof LinearLayoutManager) {
        lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
    }

    // If the total item count is zero and the previous isn't, assume the
    // list is invalidated and should be reset back to initial state

    if (totalItemCount < previousTotalItemCount) {
        this.currentPage = this.startingPageIndex;
        this.previousTotalItemCount = totalItemCount;
        if (totalItemCount == 0) {
            this.loading = true;
        }
    }
    // If it’s still loading, we check to see if the dataset count has
    // changed, if so we conclude it has finished loading and update the current page
    // number and total item count.
    if (loading && (totalItemCount > previousTotalItemCount)) {
        loading = false;
        previousTotalItemCount = totalItemCount;
    }

    // If it isn’t currently loading, we check to see if we have breached
    // the visibleThreshold and need to reload more data.
    // If we do need to reload some more data, we execute onLoadMore to fetch the data.
    // threshold should reflect how many total columns there are too
    if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
        currentPage++;
        onLoadMore(currentPage, totalItemCount, view);
        loading = true;
    }
}

// Call this method whenever performing new searches
public void resetState() {
    this.currentPage = this.startingPageIndex;
    this.previousTotalItemCount = 0;
    this.loading = true;
}

// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);

}

OnCreateView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    View view = inflater.inflate(R.layout.booking_fragment, container, false);

    recyclerView = (RecyclerView) view.findViewById(R.id.bookingRecyclerView);
    linearLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setHasFixedSize(true);

scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) {
        @Override
        public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
            // Triggered only when new data needs to be appended to the list
            // Add whatever code is needed to append new items to the bottom of the list


            if(CurrentStatus.equals("notSearch")){
                if (current < Integer.parseInt(TP)) {
                    current++;
                    loadMoreBookings(sort);
                }
                else if(current == Integer.parseInt(TP)){
                    Toast.makeText(getActivity(),"No More Data to Load", Toast.LENGTH_SHORT).show();
                }
            }else{
                if (current < Integer.parseInt(TP)) {
                    current++;
                    searchMoreBookings(search, sort);
                }
                else if(current == Integer.parseInt(TP)){
                    Toast.makeText(getActivity(),"No More Data to Be Load", Toast.LENGTH_SHORT).show();
                }
            }
        }

LoadMoreBookings

private void loadMoreBookings(final String sort){
    CurrentStatus = "notSearch";
    final ProgressDialog progressDialog = new ProgressDialog(getActivity());
    progressDialog.setMessage("Please Wait While Retrieving Data");
    progressDialog.setCancelable(false);
    progressDialog.show();
    StringRequest requesting = new StringRequest(Request.Method.POST, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String JSONString) {
                    progressDialog.dismiss();
                    try{
                        JSONObject jsonTP = new JSONObject(JSONString);
                        JSONArray jsonArrayB = jsonTP.getJSONArray("Data");
                        for(int i = 0; i < jsonArrayB.length(); i++){
                            JSONObject o = jsonArrayB.getJSONObject(i);
                            Booking list = new Booking(
                                    o.getString("bookID"),
                                    o.getString("userEmail"),
                                    o.getString("paymentMethod"),
                                    o.getString("paymentStatus"),
                                    o.getString("totalPrice"),
                                    o.getString(String.valueOf("securityCode")),
                                    o.getString(String.valueOf("travelDate")),
                                    o.getString("paymentID"),
                                    o.getString("userFN"),
                                    o.getString("userLN"),
                                    o.getString(String.valueOf("createdAt")),
                                    o.getString("tTM"),
                                    o.getString("messageToCustomer"),
                                    o.getString("messageFromMerchant"),
                                    o.getString("wCN"),
                                    o.getString("wLocation"),
                                    o.getString("wWebsite")
                            );
                            listBooking.add(list);
                            count++;
                        }
                        Toast.makeText(getActivity(), "Data : "+count, Toast.LENGTH_SHORT).show();
                        adapter = new BookingAdapter(listBooking,getActivity());
                        recyclerView.setAdapter(adapter);
                    } catch (JSONException e) {
                        loadMoreBookings(sort);
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressDialog.dismiss();
                    Toast.makeText(getActivity().getApplicationContext(), "Failed To Retrieve Data. Please Try Again.",Toast.LENGTH_LONG).show();
                }
            }
    ){
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String,String> params = new HashMap<String, String>();
            String user = getActivity().getIntent().getStringExtra("username");
            params.put("username", user);
            params.put("currentpage", String.valueOf(current));
            params.put("sorting", sort);
            return params;
        }
    };
    RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
    requestQueue.add(requesting);
}
1

There are 1 answers

4
Om Infowave Developers On BEST ANSWER

set adapter in onCreateView()

   @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View view = inflater.inflate(R.layout.booking_fragment, container, false);

        recyclerView = (RecyclerView) view.findViewById(R.id.bookingRecyclerView);
        linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);

 adapter = new BookingAdapter(listBooking,getActivity());
                            recyclerView.setAdapter(adapter);

    scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) {
            @Override
            public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
                // Triggered only when new data needs to be appended to the list
                // Add whatever code is needed to append new items to the bottom of the list


                if(CurrentStatus.equals("notSearch")){
                    if (current < Integer.parseInt(TP)) {
                        current++;
                        loadMoreBookings(sort);
                    }
                    else if(current == Integer.parseInt(TP)){
                        Toast.makeText(getActivity(),"No More Data to Load", Toast.LENGTH_SHORT).show();
                    }
                }else{
                    if (current < Integer.parseInt(TP)) {
                        current++;
                        searchMoreBookings(search, sort);
                    }
                    else if(current == Integer.parseInt(TP)){
                        Toast.makeText(getActivity(),"No More Data to Be Load", Toast.LENGTH_SHORT).show();
                    }
                }
            }

don't set adapter every time just notify the adapter item inserted at position.

private void loadMoreBookings(final String sort){
    CurrentStatus = "notSearch";
    final ProgressDialog progressDialog = new ProgressDialog(getActivity());
    progressDialog.setMessage("Please Wait While Retrieving Data");
    progressDialog.setCancelable(false);
    progressDialog.show();
    StringRequest requesting = new StringRequest(Request.Method.POST, URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String JSONString) {
                    progressDialog.dismiss();
                    try{
                        JSONObject jsonTP = new JSONObject(JSONString);
                        JSONArray jsonArrayB = jsonTP.getJSONArray("Data");
                        for(int i = 0; i < jsonArrayB.length(); i++){
                            JSONObject o = jsonArrayB.getJSONObject(i);
                            Booking list = new Booking(
                                    o.getString("bookID"),
                                    o.getString("userEmail"),
                                    o.getString("paymentMethod"),
                                    o.getString("paymentStatus"),
                                    o.getString("totalPrice"),
                                    o.getString(String.valueOf("securityCode")),
                                    o.getString(String.valueOf("travelDate")),
                                    o.getString("paymentID"),
                                    o.getString("userFN"),
                                    o.getString("userLN"),
                                    o.getString(String.valueOf("createdAt")),
                                    o.getString("tTM"),
                                    o.getString("messageToCustomer"),
                                    o.getString("messageFromMerchant"),
                                    o.getString("wCN"),
                                    o.getString("wLocation"),
                                    o.getString("wWebsite")
                            );
                            listBooking.add(list);
                            adapter.notifyItemInserted(count);
                            count++;
                        }
                        Toast.makeText(getActivity(), "Data : "+count, Toast.LENGTH_SHORT).show();

                    } catch (JSONException e) {
                        loadMoreBookings(sort);
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressDialog.dismiss();
                    Toast.makeText(getActivity().getApplicationContext(), "Failed To Retrieve Data. Please Try Again.",Toast.LENGTH_LONG).show();
                }
            }
    ){
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String,String> params = new HashMap<String, String>();
            String user = getActivity().getIntent().getStringExtra("username");
            params.put("username", user);
            params.put("currentpage", String.valueOf(current));
            params.put("sorting", sort);
            return params;
        }
    };
    RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
    requestQueue.add(requesting);
}