timusus / RecyclerView-FastScroll

A simple FastScroller for Android's RecyclerView
Other
1.39k stars 182 forks source link

Add support for CoordinatorLayout offset behaviors #7

Closed timusus closed 6 years ago

timusus commented 8 years ago

When the parent RecyclerView is contained in a ViewGroup with another view whose scrolling behavior causes the RecyclerView to be pushed down, the FastScroll track and thumb moves off-screen with the RecyclerView.

There should be some sort of adjustment to allow the FastScroll track, thumb & scroll-range to remain fixed even when the parent RecyclerView is moved down.

ezamelczyk commented 8 years ago

Has that issue been resolved? I'm currently having the same problem.

NammariMarkavip commented 8 years ago

@soberowy refer to my fork for solution

timusus commented 8 years ago

See #19 for a potential (unconfirmed) fix. I haven't been able to confirm whether #19 is a general fix for this issue, or whether it's more of a work-around for specific scenarios.

loki666 commented 8 years ago

19 doesn't fix the issue when the RecyclerView is in a CoordinatorLayout

jiansheliuxing commented 8 years ago

does 1.0.9 has fixed this issue?

loki666 commented 8 years ago

nop, I was testing on 1.0.9

jiansheliuxing commented 8 years ago

Phonograph is also using this widget and it's well performed. I can't find out how Phonograph fixed this issue.

timusus commented 8 years ago

@kabouzeid, IIRC you were saying you felt that you had more of a workaround than a fix.. Would you share that workaround here?

jiansheliuxing commented 8 years ago

@loki666 @timusus I find a way. AppBarLayout has a method 'addOnOffsetChangedListener', so we can add an 'OnOffsetChangedListener' into it. With the callback method 'onOffsetChanged' we can do something on pading or margin. but, it may consume much cpu.

jahirfiquitiva commented 6 years ago

@timusus

There's an old abandoned library that has support for this. Maybe you can check its code and try to port it to yours?

Here's the line that connects CoordinatorLayout and AppBarLayout to the fast scroll.

zhanghai commented 6 years ago

I've also encountered this issue just now, with almost the same layout as the sample in @Nammari 's PR.

There should be some sort of adjustment to allow the FastScroll track, thumb & scroll-range to remain fixed even when the parent RecyclerView is moved down.

This approach seemed plausible to me at first glance, however after looking into it I found that in the CoordinatorLayout setup the whole RecyclerView is pushed down, which means you cannot reveal the very bottom of the list without pushing it up again. So simply limiting the height of the FastScroll track won't fix this issue.

My observation about the fix by @Nammari is that in his PR the AppBarLayout will be collapsed/expanded (with an animation) after the user starts dragging the fast scroll thumb (but still no idea about his magic ±3). This is a possible fix, however I'm feeling it would still feel a little bit bumpy to users (AppBarLayout suddenly moving regardless of user's touch movement distance).
(Disclaimer: I merely looked at his changes but didn't run it.)

So I think a proper fix can be the same as what happens when you drag the RecyclerView itself, i.e. nested scrolling, that the RecyclerView should pass on the scroll to CooridnatorLayout (or whatever nested scrolling parent) before using it for fast scroll.

And maybe another possibility would be changing the nested scrolling behavior so that the RecyclerView is resized instead of pushed down.

(But still, I haven't figured out what @kabouzeid did in his Phonograph, which worked perfectly.)

zhanghai commented 6 years ago

After some digging into Phonograph I've found out his fix 😀

He was taking the approach that I mentioned as the other possibility, i.e. "changing the nested scrolling behavior so that the RecyclerView is resized instead of pushed down", by changing the bottom padding in AppBarLayout.OnOffsetChangedListener (which a bit to my surprise didn't impact the scrolling performance so much despite the re-layout).

You can see his listener implementation here. It worked perfectly for me.

container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), container.getPaddingRight(), appbar.getTotalScrollRange() + verticalOffset);

And it would also be nice if this could be added to README :smile:

kabouzeid commented 6 years ago

Good that you found it, I didn't remember where exactly I did this 😅

yaroslav-shlapak commented 6 years ago

Thanks @kabouzeid and @DreaminginCodeZH Based on previous comments, Kotlin solution:

appbar.addOnOffsetChangedListener(
                AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
                    recyclerContainer?.setPadding(
                            recyclerContainer.paddingLeft,
                            recyclerContainer.paddingTop,
                            recyclerContainer.paddingRight,
                            (appBarLayout?.totalScrollRange ?: 0) + verticalOffset
                    )
                }
        )
timusus commented 6 years ago

I think the responsibility for working around this issue falls outside of the scope of this library. Thus, closing this issue.