Як показати порожній вигляд за допомогою 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.