I have a recycler view in which I load some data from the server when user scroll to bottom I want to show a progress bar and send another request to the server for more dat
Use Below Code:
First Declare these global variables:
int visibleItemCount, totalItemCount = 1;
int firstVisiblesItems = 0;
int totalPages = 1; // get your total pages from web service first response
int current_page = 0;
boolean canLoadMoreData = true; // make this variable false while your web service call is going on.
LinearLayoutManager linearLayoutManager;
Assign Layout manager to your Recyclerview:
linearLayoutManager = new LinearLayoutManager(mActivity);
mRecyclerView.setLayoutManager(linearLayoutManager);
Scroll Listener of your recyclerview:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) //check for scroll down
{
visibleItemCount = linearLayoutManager.getChildCount();
totalItemCount = linearLayoutManager.getItemCount();
firstVisiblesItems = linearLayoutManager.findFirstVisibleItemPosition();
if (canLoadMoreData) {
if ((visibleItemCount + firstVisiblesItems) >= totalItemCount) {
if (current_page < totalPages) {
canLoadMoreData = false;
/**
* .
* .
* .
* .call your webservice with page index
* .
* .
*
*/
//After completion of web service make 'canLoadMoreData = true'
}
}
}
}
}
});
Too late but i'm also refer same way check with my code it work for me
Here is API call using retrofit and get listnotifications
then in this method i create one more method for loadmore getMoreNotificationListApiCall()
public void getNotification()
{
if (listnotifications.size() > 0) {
notificationListAdapter = new NotificationListAdapter(NotificationListActivity.this, listnotifications, notificationListRecyclerview);
notificationListRecyclerview.setAdapter(notificationListAdapter);
notificationListAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore() {
Log.e("ad", "Load More");
listnotifications.add(null);
Handler handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
if (listnotifications.size()>0) {
notificationListAdapter.notifyItemInserted(listnotifications.size() - 1);
}
}
};
handler.post(r);
try {
if (CommonUtils.isConnectingToInternet(NotificationListActivity.this)) {
// Internet Connection is Present
getMoreNotificationListApiCall();
} else {
//Remove loading item
if (listnotifications.size()>0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
CommonUtils.commonToast(NotificationListActivity.this, getResources().getString(R.string.no_internet_exist));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
getMoreNotificationListApiCall()
method code in this method i increment startlimit
means page index and remove null
(i'm using retorfit for api call)
private void getMoreNotificationListApiCall() {
try {
if (CommonUtils.isConnectingToInternet(NotificationListActivity.this)) {
StartLimit = StartLimit + 10;
Call<NotificationBase> call = ApiHandler.getApiService().getNotificationListApi(notificationListJsonMap());
call.enqueue(new Callback<NotificationBase>() {
@Override
public void onResponse(Call<NotificationBase> registerCall, Response<NotificationBase> response) {
Log.e(TAG, " Full json gson => " + "Hi i am here");
try {
Log.e(TAG, " Full json gson => " + new Gson().toJson(response));
JSONObject jsonObj = new JSONObject(new Gson().toJson(response).toString());
Log.e(TAG, " responce => " + jsonObj.getJSONObject("body").toString());
if (response.isSuccessful()) {
int success = response.body().getSuccess();
if (success == 1) {
List<NotificationBean> moreNotication = response.body().getNotificatons();
//Remove loading item
if (listnotifications.size() > 0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
for (int i = 0; i < moreNotication.size(); i++) {
listnotifications.add(moreNotication.get(i));
}
notificationListAdapter.notifyDataSetChanged();
notificationListAdapter.setLoaded();
} else if (success == 0) {
if (listnotifications.size() > 0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
} else {
if (listnotifications.size() > 0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
}
} else {
if (listnotifications.size() > 0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
}
} catch (Exception e) {
e.printStackTrace();
try {
Log.e(TAG, "error=" + e.toString());
if (listnotifications.size() > 0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
} catch (Resources.NotFoundException e1) {
e1.printStackTrace();
}
}
}
@Override
public void onFailure(Call<NotificationBase> call, Throwable t) {
try {
Log.e(TAG, "error" + t.toString());
if (listnotifications.size() > 0) {
listnotifications.remove(listnotifications.size() - 1);
}
notificationListAdapter.notifyItemRemoved(listnotifications.size());
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
}
});
} else {
CommonUtils.commonToast(NotificationListActivity.this, getResources().getString(R.string.no_internet_exist));
}
} catch (Resources.NotFoundException e) {
e.printStackTrace();
}
}
Here is my Adapter class in which i implement OnLoadMoreListener
public class NotificationListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static List<NotificationBean> mList;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
FragmentActivity mFragmentActivity;
private OnLoadMoreListener mOnLoadMoreListener;
private boolean isLoading;
private int visibleThreshold = 5;
private int lastVisibleItem, totalItemCount;
public NotificationListAdapter(FragmentActivity fragmentActivity, List<NotificationBean> data, RecyclerView mRecyclerView) {
this.mList = data;
this.mFragmentActivity = fragmentActivity;
final LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mRecyclerView.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 (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
if (mOnLoadMoreListener != null) {
mOnLoadMoreListener.onLoadMore();
}
isLoading = true;
}
}
});
}
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
@Override
public int getItemViewType(int position) {
return mList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
public void delete(int position) { //removes the row
Log.e("Position : ", "" + position);
mList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mList.size());
}
// Return the size arraylist
@Override
public int getItemCount() {
return mList == null ? 0 : mList.size();
}
public void setLoaded() {
isLoading = false;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_notification_list, parent, false);
return new ViewHolder(itemLayoutView);
} else if (viewType == VIEW_TYPE_LOADING) {
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.loading_layout, parent, false);
return new LoadingViewHolder(itemLayoutView);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof ViewHolder) {
try {
final ViewHolder viewHolder = (ViewHolder) holder;
viewHolder.singleBean = mList.get(position);
viewHolder.pos = position;
final NotificationBean list = mList.get(position);
String notificationTitle = list.getMessage();
String notificationTimeDate = list.getCreatedDatetime();
String notificationIsRead = list.getIsRead();
} catch (Exception e) {
e.printStackTrace();
}
} else if (holder instanceof LoadingViewHolder) {
LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
loadingViewHolder.progressBar.setIndeterminate(true);
}
}
static class LoadingViewHolder extends RecyclerView.ViewHolder {
public ProgressBar progressBar;
public LoadingViewHolder(View itemView) {
super(itemView);
progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar1);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
public NotificationBean singleBean;
int pos;
TextView txt_notification_time_date;
CustomTextview checkbox_notification;
RelativeLayout rl_row_background;
public ViewHolder(final View v) {
super(v);
checkbox_notification = (CustomTextview) v.findViewById(R.id.checkbox_notification);
//checkbox_notification.setButtonDrawable(android.R.color.transparent);//custom_checkbox
// txt_notification_title= (TextView) v.findViewById(R.id.txt_notification_title);
txt_notification_time_date = (TextView) v.findViewById(R.id.txt_notification_time_date);
rl_row_background = (RelativeLayout) v.findViewById(R.id.rl_row_background);
}
}
public void refreshAdapter() {
notifyDataSetChanged();
}
}
here is xml file loading_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar1"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:indeterminate="true" />
</LinearLayout>
Fetching the data from server is a Async Task. So you need to enclose the updation code in a runOnUiThread runnable. to change UI.
runOnUiThread(new Runnable() {
@Override
public void run() {
mUsers.remove(mUsers.size() - 1);
mUserAdapter.notifyItemRemoved(mUsers.size());
//sending request to server for more data
moreDealsRequest();
mUserAdapter.notifyDataSetChanged();
mUserAdapter.setLoaded();
}});