หลักเกณฑ์การออกแบบแอป TV กำหนดตัวแปรของการ์ด ที่เรียกว่าการ์ดคลาสสิกแบบกว้าง ซึ่งจะแสดงรูปภาพและบล็อกเนื้อหาคำอธิบายเคียงข้างกัน
เมื่อสร้างเลย์เอาต์ 2 มิติที่ซับซ้อนสำหรับหน้าจอทีวี การใช้การจัดตำแหน่งแบบดั้งเดิมตามพิกัดหรือคอนเทนเนอร์ Row และ Column ที่ซ้อนกันหลายชั้นอาจทำให้โค้ดอ่าน แก้ไข และปรับโครงสร้างได้ยาก
การ์ดคลาสสิกแบบกว้างเป็นกรณีการใช้งานที่เหมาะสำหรับ Jetpack Compose Grid API ซึ่งช่วยให้คุณจัดโครงสร้างองค์ประกอบเคียงข้างกันได้อย่างชัดเจนโดยใช้พื้นที่เลย์เอาต์ 2 มิติที่กำหนดโดยผู้ใช้และมีความหมาย
แนวทางปฏิบัติแนะนำ
ใช้ Grid เพื่อใช้เลย์เอาต์การ์ด
การใช้คอนเทนเนอร์ Grid ช่วยให้โค้ดอ่านง่ายขึ้นด้วยการแยกขนาดเลย์เอาต์จริงออกจากการจัดวางรายการย่อย
กำหนดพื้นที่ที่มีชื่อซึ่งมีความหมายด้วยฟังก์ชัน area และวางคอมโพสได้ย่อยด้วยตัวปรับแต่ง gridItem แทนที่จะใช้ดัชนีแทร็กที่แน่นอน
รวมการปรับขนาดแทร็กที่ยืดหยุ่น เช่น GridTrackSize.Auto
และ minmax(0.dp, 1.fr),
เข้ากับช่องว่างแทร็กที่แน่นอน (gap(row = 8.dp, column = 16.dp))
เพื่อจัดระเบียบคอมโพเนนต์การ์ดที่ซับซ้อนซึ่งอยู่เคียงข้างกันอย่างชัดเจนและมีประสิทธิภาพ
ส่วนประกอบ
Grid: เลย์เอาต์คอนเทนเนอร์ 2 มิติใน Jetpack Compose ที่จัดเรียงคอมโพสได้ย่อยเป็นแถวและคอลัมน์ตามแลมบ์ดาการกำหนดค่าgridItem: ส่วนขยายModifierที่เชื่อมโยงองค์ประกอบ UI ย่อยกับareaIdที่เฉพาะเจาะจงซึ่งมีชื่อภายในเลย์เอาต์Gridarea: ฟังก์ชัน DSL การกำหนดค่าภายในGridConfigurationScopeที่ แมปareaIdที่มีความหมายกับช่วงหรือช่วงของแถวและคอลัมน์ที่เฉพาะเจาะจงCard: คอมโพสได้คอนเทนเนอร์ Material Design ที่จัดกลุ่มองค์ประกอบ UI และการจัดรูปแบบที่เกี่ยวข้องGridTrackSize.MinMax: พร็อพเพอร์ตี้การปรับขนาดแทร็กที่กำหนดขอบเขตที่ยืดหยุ่น (minและmax) สำหรับขนาดแถวหรือคอลัมน์GridTrackSize.Auto: พร็อพเพอร์ตี้การปรับขนาดแทร็กที่ปรับขนาดแทร็กแถวหรือคอลัมน์ โดยอัตโนมัติให้พอดีกับเนื้อหา (column(GridTrackSize.Auto))gap: ฟังก์ชันการกำหนดค่าที่ระบุระยะห่างแนวตั้ง (row) และแนวนอน (column) ระหว่างแทร็กตารางกริด
ขั้นตอน
กำหนดตัวระบุพื้นที่ กำหนดค่าแทร็กและพื้นที่ตารางกริด แล้ววางคอมโพสได้ย่อย
1. กำหนดตัวระบุพื้นที่ที่มีความหมาย
ขั้นแรก ให้สร้างการแสดงภูมิภาคภายในเลย์เอาต์การ์ดคลาสสิกแบบกว้างที่ปลอดภัยต่อประเภท คลาส enum ช่วยหลีกเลี่ยงการพิมพ์ผิดของสตริงและให้ความปลอดภัยในเวลาคอมไพล์เมื่อแมปแทร็กและวางรายการย่อย
enum class CardArea { Image, Title, Subtitle, Description, ExtraText, }
2. กำหนดค่าแทร็กตารางกริด 2 มิติและพื้นที่ที่มีชื่อ
กำหนดคอลัมน์และแถวที่ประกอบกันเป็นโครงสร้างการ์ดภายในแลมบ์ดา config ของคอมโพสได้ Grid ใช้ GridTrackSize.Auto สำหรับคอลัมน์รูปภาพเพื่อให้ครอบคลุมความกว้างของภาพขนาดย่อได้อย่างชัดเจน ใช้ minmax(0.dp, 1.fr) สำหรับคอลัมน์เนื้อหาเพื่อให้ขยายได้อย่างยืดหยุ่นตามความกว้างที่เหลือของการ์ด ระบุระยะห่างแทร็กด้วย gap(row = 8.dp, column = 16.dp) แมปตัวระบุ CardArea กับพิกัดแทร็กจริงโดยใช้ฟังก์ชัน area
Grid( config = { // Define columns: left column for image, right for content column(GridTrackSize.Auto) column(minmax(0.dp, 1.fr)) // Define row tracks for the vertical content stack row(GridTrackSize.Auto) row(GridTrackSize.Auto) row(GridTrackSize.Auto) row(GridTrackSize.Auto) // Map semantic identifiers to grid coordinates and spans area(CardArea.Image, row = 1, column = 1, rowSpan = 4) area(CardArea.Title, row = 1, column = 2) area(CardArea.Subtitle, row = 2, column = 2) area(CardArea.Description, row = 3, column = 2) area(CardArea.ExtraText, row = 4, column = 2) gap(row = 8.dp, column = 16.dp) } ) { // Child elements placed in Step 3 }
3. วางคอมโพสได้ย่อยโดยใช้ตัวปรับแต่ง gridItem
เมื่อกำหนดค่าแทร็กและพื้นที่แล้ว ให้วางองค์ประกอบ UI ย่อยแต่ละรายการตามความหมายโดยใช้ตัวปรับแต่ง gridItem คุณประกาศคอมโพสได้ย่อยตามลำดับใดก็ได้ คอนเทนเนอร์ Grid จะวางองค์ประกอบแต่ละรายการลงในภูมิภาค 2 มิติที่กำหนดโดยอัตโนมัติ
@Composable fun WideClassicCard( imageContent: @Composable () -> Unit, title: String, subtitle: String, description: String, extraText: String, modifier: Modifier = Modifier, ) { Card(modifier = modifier) { Grid( config = { // Define columns: left column for image, right for content column(GridTrackSize.Auto) column(minmax(0.dp, 1.fr)) // Define row tracks for the vertical content stack row(GridTrackSize.Auto) row(GridTrackSize.Auto) row(GridTrackSize.Auto) row(GridTrackSize.Auto) // Map semantic identifiers to grid coordinates and spans area(CardArea.Image, row = 1, column = 1, rowSpan = 4) area(CardArea.Title, row = 1, column = 2) area(CardArea.Subtitle, row = 2, column = 2) area(CardArea.Description, row = 3, column = 2) area(CardArea.ExtraText, row = 4, column = 2) gap(row = 8.dp, column = 16.dp) }, ) { Box(modifier = Modifier.gridItem(CardArea.Image)) { imageContent() } Text( text = title, style = MaterialTheme.typography.titleLarge, modifier = Modifier .gridItem(CardArea.Title) .padding(top = 16.dp, end = 16.dp), ) Text( text = subtitle, style = MaterialTheme.typography.titleMedium, modifier = Modifier .gridItem(CardArea.Subtitle) .padding(end = 16.dp), ) Text( text = description, style = MaterialTheme.typography.bodyMedium, modifier = Modifier .gridItem(CardArea.Description) .padding(end = 16.dp), ) Text( text = extraText, style = MaterialTheme.typography.labelSmall, modifier = Modifier .gridItem(CardArea.ExtraText) .padding(bottom = 16.dp, end = 16.dp), ) } } }
ผลลัพธ์
การจัดระเบียบการ์ดคลาสสิกแบบกว้างด้วย Grid และพื้นที่ที่มีชื่อจะช่วยให้คุณแยกแทร็กเลย์เอาต์จริง พิกัดพื้นที่ และการวางคอมโพสได้ย่อยออกจากกันได้อย่างชัดเจน
โครงสร้างนี้ทำให้เลย์เอาต์อ่านและแก้ไขได้ง่ายขึ้น พร้อมทั้งเป็นไปตามหลักเกณฑ์การออกแบบแอป TV สำหรับคอมโพเนนต์ภาพขนาดย่อและคำอธิบายที่อยู่เคียงข้างกัน