คุณต้องมีข้อมูลหลายประเภท เช่น ความสามารถของอุปกรณ์และสถานะของแอป เพื่ออัปเดตเลย์เอาต์ของแอป ความกว้างและความสูงของหน้าต่างเป็นข้อมูลที่ใช้บ่อยที่สุด นอกจากนี้ คุณยังดูข้อมูลต่อไปนี้ได้
- ท่าทางของหน้าต่าง
- ความแม่นยำของอุปกรณ์ชี้
- ประเภทของแป้นพิมพ์
- อุปกรณ์รองรับกล้องและไมโครโฟนหรือไม่
- ระยะห่างระหว่างผู้ใช้กับจอแสดงผลของอุปกรณ์
เนื่องจากระบบจะอัปเดตข้อมูลแบบไดนามิก คุณจึงต้องตรวจสอบข้อมูลและทริกเกอร์การประกอบใหม่เมื่อมีการอัปเดต
ฟังก์ชัน mediaQuery จะสรุปรายละเอียดของการดึงข้อมูล
และช่วยให้คุณมุ่งเน้นไปที่การกำหนดเงื่อนไขเพื่อทริกเกอร์การอัปเดตเลย์เอาต์
ตัวอย่างต่อไปนี้จะเปลี่ยนเลย์เอาต์เป็น TabletopLayout เมื่อท่าทางของอุปกรณ์พับได้เป็นแบบวางบนโต๊ะ
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
เปิดใช้ฟังก์ชัน mediaQuery
หากต้องการเปิดใช้ฟังก์ชัน mediaQuery
ให้ตั้งค่าแอตทริบิวต์ isMediaQueryIntegrationEnabled ของ
ออบเจ็กต์ ComposeUiFlags เป็น true
class MyApplication : Application() { override fun onCreate() { ComposeUiFlags.isMediaQueryIntegrationEnabled = true super.onCreate() } }
กำหนดเงื่อนไขด้วยพารามิเตอร์
คุณกำหนดเงื่อนไขเป็น Lambda
ที่ประเมินภายใน UiMediaScope ได้
ฟังก์ชัน mediaQuery จะประเมินเงื่อนไขตามสถานะปัจจุบันและความสามารถของอุปกรณ์
ฟังก์ชันจะแสดงผลค่าบูลีน คุณจึงกำหนดเลย์เอาต์ด้วยกิ่งก้านแบบมีเงื่อนไข เช่น นิพจน์ if ได้
ตารางที่ 1 อธิบายพารามิเตอร์ที่ใช้ได้ใน UiMediaScope
| พารามิเตอร์ | ประเภทค่า | คำอธิบาย |
|---|---|---|
windowWidth |
Dp |
ความกว้างปัจจุบันของหน้าต่างในหน่วย dp |
windowHeight |
Dp |
ความสูงปัจจุบันของหน้าต่างในหน่วย dp |
windowPosture |
UiMediaScope.Posture |
ท่าทางปัจจุบันของหน้าต่างแอปพลิเคชัน |
pointerPrecision |
UiMediaScope.PointerPrecision |
ความแม่นยำสูงสุดของอุปกรณ์ชี้ที่ใช้ได้ |
keyboardKind |
UiMediaScope.KeyboardKind |
ประเภทของแป้นพิมพ์ที่ใช้ได้หรือเชื่อมต่ออยู่ |
hasCamera |
Boolean |
อุปกรณ์รองรับกล้องหรือไม่ |
hasMicrophone |
Boolean |
อุปกรณ์รองรับไมโครโฟนหรือไม่ |
viewingDistance |
UiMediaScope.ViewingDistance |
ระยะห่างโดยทั่วไประหว่างผู้ใช้กับหน้าจออุปกรณ์ |
ออบเจ็กต์ UiMediaScope จะแก้ค่าพารามิเตอร์
ฟังก์ชัน mediaQuery ใช้ LocalUiMediaScope.current
เพื่อเข้าถึงออบเจ็กต์ UiMediaScope
ซึ่งแสดงถึงความสามารถและบริบทปัจจุบันของอุปกรณ์
ระบบจะอัปเดตออบเจ็กต์นี้แบบไดนามิกเมื่อมีการเปลี่ยนแปลง เช่น เมื่อผู้ใช้เปลี่ยนท่าทางของอุปกรณ์
จากนั้นฟังก์ชัน mediaQuery จะประเมิน Lambda query ด้วยออบเจ็กต์ UiMediaScope ที่อัปเดตแล้วและแสดงผลค่าบูลีน
ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้จะเลือกระหว่าง TabletopLayout กับ FlatLayout ตามค่าพารามิเตอร์ windowPosture
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
ตัดสินใจตามขนาดหน้าต่าง
คลาสขนาดหน้าต่างคือชุดเบรกพอยต์ของวิวพอร์ตที่กำหนดไว้ล่วงหน้า
ซึ่งช่วยคุณออกแบบ พัฒนา และทดสอบเลย์เอาต์แบบปรับเปลี่ยนได้
คุณสามารถเปรียบเทียบพารามิเตอร์ 2 รายการที่แสดงถึงขนาดหน้าต่างปัจจุบันกับเกณฑ์ที่กำหนดไว้ในคลาสขนาดหน้าต่าง
ตัวอย่างต่อไปนี้จะเปลี่ยนจำนวนบานหน้าต่างตามความกว้างของหน้าต่าง
WindowSizeClass คลาสมีค่าคงที่สำหรับเกณฑ์
ของคลาสขนาดหน้าต่าง (รูปที่ 1)
ฟังก์ชัน derivedMediaQuery จะประเมิน Lambda query
และรวมผลลัพธ์ไว้ใน derivedStateOf
เนื่องจาก windowWidth และ windowHeight อาจอัปเดตบ่อยครั้ง ให้เรียกใช้ฟังก์ชัน derivedMediaQuery แทนฟังก์ชัน mediaQuery เมื่ออ้างอิงพารามิเตอร์เหล่านั้นใน Lambda query
val narrowerThanMedium by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND.dp } val narrowerThanExpanded by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND.dp } when { narrowerThanMedium -> SinglePaneLayout() narrowerThanExpanded -> TwoPaneLayout() else -> ThreePaneLayout() }
อัปเดตเลย์เอาต์ตามท่าทางของหน้าต่าง
พารามิเตอร์ windowPosture จะอธิบายท่าทางปัจจุบันของหน้าต่างเป็นออบเจ็กต์ UiMediaScope.Posture
คุณสามารถตรวจสอบ ท่าทาง ปัจจุบันได้โดยการเปรียบเทียบพารามิเตอร์
กับค่าที่กำหนดไว้ในคลาส UiMediaScope.Posture
ตัวอย่างต่อไปนี้จะเปลี่ยนเลย์เอาต์ตามท่าทางของหน้าต่าง
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
ตรวจสอบความแม่นยำของอุปกรณ์ชี้ที่ใช้ได้
อุปกรณ์ชี้ที่มีความแม่นยำสูงจะช่วยให้ผู้ใช้ชี้องค์ประกอบ UI ได้อย่างแม่นยำ ความแม่นยำของอุปกรณ์ชี้ขึ้นอยู่กับประเภทของอุปกรณ์
พารามิเตอร์ pointerPrecision จะอธิบายความแม่นยำของอุปกรณ์ชี้ที่ใช้ได้ เช่น เมาส์และหน้าจอสัมผัส
คลาส UiMediaScope.PointerPrecision มีค่า 4 ค่า ได้แก่
Fine, Coarse, Blunt และ None
None หมายความว่าไม่มีอุปกรณ์ชี้ที่ใช้ได้
ความแม่นยำจะเรียงจากสูงสุดไปต่ำสุดตามลำดับนี้ Fine, Coarse และ Blunt
หากมีอุปกรณ์ชี้หลายรายการที่ใช้ได้และมีความแม่นยำแตกต่างกัน ระบบจะแก้พารามิเตอร์ด้วยความแม่นยำสูงสุด
ตัวอย่างเช่น หากมีอุปกรณ์ชี้ 2 รายการ ได้แก่ อุปกรณ์ที่มีความแม่นยำ Fine และอุปกรณ์ที่มีความแม่นยำ Blunt ค่าของพารามิเตอร์ pointerPrecision จะเป็น Fine
ตัวอย่างต่อไปนี้แสดงปุ่มที่ใหญ่ขึ้นเมื่อผู้ใช้ใช้อุปกรณ์ชี้ที่มีความแม่นยำต่ำ
if (mediaQuery { pointerPrecision == UiMediaScope.PointerPrecision.Blunt }) { LargeSizeButton() } else { NormalSizeButton() }
ตรวจสอบประเภทแป้นพิมพ์ที่ใช้ได้
พารามิเตอร์ keyboardKind แสดงถึงประเภทของแป้นพิมพ์ที่ใช้ได้:
Physical, Virtual และ None
หากแป้นพิมพ์บนหน้าจอแสดงอยู่และมีแป้นพิมพ์ฮาร์ดแวร์ที่ใช้ได้ในเวลาเดียวกัน ระบบจะแก้พารามิเตอร์เป็น Physical
หากตรวจไม่พบทั้ง 2 อย่าง ค่าของพารามิเตอร์จะเป็น None
ตัวอย่างต่อไปนี้แสดงข้อความแนะนำให้ผู้ใช้เชื่อมต่อแป้นพิมพ์เมื่อตรวจไม่พบแป้นพิมพ์
if (mediaQuery { keyboardKind == UiMediaScope.KeyboardKind.None }) { SuggestKeyboardConnect() }
ตรวจสอบว่าอุปกรณ์รองรับกล้องและไมโครโฟนหรือไม่
อุปกรณ์บางรุ่นไม่รองรับกล้องหรือไมโครโฟน
คุณสามารถตรวจสอบว่าอุปกรณ์รองรับกล้องและไมโครโฟนหรือไม่ด้วยพารามิเตอร์ hasCamera และพารามิเตอร์ hasMicrophone
ตัวอย่างต่อไปนี้แสดงปุ่มที่จะใช้กับกล้องและไมโครโฟนเมื่ออุปกรณ์รองรับ
Row { OutlinedTextField(state = rememberTextFieldState()) // Show the MicButton when the device supports a microphone. if (mediaQuery { hasMicrophone }) { MicButton() } // Show the CameraButton when the device supports a camera. if (mediaQuery { hasCamera }) { CameraButton() } }
ปรับ UI ตามระยะห่างในการรับชมโดยประมาณ
ระยะห่างในการรับชมเป็นปัจจัยที่ช่วยกำหนดเลย์เอาต์
หากผู้ใช้ใช้แอปจากระยะไกล ผู้ใช้จะคาดหวังให้ข้อความและองค์ประกอบ UI มีขนาดใหญ่ขึ้น
พารามิเตอร์ viewingDistance จะประมาณระยะห่างในการรับชมตามประเภทของอุปกรณ์และบริบทการใช้งานโดยทั่วไป
คลาส UiMediaScope.ViewingDistance มีค่า 3 ค่า ได้แก่
Near, Medium และ Far
Near หมายความว่าหน้าจออยู่ในระยะใกล้ และ Far หมายความว่ามีการดูอุปกรณ์จากระยะไกล
ตัวอย่างต่อไปนี้จะเพิ่มขนาดแบบอักษรเมื่อระยะห่างในการรับชมเป็น Far หรือ Medium
val fontSize = when { mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Far } -> 20.sp mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Medium } -> 18.sp else -> 16.sp }
แสดงตัวอย่างคอมโพเนนต์ UI
คุณสามารถเรียกใช้ฟังก์ชัน mediaQuery และ derivedMediaQuery ในฟังก์ชันที่ใช้ร่วมกันได้เพื่อแสดงตัวอย่างคอมโพเนนต์ UI
ข้อมูลโค้ดต่อไปนี้จะเลือกระหว่าง TabletopLayout กับ FlatLayout ตามค่าพารามิเตอร์ windowPosture
หากต้องการแสดงตัวอย่าง TabletopLayout พารามิเตอร์ windowPosture ควรเป็น
UiMediaScope.Posture.Tabletop
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
ฟังก์ชัน mediaQuery และ derivedMediaQuery จะประเมิน
Lambda query ที่กำหนดไว้ภายในออบเจ็กต์ UiMediaScope
ซึ่งมีให้เป็น LocalUiMediaScope.current
คุณสามารถเขียนทับได้โดยทำตามขั้นตอนต่อไปนี้
- เปิดใช้ฟังก์ชัน
mediaQuery - กำหนดออบเจ็กต์ที่กำหนดเองซึ่งใช้ได้กับอินเทอร์เฟซ
UiMediaScope - ตั้งค่าออบเจ็กต์ที่กำหนดเองเป็น
LocalUiMediaScopeด้วยฟังก์ชันCompositionLocalProvider - เรียกใช้ฟังก์ชันที่ใช้ร่วมกันได้เพื่อแสดงตัวอย่างใน Lambda เนื้อหาของฟังก์ชัน
CompositionLocalProvider
คุณสามารถแสดงตัวอย่าง TabletopLayout ได้ด้วยตัวอย่างต่อไปนี้
@Preview @Composable fun PreviewLayoutForTabletop() { // Step 1: Enable the mediaQuery function ComposeUiFlags.isMediaQueryIntegrationEnabled = true val currentUiMediaScope = LocalUiMediaScope.current // Step 2: Define a custom object implementing the UiMediaScope interface. // The object overrides the windowPosture parameter. // The resolution of the remaining parameters is deferred to the currentUiMediaScope object. val uiMediaScope = remember(currentUiMediaScope) { object : UiMediaScope by currentUiMediaScope { override val windowPosture: UiMediaScope.Posture = UiMediaScope.Posture.Tabletop } } // Step 3: Set the object to the LocalUiMediaScope. CompositionLocalProvider(LocalUiMediaScope provides uiMediaScope) { // Step 4: Call the composable to preview. when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() } } }