Màn hình được kết nối mở rộng trải nghiệm cửa sổ kiểu máy tính sang điện thoại thông thường, giúp người dùng truy cập vào màn hình lớn từ thiết bị di động của họ. Khả năng này mở ra những cơ hội mới cho hoạt động tương tác với ứng dụng và năng suất của người dùng.
Tất cả các tính năng độc đáo của cửa sổ kiểu máy tính đều áp dụng cho màn hình được kết nối. Khi bạn kết nối điện thoại với màn hình, trạng thái của điện thoại sẽ không thay đổi và một phiên máy tính trống sẽ bắt đầu trên màn hình được kết nối. Thiết bị và màn hình hoạt động như hai hệ thống riêng biệt, với các ứng dụng dành riêng cho từng màn hình.
Nếu bạn kết nối một thiết bị hỗ trợ cửa sổ kiểu máy tính (chẳng hạn như máy tính bảng) với màn hình ngoài, thì phiên hoạt động trên máy tính sẽ mở rộng trên cả hai màn hình. Sau đó, hai màn hình sẽ hoạt động như một hệ thống liên tục. Chế độ thiết lập này cho phép các cửa sổ, nội dung và con trỏ di chuyển tự do giữa hai màn hình.
Để hỗ trợ màn hình kết nối một cách hiệu quả, bạn cần chú ý đến một số khía cạnh trong thiết kế và cách triển khai ứng dụng. Các phương pháp hay nhất sau đây đảm bảo trải nghiệm người dùng mượt mà và hiệu quả.
Xử lý các thay đổi về hiển thị động
Nhiều ứng dụng được xây dựng dựa trên giả định rằng đối tượng Display và các đặc điểm của đối tượng đó sẽ không thay đổi trong vòng đời của ứng dụng. Tuy nhiên, khi người dùng
kết nối hoặc ngắt kết nối màn hình ngoài, hoặc thậm chí di chuyển cửa sổ ứng dụng giữa
các màn hình, đối tượng Display cơ bản liên kết với bối cảnh hoặc cửa sổ của ứng dụng
có thể thay đổi. Các thuộc tính của màn hình, chẳng hạn như kích thước, độ phân giải, tốc độ làm mới, khả năng hỗ trợ HDR và mật độ, đều có thể khác nhau. Ví dụ: nếu bạn cố định giá trị trong mã dựa trên màn hình điện thoại, thì bố cục của bạn có thể sẽ bị hỏng trên màn hình ngoài.
Màn hình ngoài cũng có thể có mật độ pixel rất khác nhau. Bạn cần đảm bảo ứng dụng của mình phản hồi chính xác với các thay đổi về mật độ. Việc này bao gồm việc sử dụng pixel không phụ thuộc vào mật độ (dp) cho bố cục, cung cấp tài nguyên theo mật độ cụ thể và đảm bảo giao diện người dùng của bạn điều chỉnh theo tỷ lệ phù hợp.
Nếu một hoạt động đang chạy trên màn hình ngoài khi màn hình đó bị ngắt kết nối, thì hệ thống sẽ di chuyển hoạt động đó sang màn hình chính. Việc di chuyển này sẽ kích hoạt các thay đổi về cấu hình (chẳng hạn như thay đổi về kích thước và mật độ màn hình) có thể khiến hoạt động được tạo lại. Ứng dụng của bạn phải xử lý việc thay đổi cấu hình bằng cách lưu và khôi phục trạng thái giao diện người dùng để tránh mất dữ liệu hoặc gây nhầm lẫn cho người dùng.
Sử dụng đúng ngữ cảnh
Việc sử dụng bối cảnh phù hợp là rất quan trọng trong môi trường nhiều màn hình. Khi truy cập vào tài nguyên, bối cảnh của hoạt động (được hiển thị) khác với bối cảnh của ứng dụng (không được hiển thị).
Bối cảnh của hoạt động chứa thông tin về màn hình và luôn được điều chỉnh cho khu vực hiển thị mà hoạt động đó xuất hiện. Điều này cho phép bạn nhận được thông tin chính xác về mật độ hiển thị hoặc các chỉ số về cửa sổ của ứng dụng. Luôn sử dụng bối cảnh hoạt động (hoặc một bối cảnh dựa trên giao diện người dùng khác) để nhận thông tin về cửa sổ hoặc màn hình hiện tại. Điều này cũng ảnh hưởng đến một số API hệ thống có sử dụng thông tin từ bối cảnh.
Trong Jetpack Compose, bạn có thể truy cập vào thông tin dành riêng cho màn hình bằng cách sử dụng các đối tượng CompositionLocal như LocalConfiguration.current và LocalDensity.current. Khi một hoạt động hoặc cửa sổ di chuyển giữa các màn hình, cấu hình thiết bị sẽ thay đổi, kích hoạt quá trình kết hợp lại với các chỉ số hiển thị mới. Các đối tượng CompositionLocal giúp giao diện người dùng của bạn thích ứng liền mạch.
Nhận thông tin hiển thị
Bạn có thể sử dụng lớp Display để lấy thông tin như kích thước màn hình, mật độ hoặc cờ. Sử dụng dịch vụ hệ thống DisplayManager để xem các màn hình có sẵn. Để xác định màn hình bên ngoài, hãy lọc ra Display.DEFAULT_DISPLAY, thường là màn hình điện thoại hoặc máy tính bảng tích hợp:
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager val displays = displayManager.getDisplays() // The default display is 0. External displays have other IDs. val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }
Quản lý việc chạy và định cấu hình hoạt động
Với màn hình được kết nối, ứng dụng có thể chỉ định màn hình nào sẽ chạy khi ứng dụng khởi chạy hoặc khi tạo hoạt động khác. Hành vi này phụ thuộc vào chế độ chạy của hoạt động đã khai báo trong tệp kê khai cũng như trên các cờ ý định và tuỳ chọn do thực thể đang khởi chạy hoạt động thiết lập.
Khi một hoạt động chuyển sang màn hình phụ, ứng dụng của bạn có thể trải qua
quá trình cập nhật bối cảnh, đổi kích thước cửa sổ, cũng như các thay đổi về cấu hình và tài nguyên. Nếu hoạt động có xử lý thay đổi cấu hình, điều này sẽ được thông báo trong
onConfigurationChanged(). Nếu không, hoạt động sẽ được khởi chạy lại.
Nếu chế độ chạy đã chọn của một hoạt động cho phép có nhiều thực thể, thì việc khởi chạy trên màn hình phụ có thể tạo ra một thực thể mới của hoạt động đó. Cả hai hoạt động đều được tiếp tục cùng một lúc, điều này có thể mang lại lợi ích cho một số trường hợp đa nhiệm.
Bạn có thể chạy một hoạt động trên một màn hình cụ thể bằng cách sử dụng ActivityOptions.
Xin lưu ý rằng launchDisplayId yêu cầu Android 8 (cấp độ API 26) trở lên.
// Get DisplayManager and find the first external display. val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager val externalDisplayId = displayManager.displays .firstOrNull { it.displayId != Display.DEFAULT_DISPLAY } ?.displayId // If an external display is found, launch the activity on it. if (externalDisplayId != null) { val intent = Intent(this, MySecondaryActivity::class.java) val options = ActivityOptions.makeBasic() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { options.launchDisplayId = externalDisplayId } startActivity(intent, options.toBundle()) } else { // Optionally, handle the case where no external display is connected. }
Tránh sử dụng danh sách thiết bị cho phép
Đôi khi, ứng dụng hạn chế giao diện người dùng và tính năng trên màn hình lớn đối với một số thiết bị thông qua
danh sách cho phép hoặc bằng cách kiểm tra BUILD.MODEL và kích thước màn hình tích hợp.
Phương pháp này không hiệu quả đối với màn hình được kết nối vì hầu như mọi thiết bị đều có thể kết nối với màn hình lớn và mẫu thiết bị không thay đổi khi kết nối với màn hình ngoài.
Thay vì sử dụng danh sách cho phép hoặc kiểm tra BUILD.MODEL và kích thước màn hình tích hợp, hãy kiểm tra các chỉ số cửa sổ hoặc chức năng của thiết bị trong thời gian chạy để đưa ra quyết định về giao diện người dùng. Sử dụng API Jetpack WindowManager hoặc lớp kích thước cửa sổ để xây dựng bố cục thích ứng và thích nghi cho nhiều kích thước và mật độ màn hình.
Hỗ trợ thiết bị ngoại vi bên ngoài
Khi kết nối với màn hình ngoài, người dùng thường tạo ra một môi trường giống với máy tính hơn. Điều này thường liên quan đến việc sử dụng bàn phím, chuột, bàn di chuột, webcam, micrô và loa ngoài. Bạn cần đảm bảo ứng dụng của mình hoạt động liền mạch với các thiết bị ngoại vi này. Điều này bao gồm việc xử lý phím tắt, quản lý các hoạt động tương tác bằng con trỏ chuột, hỗ trợ chính xác camera hoặc micrô bên ngoài và tuân thủ định tuyến đầu ra âm thanh. Để biết thêm thông tin, hãy xem bài viết Khả năng tương thích đầu vào trên màn hình lớn.
Nâng cao năng suất của người dùng
Màn hình kết nối mang đến cơ hội đáng kể để cải thiện hiệu suất của người dùng. Giờ đây, bạn đã có các công cụ để xây dựng ứng dụng di động có thể mang lại trải nghiệm tương đương với ứng dụng dành cho máy tính. Hãy cân nhắc triển khai các tính năng sau để tăng năng suất của người dùng:
- Cho phép người dùng mở nhiều phiên bản của cùng một ứng dụng. Điều này rất hữu ích cho các tác vụ như so sánh tài liệu, quản lý nhiều cuộc trò chuyện hoặc xem nhiều tệp cùng một lúc.
- Cho phép người dùng chia sẻ dữ liệu đa dạng thức trong và ngoài ứng dụng bằng tính năng kéo và thả.
- Giúp người dùng duy trì quy trình làm việc của họ khi có thay đổi về cấu hình bằng cách triển khai một hệ thống quản lý trạng thái mạnh mẽ.
Bằng cách làm theo các nguyên tắc này và sử dụng các ví dụ về mã được cung cấp, bạn có thể tạo các ứng dụng thích ứng liền mạch với màn hình được kết nối, mang đến cho người dùng trải nghiệm phong phú và hiệu quả hơn.