คุณต้องมีข้อมูลหลายประเภท เช่น ความสามารถของอุปกรณ์ และสถานะของแอป เพื่ออัปเดตเลย์เอาต์ของแอป ความกว้างและความสูงของหน้าต่างเป็นข้อมูลที่ใช้กันโดยทั่วไปมากที่สุด นอกจากนี้ คุณยังดูข้อมูลต่อไปนี้ได้ด้วย
- ท่าทางของหน้าต่าง
- ความแม่นยำของอุปกรณ์ชี้ตำแหน่ง
- ประเภทของแป้นพิมพ์
- อุปกรณ์รองรับกล้องและไมโครโฟนหรือไม่
- ระยะห่างระหว่างผู้ใช้กับจอแสดงผลของอุปกรณ์
เนื่องจากข้อมูลจะอัปเดตแบบไดนามิก
คุณจึงต้องตรวจสอบและทริกเกอร์การจัดองค์ประกอบใหม่เมื่อมีการอัปเดต
ฟังก์ชัน 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 จะประเมินqueryแลมบ์ดา ด้วยออบเจ็กต์ UiMediaScope ที่อัปเดตแล้ว และแสดงผลค่าบูลีน
ตัวอย่างเช่น ข้อมูลโค้ดต่อไปนี้จะเลือกระหว่าง TabletopLayout
กับ FlatLayout โดยอิงตามค่าพารามิเตอร์ windowPosture
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
ตัดสินใจตามขนาดหน้าต่าง
คลาสขนาดหน้าต่างคือชุดเบรกพอยต์ของวิวพอร์ตที่กำหนดไว้ ซึ่งช่วยคุณออกแบบ พัฒนา และทดสอบเลย์เอาต์ที่ปรับเปลี่ยนตามพื้นที่โฆษณา
คุณสามารถเปรียบเทียบพารามิเตอร์ 2 รายการที่แสดงขนาดหน้าต่างปัจจุบัน กับเกณฑ์ที่กำหนดไว้ในคลาสขนาดหน้าต่าง
ตัวอย่างต่อไปนี้จะเปลี่ยนจำนวนบานหน้าต่างตามความกว้างของหน้าต่าง
คลาส WindowSizeClass มีค่าคงที่สำหรับเกณฑ์
ของคลาสขนาดหน้าต่าง (รูปที่ 1)
ฟังก์ชัน derivedMediaQuery จะประเมินแลมบ์ดา 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 อุปกรณ์ที่มีความแม่นยำ Fine จะเป็นค่าของพารามิเตอร์ pointerPrecision
ตัวอย่างต่อไปนี้แสดงปุ่มที่ใหญ่ขึ้น เมื่อผู้ใช้ใช้อุปกรณ์ชี้ที่มีความแม่นยำต่ำ
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 พารามิเตอร์ TabletopLayout ควรเป็น
UiMediaScope.Posture.TabletopwindowPosture
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
ฟังก์ชัน mediaQuery และ derivedMediaQuery จะประเมิน
แลมบ์ดา query ที่ระบุภายในออบเจ็กต์ UiMediaScope
ซึ่งระบุเป็น LocalUiMediaScope.current
คุณลบล้างได้โดยทำตามขั้นตอนต่อไปนี้
- เปิดใช้ฟังก์ชัน
mediaQuery - กำหนดออบเจ็กต์ที่กำหนดเองซึ่งใช้
UiMediaScopeอินเทอร์เฟซ - ตั้งค่าออบเจ็กต์ที่กำหนดเองเป็น
LocalUiMediaScopeด้วยฟังก์ชันCompositionLocalProvider - เรียกใช้ Composable เพื่อแสดงตัวอย่างใน 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() } } }