Android SwipeRefreshLayout с пустым TextView не работает должным образом

Что я хочу сделать, так это разрешить пользователю прокручивать и обновлять список, не имеет значения, есть ли данные или нет. Но когда данные есть в списке, должен быть виден только список, а когда данных нет, должно быть видно пустое текстовое представление. В обоих случаях пользователь должен иметь возможность обновлять список свайпом.

Я попробовал какое-то решение, данное здесь, в этом обсуждении, но ни одно из них не работает, идея двух SwipeToRefresh отлично работает, как указано здесь, но показывает пустой контейнер даже при извлечении данных из сервер.

Я попробовал это со своей собственной логикой, обернув Listview и Textview внутри Relative/FrameLayout, но SwipeToRefresh принимает только одно представление в соответствии с его поведением.

Вот фрагмент xml, который я пробовал

 <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/activity_main_swipe_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.945" >


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

            <ListView
                android:id="@+id/event_list_eventlist"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@color/event_background"
                android:dividerHeight="1dp" >
            </ListView>

            <TextView
                android:id="@+id/event_txt_nothing_found"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerInParent="true"
                android:layout_centerVertical="true"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"
                android:visibility="gone" />
        </RelativeLayout>
    </android.support.v4.widget.SwipeRefreshLayout>

Пожалуйста помоги


person Bhavik Mehta    schedule 13.06.2015    source источник


Ответы (4)


Я решил ту же проблему, используя FrameLayout, посмотрите на код ниже:

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

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/layout_swipe_refresh"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ListView
            android:id="@+id/lv_products"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:divider="@null" />

    </android.support.v4.widget.SwipeRefreshLayout>

    <TextView
        android:id="@+id/tv_no_product"
        style="@android:style/TextAppearance.Medium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:gravity="center"
        android:text="@string/msg_no_listing"
        android:textColor="@color/primary_green"
        android:visibility="gone" />
</FrameLayout>

Вы также можете использовать RelativeLayout, но ключ заключается в размещении вашего ListView внутри SwipeRefreshLayout, а TextView снаружи.

person Phuc Tran    schedule 13.06.2015
comment
а что делать в активности? я имею в виду, позволяет ли эта реализация снова провести пальцем, если список пуст? - person Bhavik Mehta; 13.06.2015
comment
Конечно, вы можете провести еще раз, если список пуст. Я уверен, что это работает на 100%. - person Phuc Tran; 13.06.2015
comment
не могли бы вы добавить немного кода для активности, если это возможно? - person Bhavik Mehta; 13.06.2015
comment
Вы пробовали макет выше? - person Phuc Tran; 13.06.2015
comment
да, я пытаюсь, но этот код бесполезен без java-кода, пожалуйста, если вы можете мне помочь, - person Bhavik Mehta; 13.06.2015
comment
Можешь поделиться своей активностью? - person Phuc Tran; 13.06.2015
comment
Давайте продолжим обсуждение в чате. - person Bhavik Mehta; 13.06.2015
comment
Проблема в том, что если вы установите tv_no_product как emptyView для ListView, тогда ListView установит свою видимость в GONE, в то время как emptyView виден, и вы не сможете провести пальцем, чтобы обновить, когда ListView GONE. - person BladeCoder; 16.06.2015
comment
Нет необходимости устанавливать видимость ListView GONE. Потому что, если представление списка пусто, оно ничего не показывает, но все еще там. - person Phuc Tran; 16.06.2015
comment
Как говорит @BladeCoder с этим решением, вы не можете обновить пустой вид. Решение состоит в том, чтобы поместить FrameLayout (включая ListView и EmptyView) внутрь SwipeRefreshLayout. Также установите android:clickable=”true” в FrameLayout - person antoinem; 27.07.2015
comment
@antoiem Решение немного сложнее, чтобы оно работало правильно на Android 2.x, вам нужно переопределить SwipeRefreshLayout.canChildScrollUp() - person BladeCoder; 27.07.2015
comment
я пытался с этим, но, к сожалению, не работает для меня - person Amol Suryawanshi; 13.10.2016
comment
Можете ли вы загрузить свой макет куда-нибудь и прислать мне ссылку? - person Phuc Tran; 13.10.2016

У меня тоже была эта проблема, и я решил ее без дополнительного кода в действии, используя приведенный ниже макет.

Если вы используете ListActivity или ListFragment, он обрабатывает отображение/скрытие пустого представления для вас, а обновление также работает с пустым списком с этой структурой макета.

Никаких хаков не надо, все в SwipeRefreshLayout, как и должно быть.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/Refresher"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@null" />
        <ScrollView
            android:id="@android:id/empty"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:text="Geen formulieren gevonden"
                style="@style/text.EmptyView" />
        </ScrollView>
    </LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>

Надеюсь, это поможет любому, кто борется с этой проблемой.

person avb    schedule 16.07.2015
comment
Отлично, работает нормально. Мне интересно, почему? есть какое-то объяснение этому? - person GVillani82; 06.03.2016

Моя проблема кажется недокументированной, но если у адаптера для представления ресайклера нет данных, и вы вызвали функцию setLayoutManager, то представление ресайклера становится недоступным для перелистывания. Мое решение состояло в том, чтобы вызывать setLayoutManager только после получения некоторых данных.

person Daniel Wilson    schedule 05.02.2017
comment
Спасибо, это сработало. - person Saket89; 02.06.2021

окончательно решить проблему, используя следующий код

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_container"
        android:layout_below="@+id/search_product"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

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

            <ScrollView
                android:gravity="center"
                android:fillViewport="true"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <com.forysta.inloyal.view.textviews.RegularTextView
                    android:id="@+id/tv_no_shop_data"
                    style="@style/text_Size_16"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:text="@string/alert_nodatashop"
                    android:visibility="visible"
                    app:layout_collapseMode="parallax" />
            </ScrollView>
        </LinearLayout>
    </android.support.v4.widget.SwipeRefreshLayout>
person Amol Suryawanshi    schedule 13.10.2016