Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

[Android] v9: a swipe reports idle when the finger lifts, before the page settles (settling is never sent)

Đang mở
#1,199 0 bình luận 1 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@mozzius đang làm issue này rồi.

Từ ngày 26/10/2026.

  • #1201 của @mozzius — đang mở

Đánh giá

Độ khó
4/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
android, react-native, typescript
Lĩnh vực
frontend, mobile-dev

Hướng nghiên cứu

Start with ComposePagerView and trace how DragInteraction.Stop and isScrollInProgress determine the scroll state. Reproduce a swipe while logging onPageScroll and onPageScrollStateChanged; done means a swipe reports dragging → settling → idle, with idle only after the page settles. An open pull request #1201 already addresses this issue.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Environment

Package Version
react-native-pager-view 9.0.9 (same code on main / 9.0.10)
react-native 0.88.0 (New Architecture, Hermes)
react 19.3.0
expo 58
androidx.compose.foundation 1.12.1 (the drag/fling code involved is the same in 1.7.x)
  • Platform: Android (iOS is not affected)
  • Device: Pixel 8 emulator, API 34, debugOptimized build

Description

On Android, a swipe reports onPageScrollStateChanged idle the moment the finger lifts, while the pager is still animating to the next page. onPageScroll keeps firing for another ~150–300 ms after idle, and settling is never reported for a swipe. A swipe goes dragging → idle instead of dragging → settling → idle.

Anything that treats idle as "the pager has stopped" acts too early. In our app (Bluesky), the feed tab bar follows onPageScroll until the pager is idle. With 9.x on Android it froze wherever the finger was lifted, and the underline ended up under the right tab while the tab strip didn't. Videos: https://github.com/bluesky-social/social-app/pull/12195

Programmatic setPage is fine: it reports settling → idle, with idle at the end.

Steps to reproduce

  1. Log onPageScroll and onPageScrollStateChanged on any pager.
  2. Swipe to the next page and lift the finger before the page has fully moved.

Expected: dragging, then settling when the finger lifts, then idle once onPageScroll reports offset 0 on the new page.

Actual: dragging, then idle when the finger lifts. onPageScroll keeps reporting fractional offsets after that, and no further state event arrives when the page actually stops.

From our logs (one swipe from page 0 to page 1, times in ms):

   0  scroll   position=0 offset=0.681   <- last event before the finger lifts
  65  state    idle
  67  selected position=1
  96  scroll   position=0 offset=0.694   <- the snap animation is still running
 115  scroll   position=0 offset=0.726
 ...  (21 more scroll events up to position=1 offset=0, no further state event)

Across dozens of swipes (slow, fast flicks, rapid consecutive swipes), settling never appeared once.

Cause

ComposePagerView picks the state when it sees DragInteraction.Stop:

is DragInteraction.Stop,
is DragInteraction.Cancel -> {
  if (pagerState.isScrollInProgress) {
    dispatchScrollState("settling")
  } else {
    dispatchScrollState("idle")
  }
}

But Compose ends the drag's scroll {} before the fling that snaps the pager starts its own. DragGestureNode returns from drag {}, emits DragInteraction.Stop, and only then does ScrollableNode.onDragStopped launch the fling in a new coroutine. When the collector handles the Stop, isScrollInProgress is false, so it always reports idle. When the fling ends, the isScrollInProgress collector sends idle again, but dispatchScrollState drops it as a duplicate.

That same collector can also see the gap between the drag and the fling. It then sends onPageScroll(settledPage, 0) and idle mid-gesture.

I have a fix with an example-app repro and an e2e test, and will open a PR.

Ngôn ngữ chính
TypeScript
Star
3.4k
Fork
488
Merge trung bình
2 ngày 7 giờ
Pull request đã merge (30 ngày)
29

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của callstack/react-native-pager-view

Tất cả issue của callstack/react-native-pager-view

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.