Bạn có thể làm cho ứng dụng hiển thị hiện nội dung tràn viền (sử dụng toàn bộ chiều rộng và chiều cao của màn hình) bằng cách vẽ phía sau thanh hệ thống. Thanh hệ thống là thanh trạng thái và thanh điều hướng.
Để triển khai bố cục tràn viền, ứng dụng của bạn phải làm như sau:
- Vẽ phía sau thanh điều hướng để đạt được trải nghiệm người dùng hấp dẫn và hiện đại hơn.
- Vẽ phía sau thanh trạng thái nếu thanh trạng thái phù hợp với nội dung và bố cục của bạn, chẳng hạn như trong trường hợp hình ảnh có chiều rộng đầy đủ. Để thực hiện việc này, hãy dùng các API như
AppBarLayout
, nhằm xác định thanh ứng dụng được ghim vào đầu màn hình.
Để triển khai bố cục tràn viền trong ứng dụng, hãy thực hiện các bước sau:
- Bật màn hình tràn viền.
- Xử lý mọi trường hợp trùng lặp hình ảnh.
Bật màn hình tràn viền.
Bạn có thể bật màn hình tràn viền trong ứng dụng bằng cách gọi enableEdgeToEdge
trong onCreate
của Activity
. Phương thức này sẽ được gọi trước setContentView
.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) ... }
Java
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { EdgeToEdge.enable(this); super.onCreate(savedInstanceState); ... }
Theo mặc định, enableEdgeToEdge
làm cho các thanh hệ thống trong suốt, ngoại trừ ở chế độ điều hướng bằng 3 nút, trong đó thanh trạng thái sẽ có màn hình trong suốt. Màu của các biểu tượng hệ thống và màn hình được điều chỉnh dựa trên giao diện sáng hoặc tối của hệ thống.
Phương thức enableEdgeToEdge
sẽ tự động khai báo rằng ứng dụng nên được đặt cạnh nhau và điều chỉnh màu của các thanh hệ thống. Hãy xem phần "Thiết lập màn hình tràn viền theo cách thủ công" nếu việc này là cần thiết vì bất kỳ lý do gì.
Xử lý các trường hợp trùng lặp bằng cách sử dụng phần lồng ghép
Sau khi bạn bật màn hình tràn viền, một số khung hiển thị của ứng dụng có thể vẽ phía sau thanh hệ thống, như minh hoạ trong hình 3.
Bạn có thể giải quyết các trường hợp trùng lặp bằng cách phản ứng với phần lồng ghép, chỉ định những phần của màn hình giao nhau với giao diện người dùng hệ thống, chẳng hạn như thanh điều hướng hoặc thanh trạng thái. Việc giao cắt có thể có nghĩa là hiển thị phía trên nội dung, nhưng cũng có thể thông báo cho ứng dụng về các cử chỉ của hệ thống.
Các loại phần lồng ghép áp dụng để hiển thị ứng dụng tràn viền là:
Phần lồng ghép thanh hệ thống: phù hợp nhất với những khung hiển thị có thể nhấn vào và không bị thanh hệ thống che khuất hình ảnh.
Phần lồng ghép cử chỉ hệ thống: dành cho các khu vực thao tác bằng cử chỉ mà hệ thống sử dụng và được ưu tiên hơn ứng dụng của bạn.
Phần lồng ghép thanh hệ thống
Phần lồng ghép thanh hệ thống là loại phần lồng ghép thường dùng nhất. Chúng đại diện cho khu vực mà giao diện người dùng hệ thống hiển thị trong trục Z phía trên ứng dụng của bạn. Bạn nên sử dụng giao diện này để di chuyển hoặc đệm các khung hiển thị có thể nhấn vào trong ứng dụng và không bị che khuất hình ảnh bởi các thanh hệ thống.
Ví dụ: nút hành động nổi (FAB) trong hình 3 bị thanh điều hướng che khuất một phần:
Để tránh loại hình ảnh trùng lặp này ở chế độ cử chỉ hoặc chế độ nút, bạn có thể tăng lề của khung hiển thị bằng cách sử dụng getInsets(int)
thông qua WindowInsetsCompat.Type.systemBars()
.
Ví dụ về mã sau đây cho thấy cách triển khai các phần lồng ghép thanh hệ thống:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams>( leftMargin = insets.left, bottomMargin = insets.bottom, rightMargin = insets.right, ) // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
Nếu bạn áp dụng giải pháp này cho ví dụ minh hoạ trong hình 3, thì sẽ không có tình trạng trùng lặp hình ảnh ở chế độ nút, như minh hoạ trong hình 4:
Điều này cũng áp dụng cho chế độ thao tác bằng cử chỉ, như trong hình 5:
Phần lồng ghép cử chỉ hệ thống
Các phần lồng ghép cử chỉ hệ thống thể hiện các khu vực của cửa sổ nơi các cử chỉ hệ thống sẽ được ưu tiên hơn ứng dụng của bạn. Những vùng này được hiển thị bằng màu cam trong hình 6:
Giống như các phần lồng ghép thanh hệ thống, bạn có thể tránh chồng chéo các phần lồng ghép cử chỉ hệ thống bằng cách sử dụng getInsets(int)
với WindowInsetsCompat.Type.systemGestures()
.
Sử dụng các phần lồng ghép này để di chuyển hoặc di chuyển các chế độ xem có thể vuốt ra khỏi các cạnh. Một số trường hợp sử dụng phổ biến bao gồm bảng dưới cùng, vuốt trong trò chơi và băng chuyền được triển khai bằng ViewPager2
.
Trên Android 10 trở lên, các phần lồng ghép cử chỉ hệ thống chứa một phần lồng ghép dưới cùng cho cử chỉ màn hình chính và một phần lồng ghép bên trái và bên phải cho cử chỉ quay lại:
Mã ví dụ sau đây cho thấy cách triển khai các phần lồng ghép cử chỉ hệ thống:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Chế độ hiển thị tối đa
Một số nội dung có trải nghiệm tốt nhất ở chế độ toàn màn hình, mang đến cho người dùng trải nghiệm sống động hơn. Bạn có thể ẩn các thanh hệ thống cho chế độ hiển thị tối đa bằng cách sử dụng thư viện WindowInsetsController
và WindowInsetsControllerCompat
:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
Tham khảo bài viết Ẩn thanh hệ thống cho chế độ hiển thị tối đa để biết thêm thông tin về cách triển khai tính năng này.
Tài nguyên khác
Hãy xem các tài liệu tham khảo sau để biết thêm thông tin về WindowInsets
, thao tác bằng cử chỉ và cách hoạt động của phần lồng ghép:
- WindowInsets – trình nghe bố cục
- Thao tác bằng cử chỉ: Phần lồng ghép
- Cách phần lồng ghép hoạt động trên Android?