15

I am trying to implement a ViewPager-like behavior for a horizontal RecyclerView. The data from the adapter should inflate and bind as normal, but the navigation through the Recycler should be handled differently. When the user swipes (or attempts to scroll), I move the Recycler one item in that direction, sticking it to the left side.

I already have all the item transition logic. I am using a custom LayoutManager, which overrides onSmoothScrollToPosition() with a custom LinearSmoothScroller() which does the item to-the-left sticking.

The question is - how can I override the scrolling behavior of the RecyclerView to intercept the swipes and handle them myself? I tried disabling scrolling in the LayoutManager and then intercepting the gesture in an onTouchListener, but this does not seem to work. Does the RecyclerView framework have a clean way to handle this?

Kelevandos
  • 7,024
  • 2
  • 29
  • 46
  • I think intercepting the gesture in `onTouchListener` should already do the trick. What's not working about that solution? – EpicPandaForce Mar 31 '16 at 09:22
  • Well, It does not intercept anything for some reason. I assume this may be caused by the fact that the horizontal Recycler is in a page of a larger pager (Fragment Pager for sections of the app) and it just passes the gesture to the top pager :( – Kelevandos Mar 31 '16 at 09:25
  • @EpicPandaForce I managed to get it to work, turns out I had to implement onScroll() in the SimpleGestureListener, not just onFling(). However, there is a problem with that as well - the onScroll() method will trigger multiple times, resulting in the Recycler going through all items at once. Any patterns to handle this? – Kelevandos Mar 31 '16 at 11:10

3 Answers3

29

The native Android solution covered in this post was a super easy way to get the RecyclerView to behave like a ViewPager.

Relevant bits:

The 24.2.0 version of the support library introduced two new classes (SnapHelper and LinearSnapHelper) that should be used to handle snapping in a RecyclerView. .... The only code needed is:

SnapHelper snapHelper = new LinearSnapHelper(); snapHelper.attachToRecyclerView(recyclerView);

SnapHelper snapHelper = new GravitySnapHelper(Gravity.START); snapHelper.attachToRecyclerView(startRecyclerView);

sorter
  • 513
  • 6
  • 8
  • 1
    Please include the relevant part of your linked page in your answer. A link-only answer is not user friendly, and becomes totally useless if the link dies! – BenMorel May 19 '17 at 20:13
  • 7
    PagerSnapHelper is another class available that extends SnapHelper. It works well if you want paging-like behavior. – iOS_Mouse May 11 '20 at 22:55
  • 1
    Was one step away from giving up the search and stat coding it myself, then I found your comment. – Dinu Nicolae Aug 15 '20 at 08:06
2

Attach your RecyclerView to SnapHelper

Official Doc

Library

Aks4125
  • 4,522
  • 4
  • 32
  • 48
  • 1
    And how will this help? – Kelevandos Mar 31 '16 at 09:24
  • @Kelevandos use custom scrollview to detect YScroll. [reference](http://stackoverflow.com/questions/2646028/android-horizontalscrollview-within-scrollview-touch-handling) – Aks4125 Mar 31 '16 at 09:30
  • You mean a ScrollView wrapper for the RecyclerView? This could work, but I hope there is a way to handle this in a clean way using the RecyclerView framework :-( – Kelevandos Mar 31 '16 at 09:32
  • You should go with this, believe me I've done R&D and came up with this. working smoothly without any issue – Aks4125 Mar 31 '16 at 09:35
2

there is a library layoutmanagers exactly for this.

the one that you need is ViewPagerLayoutManager. It is based on the same idea you already have but more extended and handles multiple cases. It basically scrolls until there is a change of page & state then takes over and adjust to the right page.

To use it you just need to set it as a normal Layout manager:

recyclerView.setLayoutManager(new ViewPagerLayoutManager(getActivity()));

for more info and examples check here

kalin
  • 3,546
  • 2
  • 25
  • 31