15

I am getting this error in my Pre-Launch Reports, but it doesn't show any references to my .java files. Can anyone please shed some light on this?

I'm using a ViewPager2 (1.0.0) with page transformations.

Issue: java.lang.IllegalStateException: Page can only be offset by a positive amount, not by -54
 FATAL EXCEPTION: main
Process: [redacted], PID: 18424
java.lang.IllegalStateException: Page can only be offset by a positive amount, not by -54
    at androidx.viewpager2.widget.ScrollEventAdapter.updateScrollEventValues(ScrollEventAdapter.java:280)
    at androidx.viewpager2.widget.ScrollEventAdapter.onScrolled(ScrollEventAdapter.java:178)
    at androidx.recyclerview.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:5173)
    at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5338)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
    at android.view.Choreographer.doCallbacks(Choreographer.java:670)
    at android.view.Choreographer.doFrame(Choreographer.java:603)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
    at android.os.Handler.handleCallback(Handler.java:746)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5459)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

I found this page about ViewPager2 with reference to a similar error being a bug of ViewPager2.

Possibly relevant:

I only started getting this error very recently. I recently changed my code in the following manner. I'm overriding the getItemCount() method, and the NUM_PAGES value that it returns varies depending on a selectable option elsewhere. Previously I would just recreate() the Activity holding all the Fragments when this option is toggled. Instead, now I call Objects.requireNonNull(recyclerViewAdapter).notifyDataSetChanged(); and it works nicely. I'm not sure if this is the correct way to add/remove or show/hide the rightmost fragment, as other options leaves an empty page where the fragment normally would be.

EDIT: I removed my PageTransformer from the ViewPager2 - which only sets the alpha - and the error is currently gone. But I think it may be co-incidence. I haven't seen the error 'in the wild', only in the Pre-Launch Reports intermittently.

EDIT: I have no ViewGroups in my Fragments with layout animations: Not animating ViewGroups

grolschie
  • 2,163
  • 2
  • 12
  • 29
  • show your xml and javacode – Prajwal Waingankar Jan 09 '20 at 09:23
  • There's way too much to copy/paste. Another thought is that I'm doing something possibly naughty by calling ```this.onresume()``` from my activity, since I want my app to think this Activity has just been resumed. The issue is intermittent, but I haven't seen it happen on emulator or real device. – grolschie Jan 09 '20 at 09:34
  • I removed my call to ```this.onresume()``` and created a new method with the same code from ```onresume()``` method and its seems that the errors are gone. – grolschie Jan 11 '20 at 05:42
  • Forget that. The error went away, and now is back... – grolschie Jan 16 '20 at 06:50
  • I have disabled my ```ViewPager2.PageTransformer``` (which merely adjusts the alpha), and the problem is gone again. For now... – grolschie Jan 23 '20 at 19:26
  • had the same issue. resolved it by adding `pager.setOffscreenPageLimit(2);` – Deepak Goyal Oct 28 '20 at 14:10

3 Answers3

17

This error can occur if you have a ViewGroup with animateLayoutChanges set to true in your ViewPager2's child fragments.

If this is the case, you need to tell that ViewGroup to only animate its own layout changes and not those of the ViewPager2, by calling

viewGroup.layoutTransition.setAnimateParentHierarchy(false)

as detailed in that answer.

The ViewPager2 documentation explains it :

If your pages contain LayoutTransitions, then those LayoutTransitions must have animateParentHierarchy set to false.

Note that if you have a ViewGroup with animateLayoutChanges="true" in your layout xml file, a LayoutTransition is added automatically to that ViewGroup.

You will need to manually call getLayoutTransition().setAnimateParentHierarchy(false) on that ViewGroup after you inflated the xml layout.

Community
  • 1
  • 1
Ronan
  • 398
  • 3
  • 12
  • 1
    I encountered the error and was able to reproduce it, then solve it by adding that instruction. In my case, the error occured when going back to the first page of the ViewPager2 after having gone to the sixth page, at which point the fragment of the first page had been destroyed and had to be rebuild. – Ronan Mar 05 '20 at 09:54
  • Hi @Ronan. Thanks for that. However, I do not have any page animations (that I know of) and no ViewGroups defined. The error only shows up intermittently on the Pre-Launch Reports, and not actual devices. – grolschie Mar 06 '20 at 23:23
  • 2
    Alright, sorry It couldn't help in your case. Just to clarify, ViewGroup is actually the parent class of all layouts (LinearLayout, ConstraintLayout, FrameLayout, etc.) so you do have some defined even if you don't know it. In my case the ConstraintLayout at the root of my child fragment had the attribute `animateLayoutChanges="true"` set in xml, which automatically animates layout changes (e.g. views appearing or disappearing). – Ronan Mar 10 '20 at 10:46
  • from the source code in ScrollEventAdapter.java, the bad thing is the version of viewpage2 1.0.0 which had considered the situation triggered by animateLayoutChanges, if triggered by that, viewpager2 will throw the exact tip like : "Page(s) contain a ViewGroup with a " + "LayoutTransition (or animateLayoutChanges=\"true\"), which interferes with the scrolling animation. Make sure to call getLayoutTransition().setAnimateParentHierarchy(false) on all ViewGroups with a LayoutTransition before an animation is started." – wjploop Nov 16 '22 at 12:38
1

I had this problem as I was overriding getItemCount in the adapter so I can effectively lazy-load a large number of pages. The issue for me came when I tried to call viewPager.setCurrentItem(newPosition); for an item that was a long way off and the ViewPager tried to animate that change. After I changed the call to viewPager.setCurrentItem(newPosition, false); (which disabled smooth scrolling), I stopped getting this error.

Praxder
  • 2,315
  • 4
  • 32
  • 51
  • Thanks. I am overriding ```getItemCount```, but all it does is return the fixed number of pages. But this is a good opportunity to revisit this error - which I haven't seen in months. – grolschie May 01 '21 at 02:15
0

It's an bug in ViewPager2, which is caused when calculating the offset of the first item in RecyclerView. Try removing start/left side separator, and paddingLeft/paddingStart.

Source

isaaaaame
  • 460
  • 4
  • 9
  • Thanks. The thing is that it's been working for months now and now started with this intermittent error. I'm not even touching any margins or padding. The Fragments take up the whole screen. – grolschie Jan 09 '20 at 09:38