4

I have a fragment that contain a SwipeRefreshLayour with a RecyclerView inside.

This recyclerView doesn't show overscroll effects. I tried a lot of things like use this:

 android:isScrollContainer="true"
 android:overScrollMode="always"

Custom color via styles doesn't work

fadingEdge, fadingEdgeLengh, requiresFadingEdge...

Swipe to refresh is working and it shows this:

enter image description here

I don't get this:

enter image description here

JavierSegoviaCordoba
  • 6,531
  • 9
  • 37
  • 51
  • It would really help to answer if you could post your layout and activity/fragment code, (or at least the relevant parts to this issue). – RestingRobot Aug 28 '17 at 23:53
  • It is not a layout or code problem, I created a default activity with overscroll via android studio templates (ScrollingActivity), and in my app it hasn't overscroll effects. – JavierSegoviaCordoba Aug 28 '17 at 23:56
  • Okay, I created a new app with the default ScrollingActivity and now it hasn't overscroll when a older app of this same ScrollingActivity has overscroll, I am using Android Studio 3.0 beta 2 with the lastest support library. Maybe it is causing this bug? – JavierSegoviaCordoba Aug 28 '17 at 23:59
  • The default is working for me – RestingRobot Aug 29 '17 at 00:07
  • hold on i will post a video. Keep in mind you need to have velocity for it to trigger. I am using the latest version of android studio as well – RestingRobot Aug 29 '17 at 00:11
  • I failed, with Android 2.3.3 it has overscroll effects. It is a bug caused by Android Studio 3.0 beta 2 – JavierSegoviaCordoba Aug 29 '17 at 00:11
  • Ok i see I am using 2.3.3. But here it is working anyways https://giphy.com/gifs/1Zw0ZeTP8tljq – RestingRobot Aug 29 '17 at 00:13
  • I am going to report this bug. One question, do you know how to force to show always overscroll. For example, if you open Play Store navigation drawer and scroll down you can check what I mean – JavierSegoviaCordoba Aug 29 '17 at 00:19

2 Answers2

1

I just solved it by overwriting the SwipeRefreshLayout and using it instead of the default implementation:

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout

class SwipeRefreshLayoutWithRecyclerViewOverscroll : SwipeRefreshLayout {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    override fun onStartNestedScroll(child: View, target: View, nestedScrollAxes: Int): Boolean =
        (child.canScrollVertically(1) && super.onStartNestedScroll(child, target, nestedScrollAxes))

}

I'm using a RecyclerView that is a linear vertical list and child.canScrollVertically(1) checks wether this list is currently at the very bottom. If it is at the bottom of the list onStartNestedScroll returns false, allowing the RecyclerView to handle the pull up motion of the user so that an overscroll effect is shown.

NOTE: This only shows the bottom edge overscroll and not the top one, because I don't want to see the pull-to-refresh animation together with the top overscroll edge.

0

In my implementation of this feature, (the over-scroll is working on both top and bottom), I have my layout like this:

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

<...<custom view>...SwipeRefreshWrapper
    android:id="@+id/swiperefresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

        <RecyclerView
            android:id="@+id/video_recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <include layout="@layout/include_video_list_empty_view"/>
        <include layout="@layout/include_watchlist_empty_view"/>

    </FrameLayout>
<SwipeRefreshWrapper>

And my SwipeRefreshWrapper implementation is as follows:

/**
* This Class ensures that a SwipeRefreshLayout will only refresh if the
* list it wraps cannot scroll up anymore, (that it is at the top). Otherwise
* when the user attempts to scroll up from the middle of the list, the refresh
* will trigger. This is necessary for custom List implementations, (or
* RecyclerViews), only.
*/
public class SwipeRefreshWrapper extends SwipeRefreshLayout {
     private ScrollResolver mScrollResolver;

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

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

     public void setScrollResolver(ScrollResolver scrollResolver) {
         mScrollResolver = scrollResolver;
     }

     @Override
     public boolean canChildScrollUp() {
         if(mScrollResolver != null){
             return mScrollResolver.canScrollUp();
         } else {
             return super.canChildScrollUp();
         }
     }

     public static interface ScrollResolver{
         public boolean canScrollUp();
     }
}

Then in my Fragment I setup the SwipeRefreshLayout:

 /**
 * Initializes PullToRefresh handler
 */
private void initPullToRefresh() {
    mSwipeRefreshLayout = (SwipeRefreshWrapper) mView.findViewById(R.id.swiperefresh_layout);
    mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorAccent);

    mSwipeRefreshLayout.setScrollResolver(new SwipeRefreshWrapper.ScrollResolver() {
        @Override
        public boolean canScrollUp() {
            return mVideoRecycler.canScrollVertically(-1);
        }
    });

    mSwipeRefreshLayout.setOnRefreshListener(...)
}
RestingRobot
  • 2,938
  • 1
  • 23
  • 36
  • I created a scrolling activity and even this activity, with nested scroll, hasn't overscroll. I don't understand why I have no overscroll effects on my app – JavierSegoviaCordoba Aug 28 '17 at 23:34
  • In menus with a lot of items I have overscroll effects, so it is only on activities elements like recyclerview or nestedscrollview – JavierSegoviaCordoba Aug 28 '17 at 23:37
  • Can you post your code for this activity? Are you overriding the scroll events perhaps? – RestingRobot Aug 28 '17 at 23:37
  • I have no override any scroll on this activity. It just a nested scrollview with a few elements to show some texts. Really a simple activity. There is no scroll word even it the java file. – JavierSegoviaCordoba Aug 28 '17 at 23:42
  • I created a scrollingactivity via template with zero changes (I know 100% this activity has overscroll) and in my app hasn't it, so it should be a style problem no? – JavierSegoviaCordoba Aug 28 '17 at 23:47
  • Your scroll view should only have 1 child element, this could be your issue. In the example I posted, I have a framelayout that holds the recyclerview and some extra views. – RestingRobot Aug 28 '17 at 23:51
  • it is the default scrolling activity, you can create by yourself in Android Studio if you want to check it has overscroll but mine no. – JavierSegoviaCordoba Aug 28 '17 at 23:52
  • If you are using a recyclerview, why do you need a scrollview? I see that the default activity uses a NestedScrollView. – RestingRobot Aug 28 '17 at 23:56
  • It is other activity, I think is a bug on Android Studio 3.0 beta 2 or the lastest support libraries, no one scrollview/recycler view of any of my new apps have overscroll. – JavierSegoviaCordoba Aug 29 '17 at 00:00
  • I am guessing if you added views to the sample that you still have the NestedScrollView as the root view, try making your ScrollView the root view and see if that fixes the issue. See here for an example: http://ivankocijan.xyz/android-nestedscrollview/ – RestingRobot Aug 29 '17 at 00:00
  • You do not need a scroll view around a recycler view, it handles its own scrolling. The NestedScrollView is specifically for the instance of putting a ScrollView inside of another ScrollView. Try removing the root scrollview and let the list do the scrolling – RestingRobot Aug 29 '17 at 00:02
  • I created a new app of scrolling activity (check it by yourself in Android Studio), default scrolling activity, zero changes. It hasn't overscroll. This same app in the past had overscroll 100% for sure. it has to be a bug. – JavierSegoviaCordoba Aug 29 '17 at 00:03
  • It works for me. This is taken from the [documentation for ScrollViews](https://developer.android.com/reference/android/widget/ScrollView.html) **Never add a RecyclerView or ListView to a scroll view. Doing so results in poor user interface performance and a poor user experience.** – RestingRobot Aug 29 '17 at 00:06