Instantly share code, notes, and snippets.

Embed
What would you like to do?
RecyclerView doesn't have an emptyView support, we gotta fix that
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EmptyRecyclerView extends RecyclerView {
@Nullable View emptyView;
public EmptyRecyclerView(Context context) { super(context); }
public EmptyRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); }
public EmptyRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
void checkIfEmpty() {
if (emptyView != null) {
emptyView.setVisibility(getAdapter().getItemCount() > 0 ? GONE : VISIBLE);
}
}
final @NotNull AdapterDataObserver observer = new AdapterDataObserver() {
@Override public void onChanged() {
super.onChanged();
checkIfEmpty();
}
};
@Override public void setAdapter(@Nullable Adapter adapter) {
final Adapter oldAdapter = getAdapter();
if (oldAdapter != null) {
oldAdapter.unregisterAdapterDataObserver(observer);
}
super.setAdapter(adapter);
if (adapter != null) {
adapter.registerAdapterDataObserver(observer);
}
}
public void setEmptyView(@Nullable View emptyView) {
this.emptyView = emptyView;
checkIfEmpty();
}
}
@AnirudhaAgashe

This comment has been minimized.

Show comment
Hide comment
@AnirudhaAgashe

AnirudhaAgashe Mar 23, 2015

Consider adding onItemRangeInserted and onItemRangeInserted to the observer

onChange is not fired when notifyItemRangeInserted and notifyItemRangeInserted is called on the adapter.

onItemRangeInserted, called when notifyItemRangeInserted).
Scenario: Initially the list is empty. But after adding items in range it will not be empty

onItemRangeRemoved to, called when notifyItemRangeRemoved is used.
Scenario: All the items might be removed from the data set and it may be empty

Thanks for the gist. I have forked you gist and added the above the changes. Also I have used Android's annotation instead of JetBrains to support Android Studio

AnirudhaAgashe commented Mar 23, 2015

Consider adding onItemRangeInserted and onItemRangeInserted to the observer

onChange is not fired when notifyItemRangeInserted and notifyItemRangeInserted is called on the adapter.

onItemRangeInserted, called when notifyItemRangeInserted).
Scenario: Initially the list is empty. But after adding items in range it will not be empty

onItemRangeRemoved to, called when notifyItemRangeRemoved is used.
Scenario: All the items might be removed from the data set and it may be empty

Thanks for the gist. I have forked you gist and added the above the changes. Also I have used Android's annotation instead of JetBrains to support Android Studio

@IlyaEremin

This comment has been minimized.

Show comment
Hide comment
@IlyaEremin

IlyaEremin Jun 15, 2015

Hi, you are a popular man!

IlyaEremin commented Jun 15, 2015

Hi, you are a popular man!

@mobiRic

This comment has been minimized.

Show comment
Hide comment
@mobiRic

mobiRic Sep 3, 2015

Hello, I would like to use this code in future projects of mine.

  • Are you the original author?

Would you be happy if I fork this and add an Apache v2 licence to my copy, with attribution to you?

Thanks,
Richard
Glowworm Software
Cape Town, South Africa

mobiRic commented Sep 3, 2015

Hello, I would like to use this code in future projects of mine.

  • Are you the original author?

Would you be happy if I fork this and add an Apache v2 licence to my copy, with attribution to you?

Thanks,
Richard
Glowworm Software
Cape Town, South Africa

@adelnizamutdinov

This comment has been minimized.

Show comment
Hide comment
@adelnizamutdinov

adelnizamutdinov Sep 6, 2015

@mobiRic you can do whatever you want with this code :)

Owner

adelnizamutdinov commented Sep 6, 2015

@mobiRic you can do whatever you want with this code :)

@mobiRic

This comment has been minimized.

Show comment
Hide comment
@mobiRic

mobiRic Sep 7, 2015

Thanks - forked to https://gist.github.com/mobiRic/963a814d51259c730467

Can I suggest adding a method for swapAdapter() for completeness:

@Override
public void swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews) {
    final Adapter oldAdapter = getAdapter();
    if (oldAdapter != null) {
        oldAdapter.unregisterAdapterDataObserver(observer);
    }

    if (adapter != null) {
        adapter.registerAdapterDataObserver(observer);
    }
    super.swapAdapter(adapter, removeAndRecycleExistingViews);
    checkIfEmpty();
}

mobiRic commented Sep 7, 2015

Thanks - forked to https://gist.github.com/mobiRic/963a814d51259c730467

Can I suggest adding a method for swapAdapter() for completeness:

@Override
public void swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews) {
    final Adapter oldAdapter = getAdapter();
    if (oldAdapter != null) {
        oldAdapter.unregisterAdapterDataObserver(observer);
    }

    if (adapter != null) {
        adapter.registerAdapterDataObserver(observer);
    }
    super.swapAdapter(adapter, removeAndRecycleExistingViews);
    checkIfEmpty();
}
@sevar83

This comment has been minimized.

Show comment
Hide comment
@sevar83

sevar83 Sep 11, 2015

@AnirudhaAgashe suggestion is correct!

sevar83 commented Sep 11, 2015

@AnirudhaAgashe suggestion is correct!

@mmanishh

This comment has been minimized.

Show comment
Hide comment
@mmanishh

mmanishh Oct 9, 2015

@NotNul coudnl't resolve

mmanishh commented Oct 9, 2015

@NotNul coudnl't resolve

@bryant1410

This comment has been minimized.

Show comment
Hide comment
@bryant1410

bryant1410 Dec 7, 2015

maybe the emptyView attribute could be private

bryant1410 commented Dec 7, 2015

maybe the emptyView attribute could be private

@subbuboyapati

This comment has been minimized.

Show comment
Hide comment
@subbuboyapati

subbuboyapati Feb 27, 2016

Hi @adelnizamutdinov , This we can achieve in flowing way.
Make two list item one for showing normal data and another one is for empty view

  1. In getitemcount, if count is zero return 1 otherwise size of an adapter.
  2. In itemViewType if size 0 return empty view type otherwise return your normal list item.

subbuboyapati commented Feb 27, 2016

Hi @adelnizamutdinov , This we can achieve in flowing way.
Make two list item one for showing normal data and another one is for empty view

  1. In getitemcount, if count is zero return 1 otherwise size of an adapter.
  2. In itemViewType if size 0 return empty view type otherwise return your normal list item.
@Ghostish

This comment has been minimized.

Show comment
Hide comment
@Ghostish

Ghostish Feb 27, 2016

Really appreciate this great idea . It works well.

Ghostish commented Feb 27, 2016

Really appreciate this great idea . It works well.

@Honghe

This comment has been minimized.

Show comment
Hide comment
@Honghe

Honghe Jul 13, 2016

adapter.notifyItemRemoved(position); will not evoke checkIfEmpty()

Honghe commented Jul 13, 2016

adapter.notifyItemRemoved(position); will not evoke checkIfEmpty()

@wangyiyong

This comment has been minimized.

Show comment
Hide comment
@wangyiyong

wangyiyong May 4, 2017

But where is the emptyView attached?

wangyiyong commented May 4, 2017

But where is the emptyView attached?

@beraybentesen

This comment has been minimized.

Show comment
Hide comment
@beraybentesen

beraybentesen Jun 10, 2017

Does nothing when I use following method :
recyclerView.postDelayed(() -> Notify RecyclerView

Inflated like this :
View headerView = View.inflate(getActivity(), R.layout.layout_empty_view, null);

beraybentesen commented Jun 10, 2017

Does nothing when I use following method :
recyclerView.postDelayed(() -> Notify RecyclerView

Inflated like this :
View headerView = View.inflate(getActivity(), R.layout.layout_empty_view, null);

@josemigallas

This comment has been minimized.

Show comment
Hide comment
@josemigallas

josemigallas Oct 13, 2017

@adelnizamutdinov
Hi, I think there's a small typo on line 25. Shouldn't it be @NonNull instead of @NotNull?

josemigallas commented Oct 13, 2017

@adelnizamutdinov
Hi, I think there's a small typo on line 25. Shouldn't it be @NonNull instead of @NotNull?

@josemigallas

This comment has been minimized.

Show comment
Hide comment
@josemigallas

josemigallas Oct 13, 2017

It is also not working without implementing onItemRangeInserted in the observer. I'm using FirebaseUI.

josemigallas commented Oct 13, 2017

It is also not working without implementing onItemRangeInserted in the observer. I'm using FirebaseUI.

@Blablablar

This comment has been minimized.

Show comment
Hide comment
@Blablablar

Blablablar May 22, 2018

I have the same question, where is the emptyView attached?

Blablablar commented May 22, 2018

I have the same question, where is the emptyView attached?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment