瞭解捲動階段

捲動分為多個階段。輸入增量會透過一連串階段分派,確保每個階段都有機會消耗或回應動作。

在這個週期中,系統會在每個步驟傳遞可用的輸入增量和已耗用的輸入增量。這會為每個階段提供完整的背景資訊,以便對捲動事件做出反應、使用或監聽。

捲動週期圖,顯示使用者捲動事件的捲動階段
圖 1. 捲動週期圖,顯示使用者捲動事件的捲動階段。

如圖 1 所示,捲動程序會依下列順序執行:

  1. 過度捲動:首先接收初始輸入增量,讓過度捲動有機會先做出反應 (例如放寬作用中的延展效果)。
  2. 巢狀捲動預先捲動:在「捲動」階段之前,提供對輸入內容差異做出反應的機會。在這個階段,系統可能會消耗部分輸入增量,或只是監控輸入增量來觸發 UI 變更,例如收合或展開應用程式列。
  3. 轉換輸入內容差異:根據版面配置方向和方向調整原始輸入內容差異的符號,確保自然捲動行為。詳情請參閱「轉換輸入增量」一節。
  4. 捲動:這個階段會接收可用的未耗用輸入增量,並調整增量以符合捲動容器設定。通常會使用這個增量更新自己的捲動偏移。
  5. 還原為原始輸入增量:將「捲動」階段的可用和已用增量還原為原始輸入增量符號。
  6. 巢狀捲動後捲動:這個階段會在主要捲動階段完成後做出反應,並接收新近更新的可用和已耗用差異。它可以耗用任何剩餘的可用輸入內容,或使用剛耗用的內容。
  7. 過度捲動:最後一個階段會查看最終可用和消耗的增量。如果還有可用的輸入內容進入這個階段,通常會用於產生邊緣效果,例如延展或發光,表示使用者已到達可捲動區域的邊界。

轉換輸入內容差異

指標輸入增量需要在捲動階段進行符號調整,才能符合預期合約。在差異值達到「捲動」階段前,捲動修飾符會根據螢幕方向、版面配置方向和 RTL 環境調整輸入差異值。這是因為原始輸入會追蹤指標在螢幕上的實際像素移動 (例如,向下移動會增加螢幕的 Y 座標,產生正增量)。不過,如要實現「自然捲動」,也就是內容會隨著手指移動,向下拖曳時,視埠必須在內容上向上移動,這對應於負捲動偏移。

來自其他輸入來源 (例如滑鼠滾輪或觸控板) 的輸入增量,不會在捲動階段轉換。

範例:使用 Modifier.horizontalScroll() 將指標向右移動

圖表:指標向右移動的手勢
圖 2. 圖表:指標向右移動的手勢。

如要瞭解如何取用及轉換增量,請參閱圖 2,其中會將指標向移動的手勢對應至增量。

  • 捲動前:手勢的開始是 100 的原始輸入增量。
    • Overscroll 會觀察到這點並耗用 10,留下 90
    • 巢狀捲動前捲動可讓父項元件做出反應,並消耗 30。剩餘的原始差異為 60
  • 轉換 A:進入「捲動」階段前,horizontalScroll 會將剩餘的正向原始差異 (60) 反轉為負向差異 (-60)。這可確保視埠向左移動,讓內容隨著使用者手指往右移動。
  • 捲動:目標可捲動元件會使用部分轉換後的差異,更新捲動偏移。在本例中,系統會耗用 -30,因此 -30 仍未耗用。
  • 轉換 B:未使用的捲動增量 (-30) 會轉換回正向原始增量 (30),以符合巢狀捲動和過度捲動的合約。
  • 捲動後:剩餘的原始差異會傳回管道。
    • 巢狀捲動 (捲動後)會耗用 10,剩下 20
    • 過度捲動效果會使用最後 20 個單位來產生視覺邊緣效果,例如延展或發光,完全將輸入增量解析為 0

指標輸入增量轉換參考資料

下表列出不同階段和指標輸入方向的輸入增量簽署方式。

原始輸入差異 過度捲動效果 巢狀捲動 scrollableArea 橫向 scrollableArea 橫向 (反向) scrollableArea (直向) scrollableArea (反向)
指標向上移動 負面 負面 負面 不適用 不適用 正面 負面
指標會向下移動 正面 正面 正面 不適用 不適用 負面 正面
指標向移動 負面 負面 負面 正向 (由右至左語言為負向) 負數 (由右至左語言為正數) 不適用 不適用
指標向移動 正面 正面 正面 負數 (由右至左語言為正數) 正值 (由右至左語言為負值) 不適用 不適用