捲動分為多個階段。輸入增量會透過一連串階段分派,確保每個階段都有機會消耗或回應動作。
在這個週期中,系統會在每個步驟傳遞可用的輸入增量和已耗用的輸入增量。這會為每個階段提供完整的背景資訊,以便對捲動事件做出反應、使用或監聽。

如圖 1 所示,捲動程序會依下列順序執行:
- 過度捲動:首先接收初始輸入增量,讓過度捲動有機會先做出反應 (例如放寬作用中的延展效果)。
- 巢狀捲動預先捲動:在「捲動」階段之前,提供對輸入內容差異做出反應的機會。在這個階段,系統可能會消耗部分輸入增量,或只是監控輸入增量來觸發 UI 變更,例如收合或展開應用程式列。
- 轉換輸入內容差異:根據版面配置方向和方向調整原始輸入內容差異的符號,確保自然捲動行為。詳情請參閱「轉換輸入增量」一節。
- 捲動:這個階段會接收可用的未耗用輸入增量,並調整增量以符合捲動容器設定。通常會使用這個增量更新自己的捲動偏移。
- 還原為原始輸入增量:將「捲動」階段的可用和已用增量還原為原始輸入增量符號。
- 巢狀捲動後捲動:這個階段會在主要捲動階段完成後做出反應,並接收新近更新的可用和已耗用差異。它可以耗用任何剩餘的可用輸入內容,或使用剛耗用的內容。
- 過度捲動:最後一個階段會查看最終可用和消耗的增量。如果還有可用的輸入內容進入這個階段,通常會用於產生邊緣效果,例如延展或發光,表示使用者已到達可捲動區域的邊界。
轉換輸入內容差異
指標輸入增量需要在捲動階段進行符號調整,才能符合預期合約。在差異值達到「捲動」階段前,捲動修飾符會根據螢幕方向、版面配置方向和 RTL 環境調整輸入差異值。這是因為原始輸入會追蹤指標在螢幕上的實際像素移動 (例如,向下移動會增加螢幕的 Y 座標,產生正增量)。不過,如要實現「自然捲動」,也就是內容會隨著手指移動,向下拖曳時,視埠必須在內容上向上移動,這對應於負捲動偏移。
來自其他輸入來源 (例如滑鼠滾輪或觸控板) 的輸入增量,不會在捲動階段轉換。
範例:使用 Modifier.horizontalScroll() 將指標向右移動

如要瞭解如何取用及轉換增量,請參閱圖 2,其中會將指標向右移動的手勢對應至增量。
- 捲動前:手勢的開始是 100 的原始輸入增量。
- Overscroll 會觀察到這點並耗用 10,留下 90。
- 巢狀捲動前捲動可讓父項元件做出反應,並消耗 30。剩餘的原始差異為 60。
- 轉換 A:進入「捲動」階段前,
horizontalScroll會將剩餘的正向原始差異 (60) 反轉為負向差異 (-60)。這可確保視埠向左移動,讓內容隨著使用者手指往右移動。 - 捲動:目標可捲動元件會使用部分轉換後的差異,更新捲動偏移。在本例中,系統會耗用 -30,因此 -30 仍未耗用。
- 轉換 B:未使用的捲動增量 (-30) 會轉換回正向原始增量 (30),以符合巢狀捲動和過度捲動的合約。
- 捲動後:剩餘的原始差異會傳回管道。
- 巢狀捲動 (捲動後)會耗用 10,剩下 20。
- 過度捲動效果會使用最後 20 個單位來產生視覺邊緣效果,例如延展或發光,完全將輸入增量解析為 0。
指標輸入增量轉換參考資料
下表列出不同階段和指標輸入方向的輸入增量簽署方式。
| 原始輸入差異 | 過度捲動效果 | 巢狀捲動 | scrollableArea 橫向 |
scrollableArea 橫向 (反向) |
scrollableArea (直向) |
scrollableArea (反向) |
|
|---|---|---|---|---|---|---|---|
| 指標向上移動 | 負面 | 負面 | 負面 | 不適用 | 不適用 | 正面 | 負面 |
| 指標會向下移動 | 正面 | 正面 | 正面 | 不適用 | 不適用 | 負面 | 正面 |
| 指標向左移動 | 負面 | 負面 | 負面 | 正向 (由右至左語言為負向) | 負數 (由右至左語言為正數) | 不適用 | 不適用 |
| 指標向右移動 | 正面 | 正面 | 正面 | 負數 (由右至左語言為正數) | 正值 (由右至左語言為負值) | 不適用 | 不適用 |