RecyclerView Endless Infinite Scrolling Issue

15,969

Solution 1

I had the same issue once an I solve it using this code ... First .. create this class

public abstract class EndlessOnScrollListener extends OnScrollListener {

    public static String TAG = EndlessOnScrollListener.class.getSimpleName();

    // use your LayoutManager instead
    private LinearLayoutManager llm;

    public EndlessOnScrollListener(LinearLayoutManager sglm) {
        this.lm = llm;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        if (!recyclerView.canScrollVertically(1)) {
            onScrolledToEnd();
        }
    }

    public abstract void onScrolledToEnd();
}

Second .. in you activity use this

recyclerView.addOnScrollListener(new EndlessOnScrollListener() {

    @Override
    public void onScrolledToEnd() {
        if (!loading) {
            loading = true;
            // add 10 by 10 to tempList then notify changing in data
        }
        loading = false;
    }
});

This works for me .... I hope it works for you to.

Solution 2

Try notifyItemRangeChanged

yourCurrentList.addAll(newData);    
mAdapter.notifyItemRangeChanged(yourCurretList.size() + 1, newDataSize);

I think this'll help you.

Solution 3

replace

private List<Student> studentList;

with

private List<Object> list;

also replace

@Override
public int getItemViewType(int position) {
    return studentList.get(position) != null ? VIEW_ITEM : VIEW_PROG;
}

with

@Override
public int getItemViewType(int position) {
  return list.get(position) instanceof Student ?  VIEW_ITEM : VIEW_PROG;
}

for detect end of List you can using

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);

            // When went to the end of the list, load more posts
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {

                if (linearLayoutManager.findLastVisibleItemPosition() >= linearLayoutManager.getItemCount() - 1) {

                    // Grow List
                }
            }
}

Also for Add Loading Item. add this code in adapter

public void addLoadingView(){
   list.add(new Object());
   notifyDataSetChanged();
}
Share:
15,969

Related videos on Youtube

Oreo
Author by

Oreo

Updated on November 06, 2020

Comments

  • Oreo
    Oreo over 3 years

    I am trying to implement Endless Infinite Scrolling with RecyclerView, but I am only getting first 10 records, not getting next 10 records and even not getting any progress while trying to scroll at bottom.

    Whereas I was suppose to get next 10 records on scroll and so on... But getting only first 10 records

    Here I have uploaded copy of my JSON - But i am not able to fetch data from same url, that's why i am using client's url and local host.

    I am following this tutorial

    Here is my complete code, May I know where I am doing mistake ?

    JSON :

    {
      "names": [
        {
          "name": "Name 1"
        },
        {
          "name": "Name 2"
        },
        ....
        {
          "name": "Name 60"
        }
      ]
    }
    

    Log:

    D/name -(13759): Name 1
    D/name -(13759): Name 2
    .......................
    D/name -(13759): Name 60
    

    Here is my updated code, which i am using to parse JSON data

    MainActivity.java: UPDATED

    public class MainActivity extends AppCompatActivity {
    
    private Toolbar toolbar;
    
    private TextView tvEmptyView;
    private RecyclerView mRecyclerView;
    private DataAdapter mAdapter;
    private LinearLayoutManager mLayoutManager;
    
    private ArrayList<Student> studentList;
    
    protected Handler handler;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.activity_main);
    
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        tvEmptyView = (TextView) findViewById(R.id.empty_view);
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
    
        studentList = new ArrayList<Student>();
    
        handler = new Handler();
        if (toolbar != null) {
            setSupportActionBar(toolbar);
            getSupportActionBar().setTitle("Android Students");
        }
    
        loadData();
    
    }
    
    // load initial data
    private void loadData() {       
        new Parser().execute("http://10.0.2.2/jsons/mytest.txt");               
    }
    
    class Parser extends AsyncTask<String, Void, Boolean> {
    
        ProgressDialog dialog;
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(MainActivity.this);
            dialog.show();
            dialog.setCancelable(false);
        }
    
        @Override
        protected Boolean doInBackground(String... urls) {
            try {
                //------------------>>
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);
    
                // StatusLine stat = response.getStatusLine();
                int status = response.getStatusLine().getStatusCode();
    
                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);
    
                    JSONObject jsono = new JSONObject(data);
                    JSONArray jarray = jsono.getJSONArray("names");
    
                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);
    
                        Student actor = new Student();
    
                        actor.setName(object.getString("name"));
                        Log.d("name - ", object.getString("name"));
    
                        studentList.add(actor);             
                    }
    
                    Log.d("MainActivity:StudentList ", "The size "+studentList.size());                 
    
                    return true;
                }
    
                //------------------>>
    
            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
    
        }
    
        protected void onPostExecute(Boolean result) {
            dialog.cancel();
    
            Log.d("MainActivity:StudentList ", "The size "+studentList.size());
    
            ArrayList< Student > temArray = 
                     new ArrayList< Student >(studentList.subList(0, 10));           
            mAdapter = new DataAdapter(temArray, mRecyclerView);
    
            Log.d("MainActivity:TempList ", "The size "+temArray.size());
    
            // set the adapter object to the Recyclerview
            mRecyclerView.setAdapter(mAdapter);     
            // use this setting to improve performance if you know that changes
            // in content do not change the layout size of the RecyclerView
            mRecyclerView.setHasFixedSize(true);
    
            mLayoutManager = new LinearLayoutManager(MainActivity.this);
    
            // use a linear layout manager
            mRecyclerView.setLayoutManager(mLayoutManager);
    
            if (studentList.isEmpty()) {
                mRecyclerView.setVisibility(View.GONE);
                tvEmptyView.setVisibility(View.VISIBLE);
            } else {
                mRecyclerView.setVisibility(View.VISIBLE);
                tvEmptyView.setVisibility(View.GONE);
            }
    
            mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    //add null , so the adapter will check view_type and show progress bar at bottom
                    studentList.add(null);
                    mAdapter.notifyItemInserted(studentList.size() - 1);
    
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            //   remove progress item
                            studentList.remove(studentList.size() - 1);
                            mAdapter.notifyItemRemoved(studentList.size());
                            //add items one by one
                            int start = studentList.size();
                            int end = start + 10;
    
                            for (int i = start + 1; i < end; i++) {
                                mAdapter.notifyItemInserted(studentList.size());
                            }
                            mAdapter.setLoaded();
                           //or you can add all at once but do not forget to call mAdapter.notifyDataSetChanged();
                        }
                    }, 2000);
                }
            });
        }
    }
    
    }
    

    DataAdapter.java:

    public class DataAdapter extends RecyclerView.Adapter {
        private final int VIEW_ITEM = 1;
        private final int VIEW_PROG = 0;
    
        private List<Student> studentList;
    
        // The minimum amount of items to have below your current scroll position
        // before loading more.
        private int visibleThreshold = 5;
        private int lastVisibleItem, totalItemCount;
        private boolean loading;
        private OnLoadMoreListener onLoadMoreListener;
    
        public DataAdapter(List<Student> students, RecyclerView recyclerView) {
            studentList = students;
    
            if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
    
                final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView
                        .getLayoutManager();
    
    
                        recyclerView
                        .addOnScrollListener(new RecyclerView.OnScrollListener() {
                            @Override
                            public void onScrolled(RecyclerView recyclerView,
                                                   int dx, int dy) {
                                super.onScrolled(recyclerView, dx, dy);
    
                                totalItemCount = linearLayoutManager.getItemCount();
                                lastVisibleItem = linearLayoutManager
                                        .findLastVisibleItemPosition();
                                if (!loading
                                        && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                                    // End has been reached
                                    // Do something
                                    if (onLoadMoreListener != null) {
                                        onLoadMoreListener.onLoadMore();
                                    }
                                    loading = true;
                                }
                            }
                        });
            }
        }
    
        @Override
        public int getItemViewType(int position) {
            return studentList.get(position) != null ? VIEW_ITEM : VIEW_PROG;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent,
                int viewType) {
            RecyclerView.ViewHolder vh;
            if (viewType == VIEW_ITEM) {
                View v = LayoutInflater.from(parent.getContext()).inflate(
                        R.layout.list_row, parent, false);
    
                vh = new StudentViewHolder(v);
            } else {
                View v = LayoutInflater.from(parent.getContext()).inflate(
                        R.layout.progress_item, parent, false);
    
                vh = new ProgressViewHolder(v);
            }
            return vh;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof StudentViewHolder) {
    
                Student singleStudent= (Student) studentList.get(position);
    
                ((StudentViewHolder) holder).tvName.setText(singleStudent.getName());
    
                ((StudentViewHolder) holder).student= singleStudent;
    
            } else {
                ((ProgressViewHolder) holder).progressBar.setIndeterminate(true);
            }
        }
    
        public void setLoaded() {
            loading = false;
        }
    
        @Override
        public int getItemCount() {
            return studentList.size();
        }
    
        public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
            this.onLoadMoreListener = onLoadMoreListener;
        }
    
    
        //
        public static class StudentViewHolder extends RecyclerView.ViewHolder {
            public TextView tvName;     
    
            public Student student;
    
            public StudentViewHolder(View v) {
                super(v);
                tvName = (TextView) v.findViewById(R.id.tvName);
    
                v.setOnClickListener(new OnClickListener() {
    
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(v.getContext(),
                                "OnClick :" + student.getName(),
                                Toast.LENGTH_SHORT).show();
    
                    }
                });
            }
        }
    
        public static class ProgressViewHolder extends RecyclerView.ViewHolder {
            public ProgressBar progressBar;
    
            public ProgressViewHolder(View v) {
                super(v);
                progressBar = (ProgressBar) v.findViewById(R.id.progressBar1);
            }
        }
    }
    

    OnLoadMoreListener.java:

    public interface OnLoadMoreListener {
         void onLoadMore();
    }
    
    • Satyen Udeshi
      Satyen Udeshi over 8 years
      can you execute 10.0.2.2/jsons/mytest.txt in browser and see what are you getting there ?
    • Satyen Udeshi
      Satyen Udeshi over 8 years
      can you log data in LogCat and see what it prints ?
    • subhash
      subhash over 8 years
      you are not adding items in loop inside loadMore
    • subhash
      subhash over 8 years
      since you are loading all items at once i think you will not need load more. You have not changed visibility of list view on post execute. add if (studentList.isEmpty()) { mRecyclerView.setVisibility(View.GONE); tvEmptyView.setVisibility(View.VISIBLE); } else { mRecyclerView.setVisibility(View.VISIBLE); tvEmptyView.setVisibility(View.GONE); } on post execute of async task
    • ρяσѕρєя K
      ρяσѕρєя K over 8 years
      Getting first 11 black item due to for (int i = 1; i <= 10; i++) { studentList.add(new Student()); } please remove these lines
    • ρяσѕρєя K
      ρяσѕρєя K over 8 years
      @Oreo: see my answer probably help u
    • Jon
      Jon over 8 years
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
    @Oreo: ok move mAdapter.setOnLoadMoreListener method code inside onPostExecute after mRecyclerView.setAdapter(mAdapter); line
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
    @Oreo: Fixed or still facing same issue?
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
    @Oreo: getting data in studentList ? use log and check both studentList and temArray ArrayList Size
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
    @Oreo: please add debugger in onPostExecute method and check it is executing or not?
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
    @Oreo: please check following post stackoverflow.com/questions/29005644/…
  • Oreo
    Oreo over 8 years
    I was suppose to get next 10 records on scroll and so on... But getting only first 10 records, please check my updated code above
  • Ankur1994a
    Ankur1994a over 8 years
    i think you have to add data into list before notifyItemInserted.
  • Oreo
    Oreo over 8 years
    bhaiya answer mat do at least bhai ke hello/hi ka reply toh kiya karo, naraaz ho kya bhai se ?
  • ρяσѕρєя K
    ρяσѕρєя K over 8 years
    @Oreo:are bhai nahi aysa nahi hai. still issue is not solved?
  • Oreo
    Oreo over 8 years
    bhaiya i have tagged you not to get answer, just to greet you good afternoon, anyways i am still looking for solution, not getting where is the issue ?