If you already read my previous blog that is related to this. Almost same thing i'm going implement here except empty text view. it will visible if list has no items. I'm going to create a custom RecylceView for track load more event.
AppRecyclerView is a customized class of RecyclerView that track load more event on list scroll.
AppRecyclerView is a customized class of RecyclerView that track load more event on list scroll.
1. Here is your screen layout file that contains custom recyclerView, progressBar and Textview that shows the empty message "Record not found".
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.demo.AppRecyclerView
android:id="@+id/list_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
/>
<ProgressBar
android:id="@+id/list_pb_loader"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="bottom|center"
android:layout_marginBottom="10dp"
android:background="@color/colorTransparent"
android:indeterminateTint="@color/colorPrimaryDark"
android:indeterminateTintMode="src_atop"
android:visibility="gone"
/>
<TextView
android:id="@+id/list_tv_list_msg"
style="@style/AppBigTextViewStyleLabel"
android:layout_width="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:text="Record not found"
android:textColor="@color/colorLightGrey"
android:visibility="gone"
/>
</FrameLayout>
2. In your Activity/Fragment setup the following views.
ProgressBar progressBar = (ProgressBar) rootView.findViewById(R.id.fragment_product_list_pb_loader);
progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), R.color.colorPrimaryDark), PorterDuff.Mode.SRC_IN);
rvProductList = (AppRecyclerView) rootView.findViewById(R.id.fragment_product_list_rv);
// Provide load more view that will visible when last item come on screen.
rvProductList.setLoadMoreProgress(progressBar);
rvProductList.setLoadMoreProgress(progressBar);
//Set listener that invoke when laod more event invoke from custom AppRecyclerView
rvProductList.setLoadMoreListener(presenter);
rvProductList.setEmptyView(rootView.findViewById(R.id.fragment_product_list_tv_list_msg));
rvProductList.setLoadMoreListener(presenter);
rvProductList.setEmptyView(rootView.findViewById(R.id.fragment_product_list_tv_list_msg));
3. Customize AppRecyclerView
public class AppRecyclerView extends RecyclerView {
private ProgressBar progressBar;
private View emptyView;
private boolean loading;
private OnLoadMoreListener onLoadMoreListener;
private ProgressBar progressBar;
private View emptyView;
private boolean loading;
private OnLoadMoreListener onLoadMoreListener;
//It will observe item of list and show empty view if list not contains any item.
private AdapterDataObserver emptyObserver = new AdapterDataObserver() {
@Override
public void onChanged() {
Adapter<?> adapter = getAdapter();
if (adapter != null && emptyView != null) {
if (adapter.getItemCount() == 0) {
emptyView.setVisibility(View.VISIBLE);
AppRecyclerView.this.setVisibility(View.GONE);
} else {
emptyView.setVisibility(View.GONE);
AppRecyclerView.this.setVisibility(View.VISIBLE);
}
}
}
};
public AppRecyclerView(Context context) {
super(context);
}
public AppRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AppRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
if (adapter != null && !adapter.hasObservers()) {
adapter.registerAdapterDataObserver(emptyObserver);
}
emptyObserver.onChanged();
}
public void setEmptyView(View emptyView) {
this.emptyView = emptyView;
}
@Override
public void stopScroll()
{
try {
super.stopScroll();
} catch (NullPointerException exception) {
Crashlytics.logException(exception);
/**
* The mLayout has been disposed of before the
* RecyclerView and this stops the application
* from crashing.
*/
}
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.onLoadMoreListener = loadMoreListener;
addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy)
{
super.onScrolled(recyclerView, dx, dy);
if (getLayoutManager() instanceof LinearLayoutManager) {
validateListScroll(dy, (LinearLayoutManager) getLayoutManager());
} else {
validateGridListScroll(dy, (GridLayoutManager) getLayoutManager());
}
}
});
}
private void validateGridListScroll(int dy, GridLayoutManager gridLayoutManager) {
if (dy > 0 && (gridLayoutManager.getChildCount() + gridLayoutManager.findFirstVisibleItemPosition() + 1) >= gridLayoutManager.getItemCount() && !loading) {
setLoading(true);
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
}
}
private void validateListScroll(int dy, LinearLayoutManager linearLayoutManager) {
if (dy > 0 && (linearLayoutManager.getChildCount() + linearLayoutManager.findFirstVisibleItemPosition() + 1) >= linearLayoutManager.getItemCount() && !loading) {
setLoading(true);
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
}
}
public void setLoading(boolean loading) {
this.loading = loading;
if (progressBar != null) {
if (loading) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
}
}
public void setLoadMoreProgress(ProgressBar progressBar) {
this.progressBar = progressBar;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
}
private AdapterDataObserver emptyObserver = new AdapterDataObserver() {
@Override
public void onChanged() {
Adapter<?> adapter = getAdapter();
if (adapter != null && emptyView != null) {
if (adapter.getItemCount() == 0) {
emptyView.setVisibility(View.VISIBLE);
AppRecyclerView.this.setVisibility(View.GONE);
} else {
emptyView.setVisibility(View.GONE);
AppRecyclerView.this.setVisibility(View.VISIBLE);
}
}
}
};
public AppRecyclerView(Context context) {
super(context);
}
public AppRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AppRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
if (adapter != null && !adapter.hasObservers()) {
adapter.registerAdapterDataObserver(emptyObserver);
}
emptyObserver.onChanged();
}
public void setEmptyView(View emptyView) {
this.emptyView = emptyView;
}
@Override
public void stopScroll()
{
try {
super.stopScroll();
} catch (NullPointerException exception) {
Crashlytics.logException(exception);
/**
* The mLayout has been disposed of before the
* RecyclerView and this stops the application
* from crashing.
*/
}
}
public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
this.onLoadMoreListener = loadMoreListener;
addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy)
{
super.onScrolled(recyclerView, dx, dy);
if (getLayoutManager() instanceof LinearLayoutManager) {
validateListScroll(dy, (LinearLayoutManager) getLayoutManager());
} else {
validateGridListScroll(dy, (GridLayoutManager) getLayoutManager());
}
}
});
}
private void validateGridListScroll(int dy, GridLayoutManager gridLayoutManager) {
if (dy > 0 && (gridLayoutManager.getChildCount() + gridLayoutManager.findFirstVisibleItemPosition() + 1) >= gridLayoutManager.getItemCount() && !loading) {
setLoading(true);
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
}
}
private void validateListScroll(int dy, LinearLayoutManager linearLayoutManager) {
if (dy > 0 && (linearLayoutManager.getChildCount() + linearLayoutManager.findFirstVisibleItemPosition() + 1) >= linearLayoutManager.getItemCount() && !loading) {
setLoading(true);
if (onLoadMoreListener != null) {
onLoadMoreListener.onLoadMore();
}
}
}
public void setLoading(boolean loading) {
this.loading = loading;
if (progressBar != null) {
if (loading) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
}
}
public void setLoadMoreProgress(ProgressBar progressBar) {
this.progressBar = progressBar;
}
public interface OnLoadMoreListener {
void onLoadMore();
}
}