How to show an empty view with a RecyclerView? How to show an empty view with a RecyclerView? android android

How to show an empty view with a RecyclerView?


On the same layout where is defined the RecyclerView, add the TextView:

<android.support.v7.widget.RecyclerView    android:id="@+id/recycler_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:scrollbars="vertical" /><TextView    android:id="@+id/empty_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:visibility="gone"    android:text="@string/no_data_available" />

At the onCreate or the appropriate callback you check if the dataset that feeds your RecyclerView is empty. If the dataset is empty, the RecyclerView is empty too. In that case, the message appears on the screen.If not, change its visibility:

private RecyclerView recyclerView;private TextView emptyView;// ...recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);emptyView = (TextView) rootView.findViewById(R.id.empty_view);// ...if (dataset.isEmpty()) {    recyclerView.setVisibility(View.GONE);    emptyView.setVisibility(View.VISIBLE);}else {    recyclerView.setVisibility(View.VISIBLE);    emptyView.setVisibility(View.GONE);}


For my projects I made this solution (RecyclerView with setEmptyView method):

public class RecyclerViewEmptySupport extends RecyclerView {    private View emptyView;    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);                    RecyclerViewEmptySupport.this.setVisibility(View.GONE);                }                else {                    emptyView.setVisibility(View.GONE);                    RecyclerViewEmptySupport.this.setVisibility(View.VISIBLE);                }            }        }    };    public RecyclerViewEmptySupport(Context context) {        super(context);    }    public RecyclerViewEmptySupport(Context context, AttributeSet attrs) {        super(context, attrs);    }    public RecyclerViewEmptySupport(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    @Override    public void setAdapter(Adapter adapter) {        super.setAdapter(adapter);        if(adapter != null) {            adapter.registerAdapterDataObserver(emptyObserver);        }        emptyObserver.onChanged();    }    public void setEmptyView(View emptyView) {        this.emptyView = emptyView;    }}

And you should use it instead of RecyclerView class:

<com.maff.utils.RecyclerViewEmptySupport android:id="@+id/list1"    android:layout_height="match_parent"    android:layout_width="match_parent"    /><TextView android:id="@+id/list_empty"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="Empty"    />

and

RecyclerViewEmptySupport list =     (RecyclerViewEmptySupport)rootView.findViewById(R.id.list1);list.setLayoutManager(new LinearLayoutManager(context));list.setEmptyView(rootView.findViewById(R.id.list_empty));


Here is a solution using only a custom adapter with a different view type for the empty situation.

public class EventAdapter extends     RecyclerView.Adapter<EventAdapter.ViewHolder> {    private static final int VIEW_TYPE_EVENT = 0;    private static final int VIEW_TYPE_DATE = 1;    private static final int VIEW_TYPE_EMPTY = 2;    private ArrayList items;    public EventAdapter(ArrayList items) {        this.items = items;    }    @Override    public int getItemCount() {        if(items.size() == 0){            return 1;        }else {            return items.size();        }    }    @Override    public int getItemViewType(int position) {        if (items.size() == 0) {            return VIEW_TYPE_EMPTY;        }else{            Object item = items.get(position);            if (item instanceof Event) {                return VIEW_TYPE_EVENT;            } else {                return VIEW_TYPE_DATE;            }        }    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View v;        ViewHolder vh;        if (viewType == VIEW_TYPE_EVENT) {            v = LayoutInflater.from(parent.getContext()).inflate(                R.layout.item_event, parent, false);            vh = new ViewHolderEvent(v);        } else if (viewType == VIEW_TYPE_DATE) {            v = LayoutInflater.from(parent.getContext()).inflate(                R.layout.item_event_date, parent, false);            vh = new ViewHolderDate(v);        } else {            v = LayoutInflater.from(parent.getContext()).inflate(                R.layout.item_event_empty, parent, false);            vh = new ViewHolder(v);        }        return vh;    }    @Override    public void onBindViewHolder(EventAdapter.ViewHolder viewHolder,                                  final int position) {        int viewType = getItemViewType(position);        if (viewType == VIEW_TYPE_EVENT) {            //...        } else if (viewType == VIEW_TYPE_DATE) {            //...        } else if (viewType == VIEW_TYPE_EMPTY) {            //...        }    }    public static class ViewHolder extends ParentViewHolder {        public ViewHolder(View v) {            super(v);        }    }    public static class ViewHolderDate extends ViewHolder {        public ViewHolderDate(View v) {            super(v);        }    }    public static class ViewHolderEvent extends ViewHolder {        public ViewHolderEvent(View v) {            super(v);        }    }}