Equivalent of ListView.setEmptyView in RecyclerView

前端 未结 13 1665
孤街浪徒
孤街浪徒 2020-11-30 17:44

In RecyclerView, I want to set an empty view to be shown when the adapter is empty. Is there an equivalent of ListView.setEmptyView()?

相关标签:
13条回答
  • 2020-11-30 18:04

    I think this is more complete with both ErrorView & EmptyView https://gist.github.com/henrytao-me/2f7f113fb5f2a59987e7

    0 讨论(0)
  • 2020-11-30 18:07
    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();
      }
    }
    

    something like this might help

    0 讨论(0)
  • 2020-11-30 18:07

    You can just paint the text on the RecyclerView when it's empty. The following custom subclass supports empty, failed, loading, and offline modes. For successful compilation add recyclerView_stateText color to your resources.

    /**
     * {@code RecyclerView} that supports loading and empty states.
     */
    public final class SupportRecyclerView extends RecyclerView
    {
        public enum State
        {
            NORMAL,
            LOADING,
            EMPTY,
            FAILED,
            OFFLINE
        }
    
        public SupportRecyclerView(@NonNull Context context)
        {
            super(context);
    
            setUp(context);
        }
    
        public SupportRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs)
        {
            super(context, attrs);
    
            setUp(context);
        }
    
        public SupportRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
    
            setUp(context);
        }
    
        private Paint textPaint;
        private Rect textBounds;
        private PointF textOrigin;
    
        private void setUp(Context c)
        {
            textPaint = new Paint();
            textPaint.setAntiAlias(true);
            textPaint.setColor(ContextCompat.getColor(c, R.color.recyclerView_stateText));
    
            textBounds = new Rect();
            textOrigin = new PointF();
        }
    
        private State state;
    
        public State state()
        {
            return state;
        }
    
        public void setState(State newState)
        {
            state = newState;
            calculateLayout(getWidth(), getHeight());
            invalidate();
        }
    
        private String loadingText = "Loading...";
    
        public void setLoadingText(@StringRes int resId)
        {
            loadingText = getResources().getString(resId);
        }
    
        private String emptyText = "Empty";
    
        public void setEmptyText(@StringRes int resId)
        {
            emptyText = getResources().getString(resId);
        }
    
        private String failedText = "Failed";
    
        public void setFailedText(@StringRes int resId)
        {
            failedText = getResources().getString(resId);
        }
    
        private String offlineText = "Offline";
    
        public void setOfflineText(@StringRes int resId)
        {
            offlineText = getResources().getString(resId);
        }
    
        @Override
        public void onDraw(Canvas canvas)
        {
            super.onDraw(canvas);
    
            String s = stringForCurrentState();
            if (s == null)
                return;
    
            canvas.drawText(s, textOrigin.x, textOrigin.y, textPaint);
        }
    
        private void calculateLayout(int w, int h)
        {
            String s = stringForCurrentState();
            if (s == null)
                return;
    
            textPaint.setTextSize(.1f * w);
            textPaint.getTextBounds(s, 0, s.length(), textBounds);
    
            textOrigin.set(
             w / 2f - textBounds.width() / 2f - textBounds.left,
             h / 2f - textBounds.height() / 2f - textBounds.top);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh)
        {
            super.onSizeChanged(w, h, oldw, oldh);
    
            calculateLayout(w, h);
        }
    
        private String stringForCurrentState()
        {
            if (state == State.EMPTY)
                return emptyText;
            else if (state == State.LOADING)
                return loadingText;
            else if (state == State.FAILED)
                return failedText;
            else if (state == State.OFFLINE)
                return offlineText;
            else
                return null;
        }
    }
    
    0 讨论(0)
  • 2020-11-30 18:13

    My version, based on https://gist.github.com/adelnizamutdinov/31c8f054d1af4588dc5c

    public class EmptyRecyclerView extends RecyclerView {
        @Nullable
        private 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);
        }
    
        private void checkIfEmpty() {
            if (emptyView != null && getAdapter() != null) {
                emptyView.setVisibility(getAdapter().getItemCount() > 0 ? GONE : VISIBLE);
            }
        }
    
        private final AdapterDataObserver observer = new AdapterDataObserver() {
            @Override
            public void onChanged() {
                checkIfEmpty();
            }
    
            @Override
            public void onItemRangeInserted(int positionStart, int itemCount) {
                checkIfEmpty();
            }
    
            @Override
            public void onItemRangeRemoved(int positionStart, int itemCount) {
                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);
            }
            checkIfEmpty();
        }
    
        @Override
        public void setVisibility(int visibility) {
            super.setVisibility(visibility);
            if (null != emptyView && (visibility == GONE || visibility == INVISIBLE)) {
                emptyView.setVisibility(GONE);
            } else {
                checkIfEmpty();
            }
        }
    
        public void setEmptyView(@Nullable View emptyView) {
            this.emptyView = emptyView;
            checkIfEmpty();
        }
    }
    
    0 讨论(0)
  • 2020-11-30 18:13

    I have fixed this:
    Created layout layout_recyclerview_with_emptytext.xml file.
    Created EmptyViewRecyclerView.java
    ---------

    EmptyViewRecyclerView emptyRecyclerView = (EmptyViewRecyclerView) findViewById(R.id.emptyRecyclerViewLayout);
    emptyRecyclerView.addAdapter(mPrayerCollectionRecyclerViewAdapter, "There is no prayer for selected category.");

    layout_recyclerview_with_emptytext.xml file

        <?xml version="1.0" encoding="utf-8"?>
        <merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/switcher"
    >
    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    
    <com.ninestars.views.CustomFontTextView android:id="@+id/recyclerViewEmptyTextView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Empty Text"
        android:layout_gravity="center"
        android:gravity="center"
        android:textStyle="bold"
        />
    
        </merge>
    


    EmptyViewRecyclerView.java

    public class EmptyViewRecyclerView extends ViewSwitcher {
    private RecyclerView mRecyclerView;
    private CustomFontTextView mRecyclerViewExptyTextView;
    
    public EmptyViewRecyclerView(Context context) {
        super(context);
        initView(context);
    }
    
    public EmptyViewRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }
    
    
    private void initView(Context context) {
        LayoutInflater.from(context).inflate(R.layout.layout_recyclerview_with_emptytext, this, true);
        mRecyclerViewExptyTextView = (CustomFontTextView) findViewById(R.id.recyclerViewEmptyTextView);
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
    }
    
    public void addAdapter(final RecyclerView.Adapter<?> adapter) {
        mRecyclerView.setAdapter(adapter);
        adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                if(adapter.getItemCount() > 0) {
                    if (R.id.recyclerView == getNextView().getId()) {
                        showNext();
                    }
                } else {
                    if (R.id.recyclerViewEmptyTextView == getNextView().getId()) {
                        showNext();
                    }
                }
            }
        });
    }
    
    public void addAdapter(final RecyclerView.Adapter<?> adapter, String emptyTextMsg) {
        addAdapter(adapter);
        setEmptyText(emptyTextMsg);
    }
    
    public RecyclerView getRecyclerView() {
        return mRecyclerView;
    }
    
    public void setEmptyText(String emptyTextMsg) {
        mRecyclerViewExptyTextView.setText(emptyTextMsg);
    }
    
    }
    
    0 讨论(0)
  • 2020-11-30 18:13

    From my point of view the easiest way how to do an empty View is to create new empty RecyclerView with layout you want to inflate as a background. And this empty Adapter is set when you check your dataset size.

    0 讨论(0)
提交回复
热议问题