Skip to content Skip to sidebar Skip to footer

Android Support V4 SwipeRefreshLayout Empty View Issue

SwipeRefresh is not working after setting an empty view for listview which is the only child of a SwipeRefresh layout. How to solve this issue?

Solution 1:

Here is the solution: You can simply use this view hierarchy :

    <FrameLayout ...>

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

            <ListView
                android:id="@android:id/list" ... />
        </android.support.v4.widget.SwipeRefreshLayout>

        <TextView
            android:id="@android:id/empty" ...
            android:text="@string/empty_list"/>
    </FrameLayout>

Then, in code, you just call:

_listView.setEmptyView(findViewById(android.R.id.empty));

That's it.


Solution 2:

I had this issue too, and solved it without any additional code in the activity by using the layout below.

If you are using a ListActivity or ListFragment it handles showing/hiding the empty view for you, and refreshing works with an empty list as well with this layout structure.

No hacks needed, everything is in the SwipeRefreshLayout, as it should be.

<?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>

Hope this helps you. If so, don't forget to accept the answer.

Note: this is a duplicate of my answer to this question, but that question is pretty much a duplicate of this question... :)

UPDATE
If the SwipeRefreshLayout is activated too early, you can implement ListView.OnScroll with:

_refresher.Enabled = e.FirstVisibleItem == 0;

This disables the refresher until you scrolled to the top. This is only needed when using a ListView, the new RecyclerView works as expected.


Solution 3:

The problem for me was that when the empty view was visible then the refreshing circle wasn't shown although the refreshing method worked. For me this code worked, I hope it helps.

  • the xml layout:

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clickable="true">
    
        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fadingEdge="none"
            android:footerDividersEnabled="false"
            android:headerDividersEnabled="false"/>
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">
    
            <TextView
                android:id="@+id/empty_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:gravity="center"
                android:visibility="gone"/>
        </ScrollView>
    </FrameLayout>
    

  • the custom SwipeRefreshLayout:

    package misc;
    
    import android.content.Context;
    import android.support.v4.widget.SwipeRefreshLayout;
    import android.widget.ListView;
    
    public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {
        private ListView mListView;
    
        public CustomSwipeRefreshLayout(Context context) {
            super(context);
        }
    
        public void setListView(ListView listView) {
            mListView = listView;
        }
    
        @Override
        public boolean canChildScrollUp() {
            if (mListView == null) {
                return true;
            }
    
            return mListView.canScrollVertically(-1);
        }
    }
    
  • and in my Fragment where I use the layout I only set the swipe to refresh layout in this way:

    mSwipeRefreshLayout.setListView(mListView);
    
  • the ListView's empty view is set in this way:

    TextView emptyView = (TextView) view.findViewById(R.id.empty_view);
    emptyView.setText("No data");
    mListView.setEmptyView(emptyView);
    

I hope it helps.


Solution 4:

here's how i did this (probably not very elegant solution)

private void createEmptyView() {
    ViewGroup parent = (ViewGroup) listView.getParent();
    emptyView = (TextView) getLayoutInflater(null)
            .inflate(R.layout.view_empty, parent, false);
    parent.addView(emptyView);
    listView.setEmptyView(emptyView);
}

public class FrameSwipeRefreshLayout extends SwipeRefreshLayout {

    private ViewGroup listView;
    public void setListView(ViewGroup list) {
        listView = list;
    }

    @Override
    public boolean canChildScrollUp() {
        if (listView != null) {
            View child = listView.getChildAt(0);
            return child != null && child.getTop() != 0;
        }
        return super.canChildScrollUp();
    }
}

empty layout

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:gravity="center_horizontal"
      android:clickable="true" />

list layout

    <FrameSwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <FrameLayout
            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"
            />
        </FrameLayout>
    </FrameSwipeRefreshLayout>

Solution 5:

You can check out this issue. I posted a work around solution.

Android - SwipeRefreshLayout with empty textview


Post a Comment for "Android Support V4 SwipeRefreshLayout Empty View Issue"