Текст вместо RecyclerView при отсутствии подключения к интернету

У меня есть приложение с загрузкой изображений из интернета в RecyclerView. И хотелось бы, чтобы при отключенном интернете вместо RecyclerView отображался TextView с соответствующим сообщением об отсутствии подключения к интернету. Попадались решения, где просто создавали новый layout с TextView с текстом "Нет интернет подключения" и в зависимости от того, есть подключение или нет происходит переключение между этим макетом и макетом с RecyclerView. Но, как мне показалось, это немного странно. Может быть, есть более изящное решение?


Ответы (2 шт):

Автор решения: Sergei Buvaka

Решение тут достаточно простое, вот небольшой пример:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/app_light_background"
    tools:context=".ui.moviedetails.fragments.ReviewsFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

    <LinearLayout
        android:id="@+id/empty_data_screen"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:visibility="gone"
        tools:visibility="visible">

        <TextView
            android:id="@+id/message_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/empty_search_text_margin"
            android:fontFamily="sans-serif-medium"
            android:gravity="center"
            android:textColor="@color/app_primary_color"
            android:textSize="@dimen/empty_search_text_size"
            tools:text="@string/empty_search_text" />

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/empty_search_result"
            tools:ignore="ContentDescription" />
    </LinearLayout>

</FrameLayout>

В вашей View если вы получаете корректные данные то делаете

recyclerView.setVisibility(View.VISIBLE);
emptyDataScreen.setVisibility(View.GONE);

в случае отсутствия интернета тоже самое только наоборот, скрываете Recycler и показываете emptyScreen.

Выдумывать какие-то другие велосипеды тут нет никакого смысла.

→ Ссылка
Автор решения: Andrey Mihalev

Можно сделать свой класс основанный на RV, например RecyclerViewEmpty.java:

public class RecyclerViewEmpty 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);
                    RecyclerViewEmpty.this.setVisibility(View.GONE);
                }
                else {
                    emptyView.setVisibility(View.GONE);
                    RecyclerViewEmpty.this.setVisibility(View.VISIBLE);
                }
            }

        }
    };

    public RecyclerViewEmpty(Context context) {
        super(context);
    }

    public RecyclerViewEmpty(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RecyclerViewEmpty(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;
    }
}

Ваша разметка должна содержать и RecyclerViewEmpty и нужный View:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   ...>

   <local.example.mytest.RecyclerViewEmpty
        android:id="@+id/RVlist"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
   <TextView
        android:id="@+id/emptyText"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />
...
</LinearLayout>

Все что нужно сделать в основном классе, это объявить View и передать его в RV:

...
TextView emptyText=findViewById(R.id.emptyText);
recyclerView.setEmptyView(emptyText);
...

Вместо TextView в разметке можете использовать любой другой View. Например Layout содержащий ImageView TextView и тд

→ Ссылка