Як показати порожній вигляд за допомогою RecyclerView?


271

Мене використовують, щоб помістити спеціальний вигляд всередині файлу макета, як описано в ListActivityдокументації, яка повинна відображатися, коли немає даних . Цей вид має ідентифікатор "android:id/empty".

<TextView
    android:id="@android:id/empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/no_data" />

Цікаво, як це можна зробити з новим RecyclerView?


2
Ви можете використовувати github.com/rockerhieu/rv-adapter-states , він підтримує не тільки порожній вигляд, але й завантаження подання та перегляду помилок. І використовувати його можна, не змінюючи логіку існуючого адаптера.
— Hieu Rocker

20
Це не просто захоплююче те, що, здається, не існує простого setEmptyView()методу проти RecyclerView...
— Subby

Ось моя відповідь, перевірте це посилання stackoverflow.com/a/58411351/5449220
— Ракеш Верма

@Subby, згоден, але setEmptyView()також мав недолік. Під час завантаження даних ми не хотіли показувати порожній вигляд у ListView, але це було. Отже, нам довелося реалізувати певну логіку. В даний час я використовую stackoverflow.com/a/48049142/2914140 .
— CoolMind

Відповіді:


305

У той же макет, де визначено RecyclerView, додайте 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" />

При onCreateабо відповідному зворотному дзвінку ви перевіряєте, чи набір даних, який подає RecyclerView, порожній. Якщо набір даних порожній, то RecyclerViewтакож порожній. У такому випадку на екрані з'являється повідомлення. Якщо ні, змініть її видимість:

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);
}

11
Це не працює для мене, оскільки макет подання рециркулятора завищений у фрагменті, тоді як рішення про те, чи відображати звичайний макет елемента чи макет без елементів, приймається в адаптері.
— JJD

1
@JJD при використанні фрагмента застосовується те саме. Коли ви надуваєте свій фрагмент, ви маєте перегляд рециркулятора, а потім інший макет, який буде використаний для порожнього перегляду. Зазвичай у моїх фрагментах у мене будуть такі подання: 1) перегляд рециркулятора, 2) порожній вигляд та 3) перегляд панелі прогресу. Я зазвичай передаю адаптер незалежно від списку, але виходячи з розміру списку, я або приховую рециркулятор і покажу порожній, або навпаки. Якщо рециркулятор має порожній список, то він нічого з цим не робить. Ви просто бачите порожній вид.
— Рей Хантер

1
@stackex Перевірка повинна бути у зворотному виклику onCreateView фрагмента або onResume of Activity. Таким чином, перевірка буде проведена безпосередньо перед тим, як екран відображатиметься користувачеві, і буде працювати для обох, збільшуючи або зменшуючи кількість рядків у наборі даних.
— slellis

2
@Zapnologica Ви можете це зробити навпаки. Використовуйте шину подій (наприклад, greenrobots Eventbus або Otto), а потім змініть пост адаптера на шині подій, коли зміна набору даних. У фрагменті все, що ви робите, - це створити метод, параметри якого відповідають тому, що адаптер переходить у метод Eventbus.post, а потім змінити макет відповідно. Більш простий, але також більш поєднаний підхід полягає в створенні інтерфейсу зворотного виклику в адаптері, а при створенні адаптера запропонуйте фрагмент його реалізувати.
— AgentKnopf

2
У макеті я отримую кілька кореневих тегів. Як виглядає ваш файл повного макета?
— порошок366

192

Для моїх проектів я зробив це рішення ( RecyclerViewз setEmptyViewметодом):

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;
    }
}

І вам слід використовувати його замість RecyclerViewкласу:

<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"
    />

і

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

2
Ви взяли цей код з цієї відповіді чи звідси ?
— Суфіан

@Sufian Ні, я не бачив такої відповіді, просто знайшов те саме. Але цей код, безумовно, виглядає красивішим, ніж мій :)
— maff91

2
Я спробував поєднати це з FirebaseRecyclerAdapter, це не спрацювало. Це пояснюється тим, що FirebaseRecyclerAdapter не викликає onChange (AdapterDataObserver), а він викликає методи onItem *. Для того, щоб він працював, додайте: `Переосмислити загальнодоступну недійсність onItemRangeRemoved (int positionStart, int itemCount) {// чек} Переозначити публічну недійсність onItemRangeMoved (int fromPosition, int toPosition, int itemCount) {// the check} // тощо ..`
— FrankkieNL

1
Чому ви перевіряєте, чи немає адаптер у спостерігачі? якщо адаптер недійсний, спостерігача ніколи не слід викликати.
— Стімсоні

16
Тьфу, мушу сказати, що це просто класичний Google BS. Я маю це реалізувати лише для того, щоб додати порожній вигляд? Він повинен бути включений до їх CR @ psh1t SDK! Заради Бога!
— Неонова війна

62

Ось рішення з використанням лише спеціального адаптера з іншим типом перегляду для порожньої ситуації.

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);
        }
    }

}

3
@ sfk92fksdf Чому це схильність до помилок? Це те, як ви повинні обробляти кілька типів перегляду у
— recilerview

@billynomates, тому що getItemCount()має бути oneliner, але тут у нас є нетривіальний ifз деякою прихованою логікою. Ця логіка також з'являється незграбно, getItemViewTypeі Бог знає, де ще
— Олексій Андронов,

3
Це не повинно бути одним рядком. Якщо у вас є кілька типів перегляду, це зробити так.
— MSpeed

@ sfk92fksdf Що ви маєте на увазі під прихованою логікою? Код тут прямо ▲
— radu122

1
на мою думку, ця відповідь повинна бути прийнятою відповіддю. Це справді спосіб поводження з різновидами перегляду
— Іво Бекерс,

45

Я використовую ViewSwitcher

<ViewSwitcher
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/switcher"
    >

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <TextView android:id="@+id/text_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/list_empty"
        android:gravity="center"
        />

</ViewSwitcher>

у коді ви перевірите курсор / набір даних та переключення подань.

void showItems(Cursor items) {
    if (items.size() > 0) {

        mAdapter.switchCursor(items);

        if (R.id.list == mListSwitcher.getNextView().getId()) {
            mListSwitcher.showNext();
        }
    } else if (R.id.text_empty == mListSwitcher.getNextView().getId()) {
        mListSwitcher.showNext();
    }
}

Також ви можете встановити анімацію, якщо хочете, за допомогою декількох рядків коду

mListSwitcher.setInAnimation(slide_in_left);
mListSwitcher.setOutAnimation(slide_out_right);

Це справді роман
— Чжан Сян

Чистий розчин.
— Ojonugwa Jude Ochalifu

30

Оскільки відповідь Кевіна не є повною.
Це більш правильна відповідь, якщо ви використовуєте RecyclerAdapter' notifyItemInsertedі notifyItemRemovedдля оновлення набору даних. Дивіться версію Kotlin, яку додав інший користувач нижче.

Java:

mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {

    @Override
    public void onChanged() {
        super.onChanged();
        checkEmpty();
    }

    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        super.onItemRangeInserted(positionStart, itemCount);
        checkEmpty();
    }

    @Override
    public void onItemRangeRemoved(int positionStart, int itemCount) {
        super.onItemRangeRemoved(positionStart, itemCount);
        checkEmpty();
    }

    void checkEmpty() {
        mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
    }
});

Котлін

adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
    override fun onChanged() {
        super.onChanged()
        checkEmpty()
    }

    override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
        super.onItemRangeInserted(positionStart, itemCount)
        checkEmpty()
    }

    override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
        super.onItemRangeRemoved(positionStart, itemCount)
        checkEmpty()
    }

    fun checkEmpty() {
        empty_view.visibility = (if (adapter.itemCount == 0) View.VISIBLE else View.GONE)
    }
})

2
Це чудове рішення. Я пропоную редагувати його, що буде включати версію kotlin.
— jungledev

Це здається добре, але може не спрацювати, якщо ви викликаєте swapAdapter () або навіть setAdapter () кілька разів.
— Главк

Я думаю, що це найелегантніше рішення!
— ентузіаст андроїдів

Чудова робота. не забудьте приховати RecyclerView, показуючи етикетку
— MrG

18

RVEmptyObserver

Замість використання користувацького RecyclerViewрозширення - AdapterDataObserverце більш просте рішення, яке дозволяє встановити звичай, Viewякий відображатиметься, коли в списку немає елементів:

Приклад використання:

RVEmptyObserver observer = new RVEmptyObserver(recyclerView, emptyView)
rvAdapter.registerAdapterDataObserver(observer);

Клас:

public class RVEmptyObserver extends RecyclerView.AdapterDataObserver {
    private View emptyView;
    private RecyclerView recyclerView;

    public RVEmptyObserver(RecyclerView rv, View ev) {
        this.recyclerView = rv;
        this.emptyView    = ev;
        checkIfEmpty();
    }

    private void checkIfEmpty() {
        if (emptyView != null && recyclerView.getAdapter() != null) {
            boolean emptyViewVisible = recyclerView.getAdapter().getItemCount() == 0;
            emptyView.setVisibility(emptyViewVisible ? View.VISIBLE : View.GONE);
            recyclerView.setVisibility(emptyViewVisible ? View.GONE : View.VISIBLE);
        }
    }

    public void onChanged() { checkIfEmpty(); }
    public void onItemRangeInserted(int positionStart, int itemCount) { checkIfEmpty(); }
    public void onItemRangeRemoved(int positionStart, int itemCount) { checkIfEmpty(); }
}

Я вважаю , що він буде працювати швидше , якщо ви не викликаєте checkIfEmpty()в onChanged()іonItemRangeInserted()
— Geekarist

Я погоджуюсь (і це я особисто робив), але це було покликане стати відправною точкою для людей, які стикаються з цим питанням.
— Шехаряр

9

На адаптері getItemViewType перевірки , якщо адаптер має 0 елементів і повертати різні viewType якщо так.

Тоді на своєму onCreateViewHolder перевірте, чи viewType - це той, який ви повернули раніше, і надуйте інший вигляд. У цьому випадку файл макета з цим TextView

EDIT

Якщо це все ще не працює, можливо, ви захочете встановити розмір перегляду програмно таким чином:

Point size = new Point();
((WindowManager)itemView.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(size);

А потім, коли ви надуваєте перегляд виклику:

inflatedView.getLayoutParams().height = size.y;
inflatedView.getLayoutParams().width = size.x;

Звучить добре. Однак я не отримую в onCreateViewHolderколи мій набір даних nullабо порожній , так як я повинен повернутися 0в getItemCount.
— JJD

Тоді поверніть 1, якщо це недійсне :)
— Педро Олівейра

Працює дещо. Дякую. - Невелика деталь полягає в тому, що я не можу отримати порожній елемент списку вертикально центрованим у вікні переробки. Перегляд тексту залишається у верхній частині екрана, тим не менш я встановив, android:layout_gravity="center"а також android:layout_height="match_parent"для подання батьківського переробника.
— JJD

Це залежить від компонування рядка, який ви використовуєте. Він повинен збігатися з прозорим на висоті. Якщо ви все ще не можете змусити його працювати, додайте глобальний слухач макета і встановіть параметри компонування таким же висотою і шириною, що і екран.
— Педро Олівейра

Усі контейнери (активність, фрагмент, лінійний макет, перегляд рециркулятора, перегляд тексту) встановлені на android:layout_height="match_parent". Хоча рядок не розширюється до висоти екрана.
— JJD

8

Ось мій клас для показу порожнього перегляду, повторного перегляду (коли не вдалося завантажити api) та прогресу завантаження для RecyclerView

public class RecyclerViewEmptyRetryGroup extends RelativeLayout {
    private RecyclerView mRecyclerView;
    private LinearLayout mEmptyView;
    private LinearLayout mRetryView;
    private ProgressBar mProgressBar;
    private OnRetryClick mOnRetryClick;

    public RecyclerViewEmptyRetryGroup(Context context) {
        this(context, null);
    }

    public RecyclerViewEmptyRetryGroup(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RecyclerViewEmptyRetryGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onViewAdded(View child) {
        super.onViewAdded(child);
        if (child.getId() == R.id.recyclerView) {
            mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            return;
        }
        if (child.getId() == R.id.layout_empty) {
            mEmptyView = (LinearLayout) findViewById(R.id.layout_empty);
            return;
        }
        if (child.getId() == R.id.layout_retry) {
            mRetryView = (LinearLayout) findViewById(R.id.layout_retry);
            mRetryView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    mRetryView.setVisibility(View.GONE);
                    mOnRetryClick.onRetry();
                }
            });
            return;
        }
        if (child.getId() == R.id.progress_bar) {
            mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
        }
    }

    public void loading() {
        mRetryView.setVisibility(View.GONE);
        mEmptyView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.VISIBLE);
    }

    public void empty() {
        mEmptyView.setVisibility(View.VISIBLE);
        mRetryView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
    }

    public void retry() {
        mRetryView.setVisibility(View.VISIBLE);
        mEmptyView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
    }

    public void success() {
        mRetryView.setVisibility(View.GONE);
        mEmptyView.setVisibility(View.GONE);
        mProgressBar.setVisibility(View.GONE);
    }

    public RecyclerView getRecyclerView() {
        return mRecyclerView;
    }

    public void setOnRetryClick(OnRetryClick onRetryClick) {
        mOnRetryClick = onRetryClick;
    }

    public interface OnRetryClick {
        void onRetry();
    }
}

Activity_xml

<...RecyclerViewEmptyRetryGroup
        android:id="@+id/recyclerViewEmptyRetryGroup">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"/>

        <LinearLayout
            android:id="@+id/layout_empty">
            ...
        </LinearLayout>

        <LinearLayout
            android:id="@+id/layout_retry">
            ...
        </LinearLayout>

        <ProgressBar
            android:id="@+id/progress_bar"/>

</...RecyclerViewEmptyRetryGroup>

введіть тут опис зображення

Джерело тут https://github.com/PhanVanLinh/AndroidRecyclerViewWithLoadingEmptyAndRetry


7

Використовуйте AdapterDataObserver у власному RecyclerView

Котлін:

RecyclerViewEnum.kt

enum class RecyclerViewEnum {
    LOADING,
    NORMAL,
    EMPTY_STATE
}

RecyclerViewEmptyLoadingSupport.kt

class RecyclerViewEmptyLoadingSupport : RecyclerView {

    var stateView: RecyclerViewEnum? = RecyclerViewEnum.LOADING
        set(value) {
            field = value
            setState()
        }
    var emptyStateView: View? = null
    var loadingStateView: View? = null


    constructor(context: Context) : super(context) {}

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}


    private val dataObserver = object : AdapterDataObserver() {
        override fun onChanged() {
            onChangeState()
        }

        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
            super.onItemRangeRemoved(positionStart, itemCount)
            onChangeState()
        }

        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            super.onItemRangeInserted(positionStart, itemCount)
            onChangeState()
        }
    }


    override fun setAdapter(adapter: RecyclerView.Adapter<*>?) {
        super.setAdapter(adapter)
        adapter?.registerAdapterDataObserver(dataObserver)
        dataObserver.onChanged()
    }


    fun onChangeState() {
        if (adapter?.itemCount == 0) {
            emptyStateView?.visibility = View.VISIBLE
            loadingStateView?.visibility = View.GONE
            this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
        } else {
            emptyStateView?.visibility = View.GONE
            loadingStateView?.visibility = View.GONE
            this@RecyclerViewEmptyLoadingSupport.visibility = View.VISIBLE
        }
    }

    private fun setState() {

        when (this.stateView) {
            RecyclerViewEnum.LOADING -> {
                loadingStateView?.visibility = View.VISIBLE
                this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
                emptyStateView?.visibility = View.GONE
            }

            RecyclerViewEnum.NORMAL -> {
                loadingStateView?.visibility = View.GONE
                this@RecyclerViewEmptyLoadingSupport.visibility = View.VISIBLE
                emptyStateView?.visibility = View.GONE
            }
            RecyclerViewEnum.EMPTY_STATE -> {
                loadingStateView?.visibility = View.GONE
                this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
                emptyStateView?.visibility = View.VISIBLE
            }
        }
    }
}

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:orientation="vertical">

    <LinearLayout
        android:id="@+id/emptyView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/emptyLabelTv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="empty" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/loadingView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical">

        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="45dp"
            android:layout_height="45dp"
            android:layout_gravity="center"
            android:indeterminate="true"
            android:theme="@style/progressBarBlue" />
    </LinearLayout>

    <com.peeyade.components.recyclerView.RecyclerViewEmptyLoadingSupport
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

у діяльності використовують такий спосіб:

recyclerView?.apply {
        layoutManager = GridLayoutManager(context, 2)
        emptyStateView = emptyView
        loadingStateView = loadingView
        adapter = adapterGrid
    }

    // you can set LoadingView or emptyView manual
    recyclerView.stateView = RecyclerViewEnum.EMPTY_STATE
    recyclerView.stateView = RecyclerViewEnum.LOADING

1
Якщо ви працюєте з цим рішенням, зверніть увагу, що використання переписок недостатньо через збільшення розміру розподілу пам'яті. Використовуйте цілий чи рядок залежно від вашого контексту з відповідними StringDefабо IntDefанотаціями
— Андрій Артамонов

2

Я додав RecyclerViewта альтернативу ImageViewдо RelativeLayout:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/no_active_jobs"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@mipmap/ic_active_jobs" />

    <android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

а потім у Adapter:

@Override
public int getItemCount() {
    if (mOrders.size() == 0) {
        mRecyclerView.setVisibility(View.INVISIBLE);
    } else {
        mRecyclerView.setVisibility(View.VISIBLE);
    }
    return mOrders.size();
}

7
як дістатися mRecyclerViewвсерединуAdapter
— Basheer AL-MOMANI

2
Це не дуже гарний зразок дизайну, щоб прив'язувати адаптер до конкретної діяльності. Краще зробити це через інтерфейси
— ruX

1
Також це спричиняє перевищення макета, що не рекомендується, і це може спричинити деякі проблеми з продуктивністю. Дивіться youtube.com/watch?v=T52v50r-JfE для більш детальної інформації
— Феліпе Конде

1

Ще один спосіб - це використання, addOnChildAttachStateChangeListenerякий обробляє з'являються / зникаючі дитячі погляди в RecyclerView.

recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(@NonNull View view) {
                forEmptyTextView.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onChildViewDetachedFromWindow(@NonNull View view) {
                forEmptyTextView.setVisibility(View.VISIBLE);
            }
        });

0

Просто у випадку, якщо ви працюєте з FirebaseRecyclerAdapter, ця публікація працює як шарм https://stackoverflow.com/a/39058636/6507009


7
Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
— Анх Фам
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.