Moayed Alayaseh
Moayed Alayaseh

Reputation: 243

LoadMore Recycler View From Api

I have Recycler view in Android and I need to implement load more at recycler view, I searched over internet but failed to solve my problem, this is my code please help

This is the adapter

public class NewsReycelerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private Context context;
    List<String> Dates , Titles , Details , Images;
    public static String NewsDetail,NewsDate ,NewsTitle;
    public final int TYPE_NEWS = 0;
    public final int TYPE_LOAD = 1;
    private int visibleThreshold = 2;
    private int lastVisibleItem, totalItemCount;
    private boolean loading;
    private OnLoadMoreListener onLoadMoreListener;
    public NewsReycelerViewAdapter(RecyclerView recyclerView,Context context , List<String> stringsDate , List<String> stringTitles ,  List<String> stringDetails ,List<String> stringImage,final JPANewsFragment fragment) {

        this.context = context;
        this.Dates = stringsDate;
        this.Titles = stringTitles;
        this.Details = stringDetails;
        this.Images = stringImage;

        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();
                        }
                        fragment.getHtmlNewsData("1");
                        loading = true;
                    }
                }
            });
        }
    }
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);

        if(viewType==TYPE_NEWS){
            return new Item_Holder(inflater.inflate(R.layout.news_adapter_item,parent,false));
        }else{
            return new LoadHolder(inflater.inflate(R.layout.item_loading,parent,false));
        }


    }
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ((Item_Holder)holder).Date.setText(Dates.get(position));
        ((Item_Holder)holder).Title.setText(Titles.get(position));
        NewsDetail = Details.get(position);
        NewsDate = Dates.get(position);
        NewsTitle = Titles.get(position);
        ((Item_Holder)holder).itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((MainActivity)context).changeFragmentMethod(new NewsDetailsFragment(),context.getResources().getString(R.string.news_details));
            }
        });



    }
    @Override
    public int getItemCount() {
        return Dates == null ? 0 : Dates.size();
    }



    //////////////////////////////////////////////////////////////////////////////////
    public class Item_Holder extends RecyclerView.ViewHolder {
        TextView Title , Date ;
        ImageView jpaThumbnail;
        public Item_Holder(View itemView) {
            super(itemView);
            Title = (TextView) itemView.findViewById(R.id.textView_title);
            Date = (TextView) itemView.findViewById(R.id.textView_date);
            jpaThumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);

        }
    }
    static class LoadHolder extends RecyclerView.ViewHolder{
        public LoadHolder(View itemView) {
            super(itemView);
        }
    }

    @Override
    public int getItemViewType(int position) {
        return Dates.get(position) != null ? TYPE_NEWS : TYPE_LOAD;
    }

    public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
        this.onLoadMoreListener = mOnLoadMoreListener;
    }
    public void setLoaded() {
        loading = false;
    }


}

First api have 10 item and when user swipes, I need to load more from another page,

and this is the code written in my main activity

 newsReycelerViewAdapter = new NewsReycelerViewAdapter(recyclerViewNews,context, stringsDate, stringsTitle, stringsDetails,stringsImages,new JPANewsFragment());
                    recyclerViewNews.setLayoutManager(new LinearLayoutManager(context));
                    recyclerViewNews.setAdapter(newsReycelerViewAdapter);
                    loadingProgressBar.setVisibility(View.GONE);
                    newsReycelerViewAdapter.setLoaded();
                    newsReycelerViewAdapter.notifyDataSetChanged();

Please let me know how to solve this issue.

Upvotes: 2

Views: 6437

Answers (3)

Hem Shrestha
Hem Shrestha

Reputation: 479

Here is example for Simple Implementation of LoadMore RecyclerView using a Simple Library compiled from the various sources.

Add this line in build.gradle

implementation 'com.hereshem.lib:awesomelib:2.0.1'

Create RecyclerView Layout in Activity with

<com.hereshem.lib.recycler.MyRecyclerView
        android:id="@+id/recycler"
        app:layoutManager="LinearLayoutManager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

Create a ViewHolder by passing the class that supports

public static class EVHolder extends MyViewHolder<Events> {
    TextView date, title, summary;
    public EVHolder(View v) {
        super(v);
        date = v.findViewById(R.id.date);
        title = v.findViewById(R.id.title);
        summary = v.findViewById(R.id.summary);
    }
    @Override
    public void bindView(Events c) {
        date.setText(c.date);
        title.setText(c.title);
        summary.setText(c.summary);
    }
}

Create Items List variable and adapters with very few lines by passing items, class and layout in the adapter

List<Events> items = new ArrayList<>();
MyRecyclerView recycler = findViewById(R.id.recycler);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, items, EVHolder.class, R.layout.row_event);
recycler.setAdapter(adapter);

ClickListener and LoadMore Listener can be added with following lines

recycler.setOnItemClickListener(new MyRecyclerView.OnItemClickListener() {
    @Override
    public void onItemClick(int position) {
        Toast.makeText(MainActivity.this, "Recycler Item Clicked " + position, Toast.LENGTH_SHORT).show();
    }
});

recycler.setOnLoadMoreListener(new MyRecyclerView.OnLoadMoreListener() {
    @Override
    public void onLoadMore() {
        loadData();
    }
});
loadData();

After the data is loaded this must be called

recycler.loadComplete();

When no LoadMore is required LoadMore layout can be hidden by calling

recycler.hideLoadMore();

Complete example can be found here

Hope this helps :)

Upvotes: 0

Sushin Pv
Sushin Pv

Reputation: 1894

First add a addOnScrollListener() for your RecyclerView and detect scroll down

    recyclerViewNews.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (dy > 0) {
                Log.e("test","reached the last element of recyclerview");
                visibleItemCount = mLinearLayoutManager.getChildCount();
                totalItemCount = mLinearLayoutManager.getItemCount();
                pastVisiblesItems = mLinearLayoutManager.findFirstVisibleItemPosition();

                if (loading) {
                    if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
                        loading = false;
                        fetchData();
                    }
                }
            }
        }
    });

Second Create a function fetchData() to add more data to your adapter then call on newsReycelerViewAdapter.notifyDataSetChanged(); to notify the dataset change and change loading=true

On your activity main create fields as

int pastVisiblesItems, visibleItemCount, totalItemCount;
boolean loading = true;

Upvotes: 3

FreetimeBeatz
FreetimeBeatz

Reputation: 1

My loadmore function looks like:

private void loadMoreMessages() {

        DatabaseReference messageRef = mRootRef.child("messages").child(mThemaID);
        Query messageQuery = messageRef.orderByKey().endAt(mLastKey).limitToLast(10);


        messageQuery.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                Messages message = dataSnapshot.getValue(Messages.class);
String messageKey = dataSnapshot.getKey();


                if(!mPrevKey.equals(messageKey)){
                    messagesList.add(itemPos++, message);

                }else {

                    mPrevKey = mLastKey;
                }



                if(itemPos == 1){

                    mLastKey = messageKey;
                }



                mAdapter.notifyDataSetChanged();
                mLinearLayout.scrollToPositionWithOffset(itemPos-1, 0);

              mRefreshLayout.setRefreshing(false);


            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }

        });

    }

and the listener:

mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {

        mCurrentPage++;

        itemPos = 0;

        loadMoreMessages();

    }
});

maybe you can do something with this

Upvotes: -1

Related Questions