เมื่อ Activity ควบคุมการจัดการ 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 นอกจากนี้ เลย์เอาต์ทั้งหมดที่ใช้ระยะขอบเหล่านี้จะ เคลื่อนไหวโดยอัตโนมัติด้วยเมื่อค่าระยะขอบเปลี่ยนแปลง
การจัดการระยะขอบเพื่อปรับเลย์เอาต์ที่ใช้ Composable ทำได้ 3 วิธีดังนี้
ตัวแก้ไขระยะห่างจากขอบ
Modifier.windowInsetsPadding(windowInsets: WindowInsets) จะใช้
ระยะขอบหน้าต่างที่ระบุเป็นระยะเว้น โดยจะทำงานเหมือนกับ Modifier.padding
เช่น Modifier.windowInsetsPadding(WindowInsets.safeDrawing) จะใช้
ระยะขอบของภาพวาดที่ปลอดภัยเป็นระยะห่างจากขอบในทั้ง 4 ด้าน
นอกจากนี้ ยังมีเมธอดยูทิลิตีในตัวหลายรายการสำหรับประเภท Inset ที่พบบ่อยที่สุดด้วย
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 แต่ไม่ได้ใช้
ระยะขอบภายในที่ใช้เป็นระยะขอบ ซึ่งจะเป็นประโยชน์เมื่อใช้ร่วมกับตัวแก้ไขขนาดขอบด้านใน เพื่อระบุให้องค์ประกอบที่อยู่ติดกันทราบว่ามีการใช้ขอบด้านในไปแล้วจำนวนหนึ่ง
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)) }
ในกรณีที่ต้องการขอบหน้าต่างดิบโดยไม่ต้องใช้ ให้ใช้ค่า WindowInsets โดยตรง หรือใช้ WindowInsets.asPaddingValues() เพื่อ
แสดงผล PaddingValues ของขอบที่การใช้งานไม่ส่งผลกระทบ
อย่างไรก็ตาม เนื่องจากข้อควรระวังต่อไปนี้ เราขอแนะนำให้ใช้ตัวแก้ไขระยะห่างจากขอบหน้าต่าง
และตัวแก้ไขขนาดขอบหน้าต่างทุกครั้งที่เป็นไปได้
ระยะขอบและเฟสของ Jetpack Compose
Compose ใช้ AndroidX Core API พื้นฐานเพื่ออัปเดตและเคลื่อนไหว Inset ซึ่งใช้ API ของแพลตฟอร์มพื้นฐานที่จัดการ Inset เนื่องจากลักษณะการทำงานของแพลตฟอร์มดังกล่าว ระยะขอบจึงมีความสัมพันธ์พิเศษกับเฟสของ Jetpack Compose
ค่าของระยะขอบจะได้รับการอัปเดตหลังจากเฟสการคอมโพสิต แต่ก่อนเฟสเลย์เอาต์ ซึ่งหมายความว่าการอ่านค่าของ Insets ใน Composition โดยทั่วไปจะใช้ค่าของ Insets ที่ช้าไป 1 เฟรม ตัวแก้ไขในตัว ที่อธิบายไว้ในหน้านี้สร้างขึ้นเพื่อชะลอการใช้ค่าของ ระยะขอบจนกว่าจะถึงระยะเลย์เอาต์ ซึ่งจะช่วยให้มั่นใจได้ว่าระบบจะใช้ค่าระยะขอบในเฟรมเดียวกันกับที่อัปเดต