เมื่อกิจกรรมของคุณควบคุมการจัดการ Inset ทั้งหมดแล้ว คุณจะใช้ API ของ Compose เพื่อยืนยันว่าเนื้อหาไม่ถูกบดบังและองค์ประกอบที่โต้ตอบได้ไม่ ทับซ้อนกับ UI ของระบบ นอกจากนี้ API เหล่านี้ยังซิงค์เลย์เอาต์ของแอปกับการเปลี่ยนแปลงระยะขอบ ด้วย
จัดการระยะขอบโดยใช้ตัวปรับขนาดหรือระยะเว้น
ตัวอย่างเช่น นี่คือวิธีพื้นฐานที่สุดในการใช้ระยะขอบกับเนื้อหา ของทั้งแอป
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
ข้อมูลโค้ดนี้ใช้ระยะขอบหน้าต่าง safeDrawing เป็นระยะห่างจากขอบรอบเนื้อหาทั้งหมดของแอป แม้ว่าวิธีนี้จะช่วยให้มั่นใจได้ว่าองค์ประกอบที่โต้ตอบได้จะไม่ทับซ้อนกับ UI ของระบบ แต่ก็หมายความว่าไม่มีส่วนใดของแอปที่จะวาดอยู่ด้านหลัง UI ของระบบเพื่อให้ได้เอฟเฟกต์แบบขอบจรดขอบ หากต้องการใช้ประโยชน์จากทั้งหน้าต่างอย่างเต็มที่ คุณต้องปรับแต่งตำแหน่งที่ใช้ระยะขอบในบนหน้าจอแต่ละหน้าจอ
หรือคอมโพเนนต์แต่ละคอมโพเนนต์
ประเภทการแทรกทั้งหมดนี้จะเคลื่อนไหวโดยอัตโนมัติด้วยภาพเคลื่อนไหวของ IME ที่พอร์ตกลับไปยัง API 21 นอกจากนี้ เลย์เอาต์ทั้งหมดที่ใช้ระยะขอบเหล่านี้จะ เคลื่อนไหวโดยอัตโนมัติด้วยเมื่อค่าระยะขอบเปลี่ยนแปลง
การจัดการระยะขอบเพื่อปรับเลย์เอาต์ที่ใช้ Compose ทำได้ 3 วิธีดังนี้
ตัวแก้ไขระยะห่างจากขอบ
Modifier.windowInsetsPadding(windowInsets: WindowInsets) จะใช้
ระยะขอบหน้าต่างที่ระบุเป็นระยะห่างภายใน ซึ่งทำงานเหมือนกับ Modifier.padding
เช่น Modifier.windowInsetsPadding(WindowInsets.safeDrawing) จะใช้
ระยะขอบที่ปลอดภัยในการวาดเป็นระยะห่างจากขอบทั้ง 4 ด้าน
นอกจากนี้ ยังมีเมธอดยูทิลิตีในตัวหลายรายการสำหรับประเภทการแทรกที่พบบ่อยที่สุด
Modifier.safeDrawingPadding() เป็นหนึ่งในวิธีดังกล่าว ซึ่งเทียบเท่ากับ
Modifier.windowInsetsPadding(WindowInsets.safeDrawing) โดยมีตัวแก้ไขที่คล้ายกัน
สำหรับประเภทการแทรกอื่นๆ
ตัวแก้ไขขนาดภาพซ้อน
ตัวแก้ไขต่อไปนี้จะใช้จำนวนการแทรกหน้าต่างโดยการตั้งค่าขนาดของ คอมโพเนนต์ให้เป็นขนาดของการแทรก
ใช้ด้านเริ่มต้นของ WindowInsets เป็นความกว้าง (เช่น |
|
ใช้ด้านสิ้นสุดของ WindowInsets เป็นความกว้าง (เช่น |
|
ใช้ด้านบนของ WindowInsets เป็นความสูง (เช่น |
|
|
ใช้ด้านล่างของ WindowInsets เป็นความสูง (เช่น |
ตัวแก้ไขเหล่านี้มีประโยชน์อย่างยิ่งสำหรับการกำหนดขนาด Spacer ที่ใช้พื้นที่ของระยะขอบ
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
การรับชมแบบภาพซ้อนภาพ
ตัวแก้ไขระยะขอบด้านใน (windowInsetsPadding และตัวช่วย เช่น safeDrawingPadding) จะใช้ส่วนของระยะขอบด้านในที่
ใช้เป็นระยะขอบโดยอัตโนมัติ ในขณะที่เจาะลึกเข้าไปในแผนผังการจัดองค์ประกอบ ตัวแก้ไขระยะขอบภายในที่ซ้อนกัน
และตัวแก้ไขขนาดระยะขอบภายในจะทราบว่าตัวแก้ไขระยะขอบภายในด้านนอกได้ใช้ระยะขอบภายในบางส่วนไปแล้ว และหลีกเลี่ยง
การใช้ระยะขอบภายในส่วนเดียวกันมากกว่า 1 ครั้ง ซึ่งจะทำให้มีพื้นที่ว่างมากเกินไป
ตัวแก้ไขขนาดระยะขอบยังหลีกเลี่ยงการใช้ระยะขอบส่วนเดียวกันมากกว่า 1 ครั้ง หากมีการใช้ระยะขอบไปแล้ว อย่างไรก็ตาม เนื่องจากมีการเปลี่ยนขนาดโดยตรง จึงไม่ได้ใช้ระยะขอบเอง
ด้วยเหตุนี้ ตัวแก้ไขระยะขอบที่ซ้อนกันจึงเปลี่ยนจำนวน ระยะขอบที่ใช้กับแต่ละ Composable โดยอัตโนมัติ
ดูLazyColumnตัวอย่างเดียวกันกับก่อนหน้านี้ LazyColumnจะได้รับการปรับขนาดโดยตัวแก้ไข imePadding ภายใน LazyColumn รายการสุดท้ายจะมีขนาดเท่ากับความสูงของด้านล่างของแถบระบบ ดังนี้
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
เมื่อปิด IME ตัวแก้ไข imePadding() จะไม่มีการใช้ระยะเว้น เนื่องจาก
IME ไม่มีส่วนสูง เนื่องจากตัวแก้ไข imePadding() ไม่ได้ใช้ระยะห่างจากขอบ
จึงไม่มีการใช้ระยะขอบด้านใน และความสูงของ Spacer จะเป็นขนาดของ
ด้านล่างของแถบระบบ
เมื่อ IME เปิดขึ้น ขอบแทรกของ IME จะเคลื่อนไหวให้มีขนาดเท่ากับ IME และimePadding()ตัวแก้ไขจะเริ่มใช้การเว้นวรรคด้านล่างเพื่อปรับขนาดLazyColumnเมื่อ IME เปิดขึ้น เมื่อตัวแก้ไข imePadding() เริ่มใช้
ระยะห่างจากด้านล่าง ก็จะเริ่มใช้ระยะห่างจากขอบในจำนวนดังกล่าวด้วย ดังนั้น
ความสูงของ Spacer จะเริ่มลดลง เนื่องจากตัวแก้ไข imePadding() ได้ใช้การเว้นวรรคสำหรับแถบระบบ
แล้ว เมื่อ
imePadding() ตัวแก้ไขใช้ระยะห่างจากขอบด้านล่างที่มีขนาดใหญ่กว่า
แถบระบบ ความสูงของ Spacer จะเป็น 0
เมื่อ IME ปิดลง การเปลี่ยนแปลงจะเกิดขึ้นในทางกลับกัน โดยSpacerจะเริ่มขยายจากความสูงเป็น 0 เมื่อ imePadding() ใช้ความสูงน้อยกว่าด้านล่างของแถบระบบ จนกระทั่งในที่สุด Spacer จะมีความสูงเท่ากับด้านล่างของแถบระบบเมื่อ IME เคลื่อนไหวออกไปจนหมด
TextFieldลักษณะการทำงานนี้เกิดขึ้นผ่านการสื่อสารระหว่างตัวแก้ไขทั้งหมด
windowInsetsPadding และสามารถปรับเปลี่ยนได้ด้วยวิธีอื่นๆ อีก 2-3 วิธี
Modifier.consumeWindowInsets(insets: WindowInsets) ยังใช้ระยะขอบภายใน
ในลักษณะเดียวกับ Modifier.windowInsetsPadding แต่ไม่ได้ใช้
ระยะขอบภายในที่ใช้เป็นระยะเว้น ซึ่งจะเป็นประโยชน์เมื่อใช้ร่วมกับตัวแก้ไข inset
size เพื่อระบุให้องค์ประกอบที่อยู่ติดกันทราบว่ามีการใช้ระยะขอบภายในไปแล้ว
จำนวนหนึ่ง
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) ทำงานคล้ายกับเวอร์ชันที่มีอาร์กิวเมนต์ WindowInsets มาก แต่จะใช้ PaddingValues ที่กำหนดเอง ซึ่งมีประโยชน์ในการแจ้งให้บุตรหลานทราบเมื่อมีการเว้นที่ว่างหรือการเว้นวรรคโดยกลไกอื่นที่ไม่ใช่ตัวแก้ไขการเว้นที่ว่างภายใน เช่น Modifier.padding หรือตัวเว้นวรรคที่มีความสูงคงที่
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
ในกรณีที่ต้องการใช้ Window Insets ดิบโดยไม่ต้องใช้ ให้ใช้ค่า WindowInsets โดยตรง หรือใช้ WindowInsets.asPaddingValues() เพื่อ
แสดงผล PaddingValues ของ Insets ที่ไม่ได้รับผลกระทบจากการใช้
อย่างไรก็ตาม เนื่องจากข้อควรระวังต่อไปนี้ เราขอแนะนำให้ใช้ตัวแก้ไขระยะขอบของ Window Insets
และตัวแก้ไขขนาดของ Window Insets ทุกครั้งที่เป็นไปได้
ระยะขอบและระยะของ Jetpack Compose
Compose ใช้ Core API ของ AndroidX ที่อยู่เบื้องหลังเพื่ออัปเดตและเคลื่อนไหว Inset ซึ่งใช้ API ของแพลตฟอร์มที่อยู่เบื้องหลังเพื่อจัดการ Inset เนื่องจากลักษณะการทำงานของแพลตฟอร์มดังกล่าว ขอบจึงมีความสัมพันธ์พิเศษกับเฟสของ Jetpack Compose
ค่าของ Insets จะได้รับการอัปเดตหลังจากเฟสการคอมโพสิต แต่ก่อนเฟสเลย์เอาต์ ซึ่งหมายความว่าการอ่านค่าของ Insets ใน Composition โดยทั่วไปจะใช้ค่าของ Insets ที่ช้าไป 1 เฟรม ตัวแก้ไขในตัว ที่อธิบายไว้ในหน้านี้สร้างขึ้นเพื่อหน่วงเวลาการใช้ค่าของ ระยะขอบจนกว่าจะถึงเฟสเลย์เอาต์ ซึ่งจะช่วยให้มั่นใจได้ว่าระบบจะใช้ค่าระยะขอบใน เฟรมเดียวกันกับที่อัปเดต