36

I have the following layout

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
            //some views here
        </LinearLayout>

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:stretchColumns="*" >
        </TableLayout>

    </LinearLayout>

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

The problem is when I scrolldown the table, I can't scrollUp again because the swipelayout is being triggered. How can I trigger the swiperefresh only when the first view of the table is visible?

Mika Sundland
  • 18,120
  • 16
  • 38
  • 50
user3009752
  • 164
  • 2
  • 9
  • 24
  • Please post the full xml for this layout and the other_layout, as I don't see your `SwipeRefreshLayout`... for reference, `SwipeRefreshLayout` can only have 1 child view. – sddamico Aug 13 '14 at 20:09
  • I editted my question. Sorry for the misleading information! – user3009752 Aug 14 '14 at 09:02

4 Answers4

107

I found that if you replace your ScrollView with a android.support.v4.widget.NestedScrollView the scrolling behavior will work as you expect it to.

jjnguy
  • 136,852
  • 53
  • 295
  • 323
  • 3
    My problem is a little bit different. No matter where on the screen whenever i swipe down, the SwipeRefreshLayout pickup the motion , making it unable to scroll the view down, unless it's in refreshing state. Or I must swipe up first then swipe down without remove the finger. Your solution helped alot. Thanks. – Phuong Dao Jul 05 '17 at 10:23
  • 5
    In case if you have migrated to androidX, use `androidx.core.widget.NestedScrollView` – Kishita Variya Nov 29 '19 at 19:02
10

Make your own implementation of SwipeRefreshLayout and override the canChildScrollUp in this way:

    @Override
public boolean canChildScrollUp() {
    if (scrollView != null)
        return scrollView.canScrollVertically(-1);

    return false;
}

just replace with any subclass of ScrollView.

Rishabh
  • 386
  • 1
  • 9
7

If you have layout like this:

<SwipeRefreshLayout>
    <android.support.v4.widget.NestedScrollView
        android:id="@+id/your_scroll_view_id">
        <LinearLayout>
        ...
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</SwipeRefreshLayout>

You need to create your own class and override the function in this way:

class SwipeRefreshLayoutCustom extends SwipeRefreshLayout {
    public SwipeRefreshLayoutCustom(Context context, AttributeSet attributes) {
        super(context, attributes)
    }
    @override
    boolean canChildScrollUp() {
        return your_scroll_view_id.scrollY != 0
    }
}
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Oleg Vitols
  • 71
  • 2
  • 3
  • If the LinearLayout Contains a bunch of other views with a RecyclerView, then the RecyclerView will actually behave like a list view, all viewholders biind method will be called at once. – Karan Sharma Jun 11 '21 at 16:16
-4

Use NestedScrollView with:

     app:layout_behavior="@string/appbar_scrolling_view_behavior"