Tính năng cửa sổ kiểu máy tính cho phép người dùng chạy đồng thời nhiều ứng dụng trong các cửa sổ ứng dụng có thể đổi kích thước để có trải nghiệm linh hoạt như trên máy tính.
Trong hình 1, bạn có thể thấy cách sắp xếp màn hình khi bật tính năng cửa sổ kiểu máy tính. Những điều cần lưu ý:
- Người dùng có thể chạy đồng thời nhiều ứng dụng cạnh nhau.
- Thanh tác vụ ở vị trí cố định ở cuối màn hình, hiển thị các ứng dụng đang chạy. Người dùng có thể ghim ứng dụng để truy cập nhanh.
- Thanh tiêu đề mới có thể tuỳ chỉnh giúp trang trí đầu mỗi cửa sổ bằng các nút điều khiển như thu nhỏ và phóng to.
Theo mặc định, các ứng dụng sẽ mở ở chế độ toàn màn hình trên máy tính bảng Android. Để khởi chạy một ứng dụng ở chế độ cửa sổ kiểu máy tính, hãy nhấn và giữ ô điều khiển cửa sổ ở đầu màn hình rồi kéo ô điều khiển trong giao diện người dùng, như trong hình 2.
Khi một ứng dụng đang mở ở chế độ cửa sổ kiểu máy tính, các ứng dụng khác cũng sẽ mở trong các cửa sổ kiểu máy tính.
Người dùng cũng có thể gọi tính năng cửa sổ kiểu máy tính từ trình đơn xuất hiện bên dưới thanh điều khiển cửa sổ khi bạn nhấn hoặc nhấp vào thanh điều khiển hoặc sử dụng phím tắt Meta key (Windows, Command, or Search) + Ctrl + Down.
Người dùng thoát khỏi chế độ cửa sổ kiểu máy tính bằng cách đóng tất cả các cửa sổ đang hoạt động hoặc bằng cách lấy thanh điều khiển cửa sổ ở đầu cửa sổ kiểu máy tính rồi kéo ứng dụng lên đầu màn hình. Phím tắt Meta + H cũng thoát khỏi chế độ cửa sổ kiểu máy tính và chạy lại các ứng dụng ở chế độ toàn màn hình.
Để quay lại chế độ cửa sổ kiểu máy tính, hãy nhấn hoặc nhấp vào ô không gian kiểu máy tính trong màn hình Gần đây.
Chế độ có thể đổi kích thước và tương thích
Ở chế độ cửa sổ kiểu máy tính, các ứng dụng có hướng cố định có thể đổi kích thước một cách tự do. Điều đó có nghĩa là ngay cả khi một hoạt động bị khoá ở hướng dọc, người dùng vẫn có thể đổi kích thước ứng dụng thành cửa sổ hướng ngang.
Giao diện người dùng của các ứng dụng được khai báo là không thể đổi kích thước (tức là resizeableActivity = false) sẽ được điều chỉnh tỷ lệ trong khi vẫn giữ nguyên tỷ lệ khung hình.
Các ứng dụng camera khoá hướng hoặc được khai báo là không thể đổi kích thước sẽ được xử lý đặc biệt đối với kính ngắm camera: cửa sổ có thể đổi kích thước hoàn toàn, nhưng kính ngắm vẫn giữ nguyên tỷ lệ khung hình. Bằng cách giả định rằng các ứng dụng luôn chạy ở hướng dọc hoặc ngang, các ứng dụng sẽ cố định giá trị trong mã hoặc đưa ra các giả định dẫn đến việc tính toán sai hướng hoặc tỷ lệ khung hình của bản xem trước hoặc hình ảnh đã chụp, dẫn đến hình ảnh bị kéo giãn, bị lệch sang một bên hoặc bị lộn ngược.
Cho đến khi các ứng dụng sẵn sàng triển khai kính ngắm camera hoàn toàn thích ứng, cách xử lý đặc biệt này sẽ mang lại trải nghiệm người dùng cơ bản hơn, giúp giảm thiểu tác động mà các giả định sai có thể gây ra.
Để tìm hiểu thêm về chế độ tương thích cho các ứng dụng camera, hãy xem bài viết Chế độ tương thích với thiết bị.
Phần chèn tiêu đề có thể tuỳ chỉnh
Tất cả các ứng dụng chạy ở chế độ cửa sổ kiểu máy tính đều có thanh tiêu đề, ngay cả ở chế độ toàn màn hình. Bạn có thể tuỳ chỉnh thanh này để ngăn nội dung ứng dụng bị che khuất và vẽ các thành phần giao diện người dùng tuỳ chỉnh trực tiếp vào không gian tiêu đề.
Triển khai
Để vẽ nội dung tuỳ chỉnh trong thanh tiêu đề, bước đầu tiên là làm cho nền thanh tiêu đề trong suốt. Bạn có thể thực hiện việc này bằng cách sử dụng cờ
APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND với
WindowInsetsController.
window.insetsController?.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND )
Sau khi thanh tiêu đề trong suốt, bạn có thể tạo kiểu cho vùng tiêu đề để phù hợp với thiết kế của ứng dụng. Sử dụng WindowInsets.isCaptionBarVisible để phát hiện xem thanh có
xuất hiện hay không và áp dụng chiều cao hoặc khoảng đệm thích hợp cho bố cục.
@OptIn(ExperimentalLayoutApi::class) @Composable fun CaptionBar() { if (WindowInsets.isCaptionBarVisible) { Row( modifier = Modifier .windowInsetsTopHeight(WindowInsets.captionBar) .fillMaxWidth() .background(if (isSystemInDarkTheme()) Color.White else Color.Black), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { Text( text = "Caption Bar Title", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(4.dp) ) } } }
setSystemBarsAppearance(appearance,mask): Định cấu hình kiểu hiển thị của các thanh hệ thống. Tham số đầu tiên xác định các cờ hiển thị mục tiêu, trong khi tham số thứ hai hoạt động như một mặt nạ để kiểm soát những cờ cụ thể được sửa đổi.windowInsetsTopHeight(): Tự động đặt chiều cao của Thành phần kết hợp để khớp với thanh tiêu đề của hệ thống, giúp nền tuỳ chỉnh của bạn lấp đầy vùng chú thích mà không cần mã hoá cứng các giá trị pixel.WindowInsets.captionBar: Cung cấp kích thước cho các nút điều khiển cửa sổ kiểu máy tính để bàn (Đóng, Phóng to, v.v.), cho phép giao diện người dùng của bạn tự động điều chỉnh tỷ lệ hoặc ẩn khi vào hoặc rời khỏi chế độ cửa sổ kiểu máy tính để bàn.
Để biết thêm thông tin, hãy xem bài viết Giới thiệu về phần chèn cửa sổ. Ngoài tiêu đề, bạn có thể hiển thị các thành phần giao diện người dùng khác trong thanh chú thích, chẳng hạn như các thẻ (như trong Google Chrome), thanh tìm kiếm hoặc hình đại diện hồ sơ.
Giao diện người dùng
Để tránh chồng chéo giao diện người dùng với các nút hệ thống, Android 15 cung cấp phương thức
WindowInsets#getBoundingRects(). Phương thức này trả về một danh sách các
Rect đối tượng đại diện cho các vùng do các thành phần hệ thống chiếm giữ. Mọi khoảng trống còn lại trong thanh chú thích là một vùng an toàn nơi bạn có thể đặt nội dung tuỳ chỉnh một cách an toàn.
Chuyển đổi giao diện của các thành phần chú thích hệ thống cho giao diện sáng và tối bằng
APPEARANCE_LIGHT_CAPTION_BARS. Truy cập vào phần chèn bằng
WindowInsets.Companion.captionBar() trong Compose hoặc
WindowInsets.Type.captionBar() trong Khung hiển thị.
Để biết thêm thông tin, hãy xem bài viết Giới thiệu về phần chèn cửa sổ.
Hỗ trợ chế độ đa nhiệm và nhiều phiên bản
Chế độ đa nhiệm là cốt lõi của tính năng cửa sổ kiểu máy tính và việc cho phép nhiều phiên bản của ứng dụng có thể giúp tăng năng suất của người dùng.
Kể từ Android 15, bạn có thể sử dụng
PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI. Bằng cách đặt thuộc tính này trong AndroidManifest.xml, bạn chỉ định rằng giao diện người dùng hệ thống sẽ cung cấp các lựa chọn (như nút "Cửa sổ mới") để khởi chạy ứng dụng trong nhiều phiên bản.
<application>
<property
android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
android:value="true" />
</application>
Lưu ý: Ở chế độ cửa sổ kiểu máy tính và các môi trường nhiều cửa sổ khác, các tác vụ mới sẽ mở trong một cửa sổ mới, vì vậy, hãy kiểm tra kỹ hành trình của người dùng bất cứ khi nào ứng dụng của bạn bắt đầu nhiều tác vụ.
Quản lý các phiên bản ứng dụng bằng cử chỉ kéo
Ở chế độ nhiều cửa sổ, người dùng có thể bắt đầu một phiên bản ứng dụng mới bằng cách kéo một thành phần giao diện người dùng (như thẻ hoặc tài liệu) ra khỏi cửa sổ của ứng dụng. Người dùng cũng có thể di chuyển các thành phần giữa các phiên bản khác nhau của cùng một ứng dụng.
Chuyển dữ liệu bằng thao tác kéo và thả
Để định cấu hình một thành phần kết hợp làm nguồn kéo cho thao tác kéo và thả nhiều phiên bản cho phép người dùng kéo nội dung sang một phiên bản khác của ứng dụng hoặc tạo một mới phiên bản bằng cách thả nội dung vào một vùng trống trên màn hình, hãy sử dụng đối tượng sửa đổi dragAndDropSource. Trong lambda, hãy trả về
DragAndDropTransferData, chuyển ClipData chứa dữ liệu cần
chuyển và các cờ để định cấu hình hành vi nhiều phiên bản.
Android 15 giới thiệu 2 cờ chính cho tính năng cửa sổ kiểu máy tính và các tương tác nhiều phiên bản:
DRAG_FLAG_GLOBAL_SAME_APPLICATION: Cho biết rằng thao tác kéo có thể vượt qua ranh giới cửa sổ (đối với nhiều phiên bản của cùng một ứng dụng). KhistartDragAndDrop()được gọi với cờ này được đặt, chỉ cửa sổ hiển thị thuộc cùng một ứng dụng mới có thể tham gia vào thao tác kéo và nhận nội dung được kéo.
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( clipData = ClipData.newPlainText("label", "Your data"), flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION ) }
DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG: Cho phép người dùng bắt đầu một phiên bản mới của ứng dụng bằng cách thả nội dung được kéo vào một vùng trống trên màn hình, nếu không có cửa sổ nào khác xử lý thao tác thả.- Khi sử dụng cờ này, bạn phải cung cấp một
IntentSenderbằngClipData.Item.Builder#setIntentSender(), mà hệ thống sử dụng để khởi chạy hoạt động mới nếu xảy ra thao tác thả không được xử lý.
- Khi sử dụng cờ này, bạn phải cung cấp một
Modifier.dragAndDropSource { _ -> val intent = Intent.makeMainActivity(activity.componentName).apply { putExtra("EXTRA_ITEM_ID", itemId) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK or Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT } val pendingIntent = PendingIntent.getActivity( activity, 0, intent, PendingIntent.FLAG_IMMUTABLE ) val data = ClipData( "Item $itemId", arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT), ClipData.Item.Builder().setIntentSender(pendingIntent.intentSender).build() ) DragAndDropTransferData( clipData = data, flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION or View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG, ) }
Nhận dữ liệu được chuyển
Để chấp nhận dữ liệu từ một phiên bản khác, hãy sử dụng công cụ sửa đổi dragAndDropTarget.
Bạn phải yêu cầu cấp quyền một cách rõ ràng nếu dữ liệu đến từ một phiên bản hoặc ứng dụng khác.
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.toAndroidDragEvent().clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { requestDragAndDropPermissions(activity, event.toAndroidDragEvent()) val clipData = event.toAndroidDragEvent().clipData val item = clipData?.getItemAt(0)?.text if (item != null) { // Process the dropped text item here } return item != null } } )
Các bước chính:
- Bộ lọc: Sử dụng
shouldStartDragAndDropđể kiểm tra xem dữ liệu đến (loại MIME) có được hỗ trợ hay không. - Quyền: Gọi
requestDragAndDropPermissions(event)để truy cập vào dữ liệu. - Xử lý: Trích xuất dữ liệu trong lệnh gọi lại
onDrop.
Các phương pháp tối ưu hoá khác
Tuỳ chỉnh quá trình khởi chạy ứng dụng và chuyển đổi ứng dụng từ chế độ cửa sổ kiểu máy tính sang chế độ toàn màn hình.
Chỉ định kích thước và vị trí mặc định
Không phải tất cả các ứng dụng, ngay cả khi có thể đổi kích thước, đều cần một cửa sổ lớn để mang lại giá trị cho người dùng. Bạn
có thể sử dụng phương thức ActivityOptions#setLaunchBounds() để chỉ định kích thước và vị trí mặc định
khi một hoạt động được khởi chạy.
Vào chế độ toàn màn hình từ không gian kiểu máy tính
Các ứng dụng có thể chuyển sang chế độ toàn màn hình bằng cách gọi Activity#requestFullScreenMode(). Phương thức này hiển thị ứng dụng ở chế độ toàn màn hình trực tiếp từ chế độ cửa sổ kiểu máy tính.