4

I created a RecyclerView for my application and trying to find a way to stop huge requests, I want to get the results 10 by 10 with a progress bar. My server will send the results 10 by 10 on every scrolldown to last item.

    public class ProfileActivityFriendsList extends AppCompatActivity {
        String[] names={"Ander Herera","David De Gea","Michael Carrick","Juan Mata","Diego Costa","Oscar"};
        String[] positions={"Midfielder","GoalKeeper", "Midfielder","Playmaker","Striker","Playmaker"};
        String[] urls={"Midfielder","GoalKeeper", "Midfielder","Playmaker","Striker","Playmaker"};
        int[] images = {R.mipmap.ic_launcher,R.mipmap.ic_launcher, R.mipmap.ic_launcher,R.mipmap.ic_launcher,R.mipmap.ic_launcher,R.mipmap.ic_launcher};

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_profile_friends_list);

            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            //GET RECYCLER
            RecyclerView rv = (RecyclerView) findViewById(R.id.myRecycler);
            //SET LAYOUT
            rv.setLayoutManager(new LinearLayoutManager(this));
            rv.setItemAnimator(new DefaultItemAnimator());
            //ADAPTER
            MyAdapter adapter = new MyAdapter(this, names, positions, urls, images);
            rv.setAdapter(adapter);
        }
} 

Here is my adapter class.

public class MyAdapter extends RecyclerView.Adapter<MyHolder> {
    Context c;
    String[] names;
    String[] positions;
    String[] urls;
    int[] img;

    public MyAdapter(Context ctx, String[] names, String[] positions,String[] urls, int[] images){
        this.c=ctx;
        this.names = names;
        this.positions = positions;
        this.img = images;
        this.urls = urls;
    }
    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.friend_list_model,null);

        MyHolder holder = new MyHolder(v);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyHolder holder, final int position) {
        holder.imageView.setImageResource(img[position]);
        holder.name.setText(names[position]);
        holder.desc.setText(positions[position]);

        holder.serItemClickListener(new ItemClickListener() {
            @Override
            public void onItemClick(View v, int pos) {
                Snackbar.make(v,positions[position]+" "+positions[position],Snackbar.LENGTH_LONG).show();
            }
        });
    }

    @Override
    public int getItemCount() {
        return names.length;
    }
}

and this it the holder.

public class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    CircleImageView imageView;
    TextView name;
    TextView desc;
    ItemClickListener itemClickListener;
    public MyHolder(View itemView) {
        super(itemView);

        imageView = (CircleImageView) itemView.findViewById(R.id.circleImageView1);
        name = (TextView) itemView.findViewById(R.id.textName);
        desc = (TextView) itemView.findViewById(R.id.textDesc);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        this.itemClickListener.onItemClick(v,getLayoutPosition());
    }
    public void serItemClickListener(ItemClickListener ic){
        this.itemClickListener = ic;
    }
}

I watched lots of tutorials and couldn't find a clear solution, I think there are some ways to do it but I don't know is my code available to add it?

0

4 Answers 4

5

What we did was use ReyclerView.OnScrollListener. Assuming you're using a LinearLayoutManager, you can check the current shown item versus the total count to determine when you've reached the last item, then request the next page. You also need to throw in some additional logic checks to early out to prevent "spamming" as the scroll even happens a lot.

For example:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if (!hasMoreContent()) {
            return;
        }

        if (currentlyLoadingInitialRequest()) {
            return;
        }

        if (alreadyLoadingNextPage()) {
            return;
        }

        if (isInErrorState()) {
            return;
        }

        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        int total = layoutManager.getItemCount();
        int currentLastItem = layoutManger.findLastVisibleItemPosition();
        if (currentLastItem == total - 1) {
            requestNextPage();
        }
    });
Sign up to request clarification or add additional context in comments.

1 Comment

This is a useful hack, Thank you
4

https://github.com/kunal-mahajan/PaginationAdeptor

I have implemented the pagination component / widget and that is very simple to implement. No xml is required only need to extend the class. Example is available in above url with timer task and dummy data. In main activity you may change the number of data available for testing purpose in "final int totalRecords"; If there is any issue will answer your queries. Thanks Kunal

3 Comments

Really nice sample its work for me many thanks kunal! I found it interesting solution to the complex problem. Its also working on if the request cout does not fill the screen, it automatically load new request.
Amazing code Sir. You have simplified any list loading screen whether horizontal or vertical with auto pagination and only requirement is to create adapter class for any screen. Loved this code Sir. Thanks !
Thank you so much sir, saved more than a day of work.
1

You can try this approach:

  mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if (dy > 0) //check for scroll down
        {
            visibleItemCount = mLayoutManager.getChildCount();
            totalItemCount = mLayoutManager.getItemCount();
            pastVisibleItems = mLayoutManager.findFirstVisibleItemPosition();

            if (loading) {
                if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                    loading = false;
                    if (adapter.countOfShowing < adapter.allChallenges.size()) {
                        Log.e("...", "Last Item Wow !");
                        adapter.increaseCountOfShowing();
                        adapter.notifyDataSetChanged();
                    }
                    loading = true;
                    //Do pagination.. i.e. fetch new data
                }
            }
        }
    }
});

5 Comments

can you give some examples for adapter.countOfShowing, adapter.allChallenges.size(), adapter.increaseCountOfShowing()? how do i need to implement them?
Oh, yeah, sorry. I've simply copied my own code here. I keep 2 arrays in my adapter allItems and showedItems (let's call them so). increaseCountOfShowing() is just increasing the showedItemsSize and fill them with AllItems elements. Are you clear with that?
nop :D, I will try to find a way to understand the onScrolled and the adapter issues. thanks for your help!.
I did all the parts except the countOfShowing man. how did you get the countOfShowing as int? what is the method of it?
There is just a simple method which increases variable countOfShowing called increaseCountOfShowing() for example by 10. Then I reinit showedItems array with a new size and fill that with allItems elements
-1

Two RecyclerView in same Activity with pagination then problem to get scrolling position.

First RecyclerView add in collapsing toolbar and second RecyclerView add in scrolling then second RecyclerView working fine with pagination.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.