การเลื่อนจะแบ่งออกเป็นหลายเฟส ระบบจะส่งเดลต้าอินพุตผ่าน ลำดับของเฟสเพื่อให้มั่นใจว่าแต่ละเฟสมีโอกาสที่จะใช้หรือตอบสนอง ต่อการเคลื่อนไหว
ตลอดวงจรนี้ ทั้งเดลต้าอินพุตที่ใช้ได้และเดลต้าอินพุตที่ใช้แล้วจะถูกส่งต่อในทุกขั้นตอน ซึ่งจะช่วยให้แต่ละเฟสมีบริบทที่สมบูรณ์ ซึ่งจำเป็นต่อการตอบสนอง ใช้ หรือฟังเหตุการณ์การเลื่อน
ดังที่แสดงในรูปที่ 1 กระบวนการเลื่อนจะเป็นไปตามลำดับต่อไปนี้
- การเลื่อนเกินขอบเขต: รับเดลต้าอินพุตเริ่มต้นก่อน ซึ่งจะทำให้การเลื่อนเกินขอบเขตมีโอกาสตอบสนองก่อน (เช่น โดยการผ่อนคลายเอฟเฟกต์การยืดที่ใช้งานอยู่)
- การเลื่อนก่อนการเลื่อนที่ซ้อนกัน: เปิดโอกาสให้ตอบสนองต่อเดลต้าอินพุตก่อนระยะเลื่อน ในระยะนี้ ระบบอาจใช้เดลต้าอินพุตบางส่วน หรืออาจเพียงแค่ตรวจสอบเพื่อทริกเกอร์การเปลี่ยนแปลง UI เช่น การยุบหรือขยายแถบแอป
- เปลี่ยนเดลต้าอินพุต: ปรับเครื่องหมายของเดลต้าอินพุตดิบตาม การวางแนวและทิศทางของเลย์เอาต์เพื่อให้มั่นใจว่าการเลื่อนจะเป็นไปอย่างเป็นธรรมชาติ ดูข้อมูลเพิ่มเติมได้ที่ส่วนเปลี่ยนเดลต้าอินพุต
- เลื่อน: เฟสนี้จะรับเดลต้าอินพุตที่ใช้ได้และยังไม่ได้ใช้ ซึ่งปรับให้ตรงกับการกำหนดค่าคอนเทนเนอร์เลื่อน โดยปกติแล้วจะใช้ เดลต้านี้เพื่ออัปเดตออฟเซ็ตการเลื่อนของตัวเอง
- เปลี่ยนกลับเป็นเดลต้าอินพุตดิบ: เปลี่ยนเดลต้าที่มีอยู่และใช้แล้วจากเฟสเลื่อนกลับเป็นเครื่องหมายเดลต้าอินพุตดิบเดิม
- การเลื่อนที่ซ้อนกันหลังการเลื่อน: เฟสนี้จะตอบสนองหลังจากเฟสการเลื่อนหลัก เสร็จสมบูรณ์ โดยจะรับเดลต้าที่อัปเดตใหม่ซึ่งพร้อมใช้งานและใช้ไปแล้ว โดยสามารถใช้ข้อมูลที่เหลืออยู่หรือใช้บริบทของข้อมูลที่เพิ่งใช้ไป
- การเลื่อนเกินขอบเขต: ระยะสุดท้ายนี้จะดูที่เดลต้าสุดท้ายที่ใช้ได้และใช้ไปแล้ว โดยปกติแล้ว ระบบจะใช้อินพุตที่เหลืออยู่ซึ่งพร้อมใช้งานและเข้าสู่ขั้นตอนนี้เพื่อขับเคลื่อนเอฟเฟกต์ขอบ เช่น การยืดหรือการเรืองแสง ซึ่งบ่งบอกว่าผู้ใช้มาถึงขอบเขตของพื้นที่ที่เลื่อนได้แล้ว
เปลี่ยนเดลต้าอินพุต
เดลต้าอินพุตของเคอร์เซอร์ต้องมีการปรับเครื่องหมายในระยะการเลื่อนเพื่อให้ตรงกับ สัญญาที่คาดไว้ ก่อนที่เดลต้าจะถึงเฟสเลื่อน ตัวปรับแต่งการเลื่อนจะปรับเดลต้าอินพุตตามบริบทการวางแนว ทิศทางเลย์เอาต์ และ RTL ซึ่งเป็นเพราะอินพุตดิบจะติดตามการเคลื่อนไหวของพิกเซลจริงของ เคอร์เซอร์บนหน้าจอ (เช่น การเลื่อนลงจะเพิ่มพิกัด Y ของหน้าจอ ทำให้เกิดเดลต้าที่เป็นบวก) อย่างไรก็ตาม หากต้องการให้ "การเลื่อนที่เป็นธรรมชาติ" ซึ่งเนื้อหาจะเลื่อนตามนิ้วของคุณ การลากลงหมายความว่าวิวพอร์ตต้องเลื่อนขึ้นเหนือเนื้อหา ซึ่งสอดคล้องกับออฟเซ็ตการเลื่อนที่เป็นลบ
ระบบจะไม่แปลงเดลต้าอินพุตจากแหล่งอินพุตอื่นๆ เช่น ล้อเมาส์หรือทัชแพด ตลอดทั้งระยะการเลื่อน
ตัวอย่าง: ตัวชี้เลื่อนไปทางขวาโดยใช้ Modifier.horizontalScroll()
หากต้องการดูว่าระบบใช้และแปลงเดลต้าอย่างไร ให้ดูรูปที่ 2 ซึ่งแสดงท่าทางสัมผัสที่เคอร์เซอร์เลื่อนไปทางขวา
- ก่อนเลื่อน: ท่าทางสัมผัสเริ่มต้นด้วยเดลต้าอินพุตดิบที่เป็นบวกของ 100
- การเลื่อนเกินจะสังเกตเห็นสิ่งนี้และใช้ 10 ทำให้เหลือ 90
- การเลื่อนที่ซ้อนกันก่อนการเลื่อนช่วยให้คอมโพเนนต์ระดับบนมีโอกาส ตอบสนองโดยใช้ 30 เดลต้ารวมที่เหลือคือ 60
- การเปลี่ยนรูปแบบ A: ก่อนเข้าสู่ระยะเลื่อน
horizontalScrollจะกลับค่าเดลต้ารวมดิบที่เป็นบวกที่เหลือ (60) เป็น เดลต้าที่เป็นลบ (-60) ซึ่งจะช่วยให้มั่นใจได้ว่าวิวพอร์ตจะเลื่อนไปทางซ้ายเพื่อให้ เนื้อหาดูเหมือนจะเลื่อนไปทางขวาตามนิ้วของผู้ใช้ - เลื่อน: คอมโพเนนต์เป้าหมายที่เลื่อนได้จะใช้ส่วนหนึ่งของเดลต้าที่แปลงแล้วนี้เพื่ออัปเดตออฟเซ็ตการเลื่อน ในตัวอย่างนี้ ระบบจะใช้ -30 ทำให้เหลือ -30 ที่ยังไม่ได้ใช้
- การเปลี่ยนรูปแบบ B: เดลต้าการเลื่อนที่ยังไม่ได้ใช้ (-30) จะแปลงกลับ เป็นเดลต้าดิบที่เป็นบวก (30) เพื่อให้ตรงกับสัญญาของการเลื่อนที่ซ้อนกันและการเลื่อนเกิน
- หลังการเลื่อน: ระบบจะส่งเดลต้ารูปแบบดิบที่เหลือกลับขึ้นไปในไปป์ไลน์
- การเลื่อนที่ซ้อนกันหลังการเลื่อนจะใช้ 10 ทำให้เหลือ 20
- เอฟเฟกต์การเลื่อนเกินใช้20 สุดท้ายเพื่อขับเคลื่อนเอฟเฟกต์ขอบภาพ เช่น การยืดหรือการเรืองแสง โดยจะแก้เดลต้าอินพุตเป็น 0
ข้อมูลอ้างอิงการแปลงเดลต้าอินพุตของเคอร์เซอร์
ตารางต่อไปนี้แสดงวิธีลงนามเดลต้าอินพุตในระยะต่างๆ และ ทิศทางสำหรับอินพุตของเคอร์เซอร์
| เดลต้าอินพุตดิบ | เอฟเฟกต์การเลื่อนเกิน | การเลื่อนที่ฝังไว้ | scrollableArea ที่มีการวางแนวนอน |
scrollableArea ที่มีการวางแนวนอน (กลับด้าน) |
scrollableArea ที่มีการวางแนวตั้ง |
scrollableArea ที่มีการวางแนวตั้ง (กลับด้าน) |
|
|---|---|---|---|---|---|---|---|
| Pointer เลื่อนขึ้น | ลบ | ลบ | ลบ | ไม่มี | ไม่มี | บวก | ลบ |
| เคอร์เซอร์เลื่อนลง | บวก | บวก | บวก | ไม่มี | ไม่มี | ลบ | บวก |
| เคอร์เซอร์เลื่อนไปทางซ้าย | ลบ | ลบ | ลบ | บวก (ลบสำหรับ RTL) | ลบ (บวกสำหรับ RTL) | ไม่มี | ไม่มี |
| เคอร์เซอร์เลื่อนไปทางขวา | บวก | บวก | บวก | ลบ (บวกสำหรับ RTL) | บวก (ลบสำหรับ RTL) | ไม่มี | ไม่มี |