Nguyên tắc thiết kế ứng dụng truyền hình xác định một biến thể thẻ có tên là Thẻ cổ điển dạng rộng, hiển thị hình ảnh và khối nội dung mô tả của hình ảnh đó cạnh nhau.
Khi tạo bố cục hai chiều phức tạp cho màn hình TV, việc sử dụng tính năng định vị dựa trên toạ độ truyền thống hoặc các vùng chứa Row và Column được lồng sâu có thể khiến mã của bạn khó đọc, duy trì và tái cấu trúc.
Thẻ cổ điển có chiều rộng là một trường hợp sử dụng lý tưởng cho API Grid của Jetpack Compose, giúp bạn sắp xếp các phần tử cạnh nhau một cách rõ ràng bằng cách sử dụng các vùng bố cục 2D do người dùng xác định, mang tính ngữ nghĩa.
Các phương pháp hay nhất
Triển khai bố cục thẻ bằng Grid.
Việc sử dụng vùng chứa Grid giúp cải thiện khả năng đọc mã bằng cách tách các phương diện bố cục thực tế khỏi vị trí của mục con.
Thay vì dựa vào chỉ mục chính xác của các đường kẻ, hãy xác định các vùng được đặt tên theo ngữ nghĩa bằng hàm area và đặt các thành phần kết hợp con bằng đối tượng sửa đổi gridItem.
Kết hợp tính năng điều chỉnh kích thước linh hoạt của các đường kẻ, chẳng hạn như GridTrackSize.Auto và minmax(0.dp, 1.fr), với khoảng cách chính xác giữa các đường kẻ (gap(row = 8.dp, column = 16.dp)) để sắp xếp các thành phần thẻ phức tạp cạnh nhau một cách rõ ràng và mạnh mẽ.
Nguyên liệu
Grid: Bố cục vùng chứa 2D trong Jetpack Compose, sắp xếp các thành phần kết hợp con thành hàng và cột dựa trên một lambda cấu hìnhgridItem: Một tiện íchModifierliên kết một phần tử con trên giao diện người dùng với mộtareaIdcụ thể có tên bên trong bố cụcGridarea: Một hàm DSL cấu hình trongGridConfigurationScopegiúp ánh xạ mộtareaIdngữ nghĩa đến các khoảng hoặc dải ô hàng và cột cụ thểCard: Một thành phần kết hợp vùng chứa Material Design nhóm các phần tử và kiểu giao diện người dùng có liên quanGridTrackSize.MinMax: Một thuộc tính định cỡ của đường kẻ xác định ranh giới linh hoạt (minvàmax) cho kích thước hàng hoặc cộtGridTrackSize.Auto: Một thuộc tính định cỡ của bản nhạc tự động định cỡ bản nhạc hàng hoặc cột để phù hợp với nội dung của bản nhạc (column(GridTrackSize.Auto))gap: Một hàm cấu hình chỉ định khoảng cách dọc (row) và khoảng cách ngang (column) giữa các đường lưới
Các bước
Xác định mã nhận dạng khu vực, định cấu hình các vùng và đường lưới, sau đó đặt các thành phần kết hợp con.
1. Xác định mã nhận dạng khu vực ngữ nghĩa
Trước tiên, hãy tạo một bản trình bày an toàn về kiểu của các vùng bên trong bố cục thẻ Cổ điển rộng. Lớp enum giúp tránh lỗi chính tả chuỗi và đảm bảo an toàn trong thời gian biên dịch khi ánh xạ các bản nhạc và đặt các mục con.
enum class CardArea { Image, Title, Subtitle, Description, ExtraText, }
2. Định cấu hình các kênh lưới 2D và khu vực được đặt tên
Bên trong lambda config của thành phần kết hợp Grid, hãy xác định các cột và hàng tạo nên cấu trúc thẻ. Sử dụng GridTrackSize.Auto cho cột hình ảnh để bao bọc chiều rộng hình thu nhỏ một cách gọn gàng. Sử dụng minmax(0.dp, 1.fr) cho cột nội dung để cột này mở rộng linh hoạt theo chiều rộng còn lại của thẻ. Chỉ định khoảng cách giữa các bản nhạc bằng gap(row = 8.dp, column = 16.dp). Liên kết các giá trị nhận dạng CardArea với toạ độ đường đua thực tế bằng hàm 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. Đặt các thành phần kết hợp con bằng đối tượng sửa đổi gridItem
Sau khi định cấu hình các đường và khu vực, hãy đặt từng phần tử con trên giao diện người dùng chỉ bằng ý định ngữ nghĩa bằng cách sử dụng đối tượng sửa đổi gridItem. Bạn có thể khai báo các thành phần kết hợp con theo bất kỳ thứ tự nào. Vùng chứa Grid tự động định vị từng phần tử trực tiếp vào vùng 2D được chỉ định.
@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), ) } } }
Kết quả
Bằng cách sắp xếp thẻ Wide classic bằng Grid và các vùng được đặt tên, bạn sẽ tách biệt rõ ràng giữa các đường bố cục thực, toạ độ vùng và vị trí thành phần kết hợp con.
Cấu trúc này giúp bố cục của bạn dễ đọc và duy trì trong khi tuân theo nguyên tắc thiết kế ứng dụng truyền hình cho các thành phần hình thu nhỏ và nội dung mô tả song song.