Vết cắt trên màn hình là một vùng trên một số thiết bị mở rộng ra cả bề mặt màn hình. Điều này mang lại trải nghiệm tràn viền, đồng thời cung cấp không gian cho các cảm biến quan trọng ở mặt trước thiết bị.
Android hỗ trợ vết cắt trên màn hình trên các thiết bị chạy Android 9 (API cấp 28) trở lên. Tuy nhiên, nhà sản xuất thiết bị cũng có thể hỗ trợ vết cắt trên màn hình trên các thiết bị chạy Android 8.1 trở xuống.
Tài liệu này mô tả cách triển khai tính năng hỗ trợ cho các thiết bị có vết cắt, bao gồm cả cách xử lý vùng cắt – tức là hình chữ nhật tràn viền trên bề mặt màn hình có chứa vết cắt.
![Hình ảnh ví dụ về vết cắt trên màn hình ở trên cùng chính giữa](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-intro.png?authuser=5&hl=vi)
Chọn cách ứng dụng xử lý các vùng cắt
Nếu không muốn nội dung chồng chéo với một vùng cắt, thì nhìn chung, bạn chỉ cần đảm bảo nội dung không chồng chéo với thanh trạng thái và thanh điều hướng. Nếu bạn đang kết xuất vào vùng cắt, hãy sử dụng WindowInsetsCompat.getDisplayCutout()
để truy xuất đối tượng DisplayCutout
có chứa các phần lồng ghép và hộp giới hạn an toàn cho mỗi vết cắt. Các API này cho phép bạn kiểm tra xem nội dung có trùng lặp với vết cắt hay không để bạn có thể đặt lại vị trí nếu cần.
Bạn cũng có thể xác định xem nội dung có nằm phía sau vùng cắt hay không. Thuộc tính bố cục cửa sổ layoutInDisplayCutoutMode
kiểm soát cách vẽ nội dung trong vùng cắt.
Bạn có thể đặt layoutInDisplayCutoutMode
thành một trong các giá trị sau:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
: nội dung hiển thị trong vùng cắt khi vết cắt trên màn hình nằm trong thanh hệ thống. Nếu không, cửa sổ sẽ không chồng chéo với vết cắt trên màn hình; ví dụ: nội dung có thể được tạo hiệu ứng hòm thư khi hiển thị ở chế độ ngang. Nếu ứng dụng của bạn nhắm đến SDK 35, thì giá trị này được hiểu làALWAYS
đối với cửa sổ không nổi.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
: nội dung luôn được phép kéo dài vào các vùng cắt. Nếu ứng dụng của bạn nhắm đến SDK 35 và đang chạy trên thiết bị Android 15, thì đây là chế độ duy nhất được phép dùng cho cửa sổ không nổi để đảm bảo màn hình tràn viền.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
: nội dung hiển thị trong vùng cắt ở cả chế độ dọc và ngang. Đừng sử dụng cho các cửa sổ nổi. Nếu ứng dụng của bạn nhắm đến SDK 35, thì giá trị này được hiểu làALWAYS
đối với cửa sổ không nổi.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
: nội dung không bao giờ hiển thị trong vùng cắt. Nếu ứng dụng của bạn nhắm đến SDK 35, thì giá trị này sẽ được hiểu làALWAYS
đối với cửa sổ không nổi.
Bạn có thể thiết lập chế độ cắt bỏ theo cách lập trình hoặc thiết lập kiểu trong hoạt động. Ví dụ sau đây xác định một kiểu để áp dụng thuộc tính LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
cho hoạt động.
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
Các phần sau đây sẽ mô tả chi tiết hơn về các chế độ cắt khác nhau.
Hành động mặc định.
Nếu ứng dụng của bạn nhắm đến SDK 35 và đang chạy trên thiết bị Android 15, thì LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
sẽ là hành vi mặc định và LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
được hiểu là LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
đối với các cửa sổ không nổi.
Nếu không, LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
sẽ là giá trị mặc định.
Kết xuất nội dung trong các vùng cắt cạnh ngắn
Nếu ứng dụng của bạn nhắm đến SDK 35 và đang chạy trên thiết bị Android 15, thì LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
sẽ được hiểu là LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
đối với cửa sổ không nổi.
Với LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
, nội dung sẽ mở rộng vào vùng cắt trên cạnh ngắn của màn hình ở cả chế độ dọc và ngang, bất kể các thanh hệ thống có ẩn hay hiện. Khi sử dụng chế độ này, hãy đảm bảo không có nội dung quan trọng nào chồng chéo với vùng cắt.
Hình ảnh sau đây là ví dụ về LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
cho một thiết bị ở chế độ dọc:
![Hình ảnh cho thấy nội dung xuất hiện trong vùng cắt khi ở chế độ dọc](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-short-edges-1.png?authuser=5&hl=vi)
Hình ảnh sau đây là ví dụ về LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
cho một thiết bị ở chế độ ngang:
![Hình ảnh cho thấy nội dung xuất hiện trong vùng cắt khi ở chế độ ngang](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-short-edges-2.png?authuser=5&hl=vi)
Ở chế độ này, cửa sổ sẽ mở rộng dưới các vết cắt trên cạnh ngắn của màn hình ở cả chế độ dọc và ngang, bất kể cửa sổ có ẩn các thanh hệ thống hay không.
Vết cắt ở góc được coi là trên cạnh ngắn:
![Hình ảnh cho thấy một thiết bị có vết cắt ở góc](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-corner.png?authuser=5&hl=vi)
Không bao giờ kết xuất nội dung trong vùng cắt trên màn hình
Nếu ứng dụng của bạn nhắm đến SDK 35 và đang chạy trên thiết bị Android 15, thì LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
sẽ được hiểu là LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
đối với cửa sổ không nổi.
Với LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
, cửa sổ không bao giờ được phép chồng chéo với vùng cắt.
Sau đây là ví dụ về LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
ở chế độ dọc:
![Hình ảnh hiển thị LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER cho chế độ dọc](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-never.png?authuser=5&hl=vi)
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
cho chế độ dọc.
Sau đây là ví dụ về LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
ở chế độ ngang:
![Hình ảnh hiển thị LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER cho chế độ ngang](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-never-landscape.png?authuser=5&hl=vi)
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
ở chế độ ngang.
Các phương pháp hay nhất để hỗ trợ về vết cắt trên màn hình
Khi xử lý các vết cắt trên màn hình, hãy cân nhắc những điều sau:
- Lưu ý đến vị trí của các phần tử quan trọng trên giao diện người dùng. Đừng để vùng cắt che khuất văn bản, thành phần điều khiển hoặc thông tin quan trọng khác.
- Không đặt hoặc mở rộng bất kỳ phần tử tương tác nào yêu cầu nhận dạng bằng thao tác chạm vào vùng cắt. Độ nhạy cảm ứng có thể thấp hơn ở vùng cắt.
Nếu có thể, hãy sử dụng
WindowInsetsCompat
để truy xuất chiều cao của thanh trạng thái và xác định khoảng đệm thích hợp áp dụng cho nội dung của bạn. Tránh mã cứng chiều cao của thanh trạng thái, vì điều này có thể dẫn đến việc nội dung bị trùng lặp hoặc bị cắt.Hình 7. Sử dụng WindowInsetsCompat
để tránh tình trạng trùng lặp hoặc cắt bỏ nội dung.Sử dụng
View.getLocationInWindow()
để xác định lượng không gian cửa sổ mà ứng dụng của bạn đang dùng. Đừng giả định rằng ứng dụng đang sử dụng toàn bộ cửa sổ và cũng không nên dùngView.getLocationOnScreen()
.Hãy sử dụng các chế độ cắt bỏ
always
,shortEdges
hoặcnever
nếu ứng dụng của bạn cần chuyển đổi sang và ra khỏi chế độ hiển thị tối đa. Hành vi cắt bỏ mặc định có thể khiến nội dung trong ứng dụng hiển thị trong vùng cắt khi các thanh hệ thống xuất hiện, chứ không phải khi ở chế độ hiển thị tối đa. Điều này dẫn đến việc nội dung di chuyển lên và xuống trong quá trình chuyển đổi, như được minh hoạ trong ví dụ sau.Hình 8. Ví dụ về nội dung di chuyển lên và xuống trong quá trình chuyển đổi. Ở chế độ hiển thị tối đa, hãy cẩn thận khi sử dụng toạ độ cửa sổ so với màn hình, vì ứng dụng của bạn không sử dụng toàn bộ màn hình khi ở dạng hòm thư. Do hòm thư, toạ độ trên nguồn gốc màn hình sẽ không giống với toạ độ ở gốc gốc cửa sổ. Bạn có thể chuyển đổi toạ độ màn hình thành toạ độ của thành phần hiển thị nếu cần bằng cách sử dụng
getLocationOnScreen()
. Hình ảnh sau đây cho thấy sự khác biệt giữa các toạ độ khi nội dung ở dạng hòm thư:Hình 9. Cửa sổ so với các toạ độ màn hình khi nội dung ở dạng hòm thư. Khi xử lý
MotionEvent
, hãy sử dụngMotionEvent.getX()
vàMotionEvent.getY()
để tránh các vấn đề tương tự về toạ độ. Không sử dụngMotionEvent.getRawX()
hoặcMotionEvent.getRawY()
.
Kiểm thử cách nội dung hiển thị
Kiểm thử tất cả màn hình và trải nghiệm của ứng dụng. Kiểm thử trên các thiết bị có nhiều loại vết cắt (nếu có thể). Nếu không có thiết bị có vết cắt, bạn có thể mô phỏng các cấu hình vết cắt phổ biến trên mọi thiết bị hoặc trình mô phỏng chạy Android 9 trở lên bằng cách thực hiện như sau:
- Bật Tuỳ chọn cho nhà phát triển.
- Trên màn hình Tuỳ chọn cho nhà phát triển, hãy cuộn xuống phần Bản vẽ rồi chọn Mô phỏng màn hình có vết cắt.
Chọn loại vết cắt.
Hình 10. Tuỳ chọn cho nhà phát triển để kiểm thử cách nội dung hiển thị.
Tài nguyên khác
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT