瞭解捲動階段

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

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

捲動週期圖,顯示使用者捲動事件的捲動階段
圖 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 (反向)
指標向上移動 負面 負面 負面 N/A N/A 正面 負面
指標會向下移動 正面 正面 正面 N/A N/A 負面 正面
指標向移動 負面 負面 負面 正數 (由右至左語言為負數) 負數 (由右至左語言為正數) N/A N/A
指標會向移動 正面 正面 正面 負數 (由右至左語言為正數) 正數 (由右至左語言為負數) N/A N/A