5

I am building an application that uses a ViewPager2 to scroll horizontally across pages that each have a vertically scrolling content RecyclerView where the first position of each list has a row with a Horizontally scrolling widget such as another RecyclerView or ViewPager2 attached to a Pager Indicator type widget as seen from the below image.

The parent ViewPager2 is a child of a CoordinatorLayout that handles collapsing the top content when the RecyclerView is scrolled Vertically. This ViewPager2 then inflates fragments that are horizontally scrolling. So we have for the parent layout:

-- CoordinatorLayout 
   -- FrameLayout - has appbar scrolling behavior 
      -- ViewPager2
   -- AppBarLayout
      -- CollapsingToolbarLayout
         -- ImageView - background
         -- Toolbar
         -- ConstraintLayout - Holds title and date

The parent ViewPager2 child fragments' layout:

-- FrameLayout
   -- RecyclerView
   -- Pager Indicator 

The first row of the content RecyclerView has the same layout:

-- FrameLayout
   -- RecyclerView
   -- Pager Indicator 

Unscrolled state

You can see from the above screenshot that on first load the RecyclerView is overlapping the AppBarLayout which is the correct behavior. I added negative marginTop to RecyclerView's parent layout to achieve this effect. I am tracking the AppBarLayout offset changes with a AppBarLayout.OnOffsetChangedListener and as the user scrolls up I am reducing or increasing this negative margin to have the list animate under the AppBarLayout.

The problem I am facing is if I start a vertical scroll from the first item in the list then the AppBarLayout is not getting triggered to start collapsing its content so the content ends up prematurely under the AppBarLayout. See the following screenshot:

RecyclerView incorrect scroll

I want the AppBarLayout content to start scrolling up as soon as I start the content RecyclerView scroll even if it is initiated from the first position. It seems that the first item's RecyclerView is not alerting the AppBarLayout to start collapsing. If I start the scroll from other items in the RecyclerView the correct behavior is observed. If I drag up and hold from the first row then the bug is also observed.

A good example of the behavior I am trying to achieve is the Google News App where there is a tab of news sections. The following is what I am expecting:

Correct vertical scroll animation

Marco RS
  • 8,145
  • 3
  • 37
  • 45

2 Answers2

3

The solution turned out to be simple. If you have a nested RecyclerView or similar container then you have to use:

RecyclerView.setNestedScrollingEnabled(false)
Marco RS
  • 8,145
  • 3
  • 37
  • 45
-1

i read through the offered answer(s) of using setNestedScrollingEnabled to false and it was awful for me as it makes the recyclerview not recycle and you can get crashes in memory, etc if you have a huge list. so i will give you a algorithm to make it work without confusing the coordinatorLayout.

  1. have a scroll listener on the vertical recyclerview, such as a scroll listener. anytime the list is scrolled you will get a callback that its being scrolled. you should also get a call back when its idle.

  2. now when vertical recylerview is being scrolled, setNestedScrollingEnabled = false on the horizontal list.

  3. once vertical recyclerview is idle setNestedScrollingEnabled = true on the horizontal list.

  4. also initially set the horizontal recyclerview to setNestedScrollingEnabled = false in xml

summary: essentially toggling off nested scrolling when user is scrolling vertically.

this work great with appbarlayout when coordinatorlayout gets confused with two recyclerviews in different directions.

j2emanue
  • 60,549
  • 65
  • 286
  • 456