ViewPager2报Page can only be offset by positive amount异常求助
java.lang.IllegalStateException: Page can only be offset by a positive amount in ViewPager2 1.0.0 Let’s tackle this frustrating ViewPager2 crash you’re seeing in Pre-Launch Reports. I’ve dealt with similar edge cases before, so let’s break down what’s happening and how to resolve it:
First, Understand the Crash
This is a confirmed bug in the older ViewPager2 1.0.0 release. The error fires from the internal ScrollEventAdapter class when it encounters a negative scroll offset—something that shouldn’t happen during normal operation. Since your stack trace doesn’t reference any of your own code, it’s clear this is an internal inconsistency triggered by your data update or view customization logic.
Here’s the crash log you shared for reference:
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)
Addressing Your Code Changes
1. Dynamic getItemCount() + notifyDataSetChanged()
You switched from recreating the Activity to calling notifyDataSetChanged() when updating the number of pages. While this works, we can make it more robust:
- Use granular notify methods: Instead of the blunt
notifyDataSetChanged(), trynotifyItemInserted()ornotifyItemRemoved()when adding/removing pages. This helps ViewPager2 track page positions accurately, reducing the chance of scroll offset glitches. - Reset the current item first: If granular updates aren’t feasible, call
viewPager2.setCurrentItem(0, false)beforenotifyDataSetChanged()when the page count drops significantly. This resets the viewpager to a safe starting point before updating data.
2. Alpha-Only PageTransformer
Your observation that removing this transformer stopped the crash isn’t a coincidence. Some custom PageTransformers interfere with ViewPager2’s internal scroll calculations, especially if they modify view properties in ways that confuse the ScrollEventAdapter.
- If you need the alpha effect, try simplifying your transformer implementation. Alternatively, upgrade ViewPager2 to a newer version (1.1.0+) where many of these scroll-related bugs were fixed—you might find the transformer works without crashing.
3. Pre-Launch Report Specificity
Since you don’t see this crash in real-world use, it’s likely triggered by the test robots’ aggressive scroll gestures during data updates. This confirms it’s an edge case in the outdated 1.0.0 version.
Top Recommendation: Upgrade ViewPager2
The most reliable fix is to update your ViewPager2 dependency to at least version 1.1.0 (or the latest stable release). Google fixed dozens of scroll offset and data update bugs in post-1.0.0 versions, which will almost certainly eliminate this crash entirely.
Bonus Check
You already confirmed your Fragments don’t have animated ViewGroups—great! Those can also cause similar inconsistencies with ViewPager2’s underlying RecyclerView, so avoiding them was a smart move.
内容的提问来源于stack exchange,提问作者grolschie

