Miljan Vulovic
Miljan Vulovic

Reputation: 1646

Issue with SwipeToRefresh layout in ViewPager fragment

So, I have activity with ViewPager and 2 fragments in it. In each fragment, I put the SwipeToRefreshLayout and a ListView. Xml looks like this:

<?xml version="1.0" encoding="utf-8"?>

*<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/going_out_activity_swipe_to_refresh"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">*
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/going_out_activity_list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_going_out"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_tab_new"/>


</RelativeLayout>


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

Now, there is a problem. When the list exceeds my screen, and I have to scroll down to see the items, when I try scrolling back up, it doesn't scroll, it refreshes(SwipeToRefreshLayout is called). How can I fix this?

Upvotes: 0

Views: 99

Answers (4)

user6044834
user6044834

Reputation:

This is how i did it, it scrolls perfectly and only refreshes when you swipe down when you are all the way to the top. I hope this helps.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.newthinktank.listviewexample2.app.MainActivity"
android:background="@drawable/background2"
android:layout_marginTop="65dp"
android:weightSum="1">

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

    <ListView
        android:id="@+id/lv1"
        android:layout_marginTop="15dp"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:background="#f0f0f0"
        android:alpha="0.90"
        android:layout_weight="1.01" />

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

This is how i use the swipetorefresh:

  mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipelayout);

    mSwipeRefreshLayout.setOnRefreshListener(
            new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    finish();
                    startActivity(getIntent());
                }
            }
    );

Upvotes: 0

ThaiPD
ThaiPD

Reputation: 3761

It's a bug when using ListView with SwipeToRefreshLayout. you can easy to fix it by using RecyclerView instead of ListView.

But if you want to keep to use ListView, Try with below code:

mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                boolean enable = false;
                if (ptrListView != null && mListView.getChildCount() > 0) {
                    boolean firstItemVisible = (mListView.getFirstVisiblePosition() == 0);
                    boolean topOfFirstItemVisible = (mListView.getChildAt(0).getTop() == 0);
                    enable = firstItemVisible && topOfFirstItemVisible;
                }
                mSwipeRefreshLayout.setEnabled(enable);
            }
        });

Upvotes: 1

yennsarah
yennsarah

Reputation: 5517

Taken from the android docs:

They use a ListFragment, but you should be able to do the necessary changes: You should add and use a custom SwipeRefreshLayout, where you define the conditions for scrolling:

private class ListFragmentSwipeRefreshLayout extends SwipeRefreshLayout {

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

    /**
     * As mentioned above, we need to override this method to properly signal when a
     * 'swipe-to-refresh' is possible.
     *
     * @return true if the {@link android.widget.ListView} is visible and can scroll up.
     */
    @Override
    public boolean canChildScrollUp() {
        final ListView listView = getListView();
        if (listView.getVisibility() == View.VISIBLE) {
            return canListViewScrollUp(listView);
        } else {
            return false;
        }
    }

}

/**
 * Utility method to check whether a {@link ListView} can scroll up from it's current position.
 * Handles platform version differences, providing backwards compatible functionality where
 * needed.
 */
private static boolean canListViewScrollUp(ListView listView) {
    if (android.os.Build.VERSION.SDK_INT >= 14) {
        // For ICS and above we can call canScrollVertically() to determine this
        return ViewCompat.canScrollVertically(listView, -1);
    } else {
        // Pre-ICS we need to manually check the first visible item and the child view's top
        // value
        return listView.getChildCount() > 0 &&
                (listView.getFirstVisiblePosition() > 0
                        || listView.getChildAt(0).getTop() < listView.getPaddingTop());
    }
}

Upvotes: 1

Veeresh Charantimath
Veeresh Charantimath

Reputation: 4719

Try Adding the Swipe to Refresh Layout to your ListView only.

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
android:id="@+id/going_out_activity_swipe_to_refresh"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">*
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_going_out"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_tab_new"/>


</RelativeLayout>

Upvotes: 0

Related Questions