Hỗ trợ chế độ nhiều cửa sổ

Chế độ nhiều cửa sổ cho phép các ứng dụng đồng thời chia sẻ cùng một màn hình. Các ứng dụng có thể nằm cạnh nhau hoặc một ứng dụng ở phía trên ứng dụng kia (chế độ chia đôi màn hình), một ứng dụng ở một cửa sổ nhỏ phủ lên các ứng dụng khác (chế độ hình trong hình) hoặc riêng lẻ ứng dụng trong những cửa sổ riêng biệt, có thể di chuyển và thay đổi kích thước (chế độ biểu mẫu tuỳ ý).

Hình 1. Hiển thị 2 ứng dụng cạnh nhau trong chế độ chia đôi màn hình.

Trải nghiệm người dùng phụ thuộc vào phiên bản Android và loại thiết bị:

  • Android 7.0 (API cấp 24) ra mắt chế độ chia đôi màn hình trên màn hình nhỏ và chế độ hình trong hình trên một số thiết bị.

    • Chế độ chia đôi màn hình sẽ lấp đầy màn hình bằng 2 ứng dụng, giúp các ứng dụng đó xuất hiện cạnh nhau hoặc một quảng cáo ở phía trên nhau. Người dùng có thể kéo đường phân chia tách hai ứng dụng để làm cho một ứng dụng lớn hơn và ứng dụng còn lại nhỏ hơn.

    • Chế độ hình trong hình cho phép người dùng tiếp tục phát video khi tương tác với một ứng dụng khác (xem phần Hỗ trợ tính năng Hình trong hình).

    • Chế độ biểu mẫu tuỳ ý, trong đó người dùng có thể tuỳ ý thay đổi kích thước từng hoạt động, được các nhà sản xuất thiết bị có màn hình lớn bật.

      Bạn có thể định cấu hình ứng dụng để xử lý chế độ nhiều cửa sổ bằng cách chỉ định phương diện tối thiểu được phép cho hoạt động của bạn. Bạn cũng có thể tắt bằng cách đặt chế độ nhiều cửa sổ cho ứng dụng resizeabableActivity="false" để đảm bảo hệ thống luôn hiển thị ứng dụng toàn màn hình.

  • Android 8.0 (API cấp 26) hỗ trợ cả chế độ hình trong hình trên các thiết bị nhỏ màn hình thiết bị.

  • Android 12 (API cấp 31) biến chế độ nhiều cửa sổ thành chế độ tiêu chuẩn.

    • Trên màn hình lớn (lớp kích thước cửa sổ trung bình hoặc mở rộng), nền tảng hỗ trợ tất cả ứng dụng ở chế độ nhiều cửa sổ, bất kể ứng dụng . Nếu là resizeableActivity="false", ứng dụng sẽ được đưa vào chế độ tương thích khi cần thiết để phù hợp với kích thước màn hình.

    • Trên màn hình nhỏ (lớp kích thước cửa sổ nhỏ gọn), hệ thống sẽ kiểm tra minWidthminHeight của một hoạt động để xác định xem hoạt động có thể chạy ở chế độ nhiều cửa sổ. Nếu resizeableActivity="false", ứng dụng này không được phép chạy trong chế độ nhiều cửa sổ bất kể chiều rộng và chiều cao tối thiểu là bao nhiêu.

Chế độ chia đôi màn hình

Người dùng có thể kích hoạt chế độ chia đôi màn hình bằng cách làm như sau:

  1. Mở màn hình Gần đây
  2. Vuốt một ứng dụng vào chế độ xem
  3. Nhấn vào biểu tượng ứng dụng trên thanh tiêu đề của ứng dụng
  4. Chọn tuỳ chọn trình đơn chia đôi màn hình
  5. Chọn một ứng dụng khác từ màn hình Gần đây hoặc đóng màn hình Gần đây và chạy một ứng dụng khác

Người dùng có thể thoát khỏi chế độ chia đôi màn hình bằng cách kéo bộ chia cửa sổ vào cạnh của màn hình – lên hoặc xuống, sang trái hoặc sang phải.

Mở cửa sổ chia đôi màn hình liền kề

Nếu ứng dụng của bạn cần truy cập vào nội dung thông qua một ý định, bạn có thể sử dụng FLAG_ACTIVITY_LAUNCH_ADJACENT để mở nội dung trong một giao diện liền kề cửa sổ chia đôi màn hình.

FLAG_ACTIVITY_LAUNCH_ADJACENT được ra mắt trong Android 7.0 (API cấp 24) để cho phép các ứng dụng chạy ở chế độ chia đôi màn hình khởi chạy các hoạt động trong vùng cửa sổ.

Android 12L (API cấp 32) trở lên đã mở rộng định nghĩa của cờ thành cho phép các ứng dụng chạy ở chế độ toàn màn hình kích hoạt chế độ chia đôi màn hình rồi khởi chạy trong cửa sổ liền kề.

Để khởi chạy một hoạt động liền kề, hãy dùng FLAG_ACTIVITY_LAUNCH_ADJACENT trong kết hợp với FLAG_ACTIVITY_NEW_TASK, ví dụ:

fun openUrlInAdjacentWindow(url:
String) { Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url)
addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or Intent.FLAG_ACTIVITY_NEW_TASK)
 }.also { intent -> startActivity(intent) } }

Vòng đời của hoạt động ở chế độ nhiều cửa sổ

Chế độ nhiều cửa sổ không thay đổi vòng đời hoạt động. Tuy nhiên, trạng thái tiếp tục của ứng dụng trong nhiều cửa sổ sẽ khác nhau tuỳ theo các phiên bản khác nhau Android.

Tiếp tục nhiều lần (multi-resume)

Android 10 (API cấp 29) trở lên hỗ trợ tính năng tiếp tục nhiều lần — tất cả các hoạt động vẫn ở trạng thái RESUMED khi thiết bị ở chế độ nhiều cửa sổ . Một hoạt động có thể bị tạm dừng nếu một hoạt động rõ nằm ở trên hoạt động hoặc hoạt động không thể lấy làm tâm điểm, ví dụ: hoạt động đang ở chế độ hình trong hình. Cũng có thể không có hoạt động nào tập trung vào thời gian nhất định, ví dụ: nếu ngăn thông báo đang mở. onStop() phương thức hoạt động như bình thường: phương thức này được gọi bất cứ khi nào một hoạt động bị thực hiện màn hình.

Tính năng Tiếp tục nhiều lần cũng hoạt động trên một số thiết bị chạy Android 9 (API cấp 28). Để chọn sử dụng tính năng Tiếp tục nhiều lần trên các thiết bị Android 9, hãy thêm siêu dữ liệu của tệp kê khai sau:

<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />

Để xác minh một thiết bị nào đó có hỗ trợ siêu dữ liệu của tệp kê khai này, hãy tham khảo thông số kỹ thuật của thiết bị.

Android 9

Ở chế độ nhiều cửa sổ trên Android 9 (API cấp 28) trở xuống, chỉ có hoạt động mà người dùng tương tác gần đây nhất mới ở trạng thái hoạt động tại một thời điểm nhất định. Chiến dịch này hoạt động được coi là trên cùng và là hoạt động duy nhất trong RESUMED trạng thái. Tất cả các hoạt động khác có thể hiển thị là STARTED nhưng không phải là RESUMED. Tuy nhiên, hệ thống đưa ra các hoạt động có thể nhìn thấy nhưng không được tiếp tục ở mức cao hơn mức độ ưu tiên so với các hoạt động không hiển thị. Nếu người dùng tương tác với một trong các hoạt động hiển thị, hoạt động đó được tiếp tục và hoạt động ở trên cùng trước đó hoạt động sẽ chuyển sang trạng thái STARTED.

Khi có nhiều hoạt động trong một quá trình hoạt động đơn lẻ của ứng dụng, hoạt động có thứ tự z cao nhất sẽ được tiếp tục và các hoạt động khác bị tạm dừng.

Các thay đổi về cấu hình

Khi người dùng đặt một ứng dụng vào chế độ nhiều cửa sổ, hệ thống sẽ thông báo cho hoạt động của một thay đổi về cấu hình như được chỉ định trong phần Xử lý cấu hình thay đổi. Điều này cũng xảy ra khi người dùng đổi kích thước ứng dụng hoặc khôi phục ứng dụng. sang chế độ toàn màn hình.

Về cơ bản, thay đổi này cũng ảnh hưởng đến vòng đời hoạt động như khi hệ thống sẽ thông báo cho ứng dụng rằng thiết bị đã chuyển từ chế độ dọc sang hướng ngang, ngoại trừ việc kích thước ứng dụng bị thay đổi thay vì vừa được hoán đổi. Hoạt động của bạn có thể tự xử lý thay đổi về cấu hình, hoặc ứng dụng của bạn có thể cho phép hệ thống huỷ bỏ hoạt động và tạo lại hoạt động đó bằng các phương diện mới.

Nếu người dùng đổi kích thước một cửa sổ và làm cho cửa sổ đó lớn hơn theo một trong hai thứ nguyên, thì hệ thống sẽ đổi kích thước hoạt động cho phù hợp với thao tác của người dùng, cũng như đưa ra sự thay đổi về cấu hình khi cần thiết. Nếu ứng dụng bị chậm trễ trong việc vẽ trong các vùng mới hiển thị, tạm thời lấp đầy các vùng đó bằng màu được chỉ định bởi windowBackground hoặc theo mặc định Thuộc tính kiểu windowBackgroundFallback.

Quyền truy cập tài nguyên độc quyền

Để hỗ trợ tính năng Tiếp tục nhiều lần, hãy sử dụng Phương thức gọi lại trong vòng đời onTopResumedActivityChanged().

Lệnh gọi lại được gọi khi một hoạt động nhận hoặc mất hoạt động hàng đầu đã tiếp tục vị trí. Điều này rất quan trọng khi một hoạt động sử dụng tài nguyên singleton dùng chung, chẳng hạn như micrô hoặc camera:

override fun
onTopResumedActivityChanged(topResumed: Boolean) { if (topResumed) { // Top
resumed activity. // Can be a signal to re-acquire exclusive resources. } else {
// No longer the top resumed activity. } }

Lưu ý rằng ứng dụng có thể mất đi tài nguyên vì các lý do khác, chẳng hạn như việc xoá bỏ một phần cứng được chia sẻ.

Trong mọi trường hợp, một ứng dụng phải xử lý linh hoạt các sự kiện và những thay đổi về trạng thái có ảnh hưởng đến các tài nguyên có sẵn.

Đối với các ứng dụng dùng máy ảnh: CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged() sẽ đưa ra gợi ý rằng có thể đến lúc thích hợp để truy cập vào camera. Phương thức này có trên Android 10 (API cấp 29).

Xin lưu ý rằng resizeableActivity=false không đảm bảo rằng máy ảnh dành riêng cho bạn vì các ứng dụng khác dùng máy ảnh có thể mở trên màn hình khác.

Hình 2. Máy ảnh ở chế độ nhiều cửa sổ.

Ứng dụng của bạn không cần phải giải phóng máy ảnh khi mất tiêu điểm. Ví dụ: bạn có thể muốn tiếp tục xem trước của máy ảnh trong khi người dùng tương tác với ứng dụng được tiếp tục ở trên cùng mới được lấy tiêu điểm. Ứng dụng của bạn có thể duy trì chạy máy ảnh khi đó không phải là ứng dụng được tiếp tục trên cùng, nhưng phải xử lý hãy ngắt kết nối hộp sạc đúng cách. Khi ứng dụng được tiếp tục trên cùng muốn sử dụng camera có thể mở và ứng dụng của bạn sẽ mất quyền truy cập. Ứng dụng của bạn có thể mở lại khi ứng dụng lấy lại tiêu điểm.

Sau khi một ứng dụng nhận được CameraDevice.StateCallback#onDisconnected() các lệnh gọi tiếp theo trên thiết bị máy ảnh sẽ gửi một CameraAccessException.

Chế độ Nhiều màn hình

Android 10 (API cấp 29) hỗ trợ các hoạt động trên màn hình phụ. Nếu một hoạt động đang chạy trên một thiết bị có chế độ nhiều màn hình, người dùng có thể di chuyển hoạt động đó từ màn hình này sang màn hình khác. Chế độ Tiếp tục nhiều lần áp dụng cho tình huống nhiều màn hình; có thể nhận được hoạt động đầu vào của người dùng .

Ứ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. Xem lớp ActivityOptions để biết thêm thông tin chi tiết.

Khi một hoạt động chuyển sang màn hình phụ, hoạt động đó có thể phải 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 xử lý thay đổi về cấu hình, hoạt động được thông báo trong onConfigurationChanged(); nếu không, hoạt động sẽ được chạy lại.

Một hoạt động phải kiểm tra màn hình hiện tại trong onCreate()onConfigurationChanged() nếu xử lý thay đổi cấu hình. Đảm bảo cập nhật các tài nguyên và bố cục khi màn hình thay đổi.

Nếu chế độ chạy đã chọn cho một hoạt động cho phép nhiều thực thể, thì trên màn hình phụ có thể tạo một thực thể mới của hoạt động. Cả hai hoạt động được tiếp tục cùng một lúc.

Hình 3.Nhiều thực thể của một hoạt động trên nhiều màn hình.

Bạn cũng có thể muốn đọc về các API nhiều màn hình đã được giới thiệu trong Android 8.0.

Hoạt động so với bối cảnh của ứng dụng

Việc sử dụng bối cảnh phù hợp là rất quan trọng trong chế độ 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 chỉ số cửa sổ của . Bạn phải luôn sử dụng ngữ cảnh hoạt động (hoặc một giao diện người dùng khác) ngữ cảnh) để nhận thông tin về cửa sổ hoặc màn hình hiện tại. Việc này cũng ảnh hưởng đến một số API hệ thống có sử dụng thông tin theo ngữ cảnh (ví dụ: xem Tổng quan về thông báo ngắn).

Cấu hình cửa sổ hoạt động và màn hình chính sẽ khai báo tài nguyên và bối cảnh. Nhận màn hình hiển thị hiện tại như sau:

val activityDisplay = activity.getDisplay()

Nhận các chỉ số của cửa sổ hoạt động hiện tại:

val windowMetrics = activity.getWindowManager().getCurrentWindowMetrics()

Nhận các chỉ số tối đa của cửa sổ đối với cấu hình hệ thống hiện tại:

val maximumWindowMetrics = activity.getWindowManager().getMaximumWindowMetrics()

Các chỉ số cửa sổ tối đa là để tính toán, lựa chọn bố cục hoặc xác định trước kích thước tài nguyên để tìm nạp trước. Việc tìm nạp trước này trong onCreate() cho phép bạn đưa ra các quyết định có liên quan trước lần chuyển bố cục đầu tiên. Không nên sử dụng các chỉ số này để bố trí các yếu tố xem cụ thể; thay vào đó, hãy sử dụng thông tin từ đối tượng Configuration.

Vết cắt trên màn hình

Các thiết bị có thể gập lại có thể có các đặc điểm hình học khác nhau khi gấp và mở. Để tránh các vấn đề về vết cắt, hãy xem bài viết Hỗ trợ vết cắt trên màn hình.

Màn hình phụ

Bạn có thể xem các màn hình có sẵn từ dịch vụ hệ thống DisplayManager:

val displayManager =
getSystemService(Context.DISPLAY_SERVICE) as DisplayManager val displays =
displayManager.getDisplays()

Sử dụng lớp Display để nhận thông tin về một màn hình cụ thể, chẳng hạn như như kích thước màn hình hoặc cờ cho biết màn hình có an toàn hay không. Tuy nhiên, đừng cho rằng kích thước hiển thị sẽ giống như khu vực hiển thị được phân bổ cho ứng dụng của bạn. Hãy nhớ rằng ở chế độ nhiều cửa sổ, thì ứng dụng của bạn chiếm một phần màn hình.

Xác định xem một hoạt động có thể chạy trên một màn hình hay không:

val activityManager =
getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val
activityAllowed = activityManager.isActivityStartAllowedOnDisplay(context,
displayId, intent)

Sau đó, chạy hoạt động trên màn hình:

val options = ActivityOptions.makeBasic()
options.setLaunchDisplayId(targetDisplay.displayId) startActivity(intent,
options.toBundle())

Hỗ trợ chế độ nhiều màn hình

Android hỗ trợ chế độ nhiều màn hình cho các bàn phím phần mềm, các hình nền và các trình chạy.

Bàn phím phần mềm

Một bàn phím có thể hiển thị trên màn hình phụ nếu màn hình được định cấu hình để hỗ trợ các thành phần trang trí của hệ thống. Trình chỉnh sửa phương thức nhập sẽ tự động xuất hiện nếu một trường văn bản yêu cầu dữ liệu nhập trên màn hình đó.

Hình 4. Bàn phím trên màn hình phụ.

Hình nền

Trong Android 10 (API cấp 29), màn hình phụ có thể có hình nền. Chiến lược phát hành đĩa đơn khung sẽ tạo một phiên bản WallpaperService.Engine riêng cho mỗi màn hình. Đảm bảo bề mặt của mỗi động cơ được vẽ độc lập. Nhà phát triển có thể tải nội dung bằng cách sử dụng ngữ cảnh hiển thị trong WallpaperService.Engine#getDisplayContext(). Ngoài ra, hãy đảm bảo rằng Tệp WallpaperInfo.xml thiết lập android:supportsMultipleDisplays="true".

Hình 5. Hình nền trên điện thoại và màn hình phụ.

Trình chạy

Danh mục bộ lọc ý định mới, SECONDARY_HOME, cung cấp một hoạt động dành riêng cho màn hình phụ. Các thực thể của hoạt động được sử dụng trên tất cả các màn hình để hỗ trợ các thành phần trang trí hệ thống, một thực thể dành cho mỗi màn hình.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

Hoạt động phải có một chế độ chạy cho phép tồn tại nhiều thực thể và có thể thích ứng với nhiều kích thước màn hình. Chế độ chạy không được là singleInstance hoặc singleTask.

Ví dụ: hoạt động triển khai AOSP của Launcher3 hỗ trợ một Hoạt động trên SECONDARY_HOME.

Hình 6. Trình chạy Material Design trên điện thoại.
Hình 7. Trình chạy Material Design trên màn hình phụ.

Chỉ số cửa sổ

Android 11 (API cấp 30) đã ra mắt các phương thức WindowManager sau đây để cung cấp các giới hạn của ứng dụng chạy ở chế độ nhiều cửa sổ:

Phương thức thư viện Jetpack WindowManager computeCurrentWindowMetrics()computeMaximumWindowMetrics() có chức năng tương tự tương ứng nhưng có khả năng tương thích ngược với API cấp 14.

Để lấy chỉ số của các màn hình khác với màn hình hiện tại, hãy làm như sau (như minh hoạ trong đoạn mã):

  • Tạo một ngữ cảnh hiển thị
  • Tạo ngữ cảnh cửa sổ cho màn hình
  • Nhận WindowManager của ngữ cảnh cửa sổ
  • Nhận WindowMetrics khu vực hiển thị tối đa có sẵn cho ứng dụng

val windowMetrics =
context.createDisplayContext(display)
.createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null)
.getSystemService(WindowManager::class.java) .maximumWindowMetrics

Các phương thức ngừng hoạt động

Các phương thức Display getSize()getMetrics() đã ngừng hoạt động trong API cấp 30 và ưu tiên các phương thức WindowManager mới.

Android 12 (API cấp 31) ngừng sử dụng các phương thức Display getRealSize()getRealMetrics() và cập nhật hành vi của mình để phù hợp hơn với của getMaximumWindowMetrics().

Cấu hình chế độ nhiều cửa sổ

Nếu ứng dụng của bạn nhắm đến Android 7.0 (API cấp 24) trở lên, bạn có thể định cấu hình cách cũng như liệu các hoạt động của ứng dụng có hỗ trợ chế độ nhiều cửa sổ hay không. Bạn có thể đặt trong tệp kê khai để kiểm soát cả kích thước và bố cục. Hoạt động gốc cài đặt thuộc tính áp dụng cho tất cả hoạt động trong ngăn xếp tác vụ. Ví dụ: nếu hoạt động gốc có android:resizeableActivity="true", thì tất cả các hoạt động trong ngăn xếp tác vụ có thể đổi kích thước. Trên một số thiết bị lớn hơn, chẳng hạn như Chromebook, ứng dụng của bạn có thể chạy trong một cửa sổ có thể đổi kích thước ngay cả khi bạn chỉ định android:resizeableActivity="false". Nếu việc này khiến ứng dụng gặp lỗi, bạn có thể sử dụng bộ lọc trên Google Play để hạn chế tính khả dụng của ứng dụng trên các thiết bị như vậy.

Android 12 (API cấp 31) mặc định ở chế độ nhiều cửa sổ. Trên màn hình lớn (lớp kích thước cửa sổ trung bình hoặc mở rộng), tất cả các ứng dụng đều chạy ở chế độ nhiều cửa sổ bất kể cấu hình ứng dụng là gì. Trên màn hình nhỏ, hệ thống sẽ kiểm tra minWidth, minHeightresizeableActivity của hoạt động để xác định xem hoạt động có thể chạy ở chế độ nhiều cửa sổ hay không.

resizeableActivity

Đặt thuộc tính này trong <activity> hoặc <application> của tệp kê khai để bật hoặc tắt chế độ nhiều cửa sổ đối với API cấp 30 trở xuống:

<application
  android:name=".MyActivity"
  android:resizeableActivity=["true" | "false"] />;

Nếu bạn đặt thuộc tính này thành true, thì hoạt động có thể được chạy ở chế độ chia đôi màn hình và chế độ hình dạng tuỳ ý. Nếu bạn đặt thuộc tính thành false, hoạt động sẽ không hỗ trợ chế độ nhiều cửa sổ. Nếu giá trị này là false và người dùng cố gắng khởi chạy hoạt động ở chế độ nhiều cửa sổ, hoạt động chiếm toàn bộ màn hình.

Nếu ứng dụng của bạn nhắm đến API cấp 24 trở lên, nhưng bạn không chỉ định giá trị cho thuộc tính này, giá trị của thuộc tính mặc định là true.

Nếu ứng dụng của bạn nhắm đến API cấp 31 trở lên, thì thuộc tính này sẽ hoạt động theo cách khác trên màn hình nhỏ và lớn:

  • Màn hình lớn (lớp kích thước cửa sổ trung bình hoặc mở rộng): Tất cả ứng dụng hỗ trợ chế độ nhiều cửa sổ. Thuộc tính này cho biết liệu một hoạt động có thể thay đổi kích thước. Nếu là resizeableActivity="false", ứng dụng sẽ được đưa vào chế độ tương thích khi cần để phù hợp với kích thước màn hình.
  • Màn hình nhỏ (lớp kích thước cửa sổ nhỏ gọn): Nếu resizeableActivity="true" và chiều rộng tối thiểu và chiều cao tối thiểu của hoạt động nằm trong yêu cầu nhiều cửa sổ, hoạt động sẽ hỗ trợ chế độ nhiều cửa sổ . Nếu là resizeableActivity="false", thì hoạt động sẽ không hỗ trợ chế độ nhiều cửa sổ bất kể chiều rộng và chiều cao tối thiểu của hoạt động là như thế nào.

supportsPictureInPicture

Đặt thuộc tính này trong nút <activity> của tệp kê khai để cho biết liệu hoạt động sẽ hỗ trợ chế độ hình trong hình.

<activity
  android:name=".MyActivity"
  android:supportsPictureInPicture=["true" | "false"] />

configChanges

Để tự xử lý các thay đổi về cấu hình ở chế độ nhiều cửa sổ, chẳng hạn như khi người dùng đổi kích thước cửa sổ, hãy thêm thuộc tính android:configChanges vào ứng dụng nút tệp kê khai <activity> với ít nhất các giá trị sau:

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize | smallestScreenSize
      | screenLayout | orientation" />

Sau khi thêm android:configChanges, hoạt động và các mảnh của bạn sẽ nhận được một lệnh gọi lại đến onConfigurationChanged() thay vì bị huỷ và đã tạo lại. Sau đó, bạn có thể cập nhật chế độ xem, tải lại tài nguyên và thực hiện các thao tác khác nếu cần.

<layout>

Trên Android 7.0 (API cấp 24) trở lên, phần tử tệp kê khai <layout> hỗ trợ một số thuộc tính ảnh hưởng đến cách hoạt động của một hoạt động trong chế độ nhiều cửa sổ chế độ:

  • android:defaultHeight, android:defaultWidth: Chiều cao và chiều rộng mặc định của hoạt động khi khởi chạy ở chế độ hình dạng tuỳ ý.

  • android:gravity: Vị trí đầu tiên của hoạt động khi khởi chạy trong chế độ biểu mẫu tuỳ ý. Hãy xem lớp Gravity để biết các giá trị phù hợp.

  • android:minHeight, android:minWidth: Chiều cao tối thiểu và chiều rộng tối thiểu cho hoạt động ở cả chế độ chia đôi màn hình và chế độ hình dạng tuỳ ý. Nếu người dùng di chuyển bộ chia ở chế độ chia đôi màn hình để làm cho một hoạt động nhỏ hơn giá trị tối thiểu được chỉ định, hệ thống sẽ cắt hoạt động theo kích thước mà người dùng yêu cầu.

Đoạn mã sau đây cho biết cách chỉ định kích thước và vị trí mặc định của hoạt động cũng như kích thước tối thiểu của hoạt động đó khi được hiển thị ở chế độ hình dáng tuỳ ý:

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end|..."
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

Chế độ nhiều cửa sổ trong thời gian chạy

Kể từ Android 7.0, hệ thống sẽ cung cấp chức năng hỗ trợ các ứng dụng có thể chạy ở chế độ nhiều cửa sổ.

Các tính năng bị tắt trong chế độ nhiều cửa sổ

Ở chế độ nhiều cửa sổ, Android có thể tắt hoặc bỏ qua các tính năng không áp dụng được cho hoạt động đang chia sẻ màn hình thiết bị với các hoạt động hoặc ứng dụng khác.

Ngoài ra, một số tuỳ chọn tuỳ chỉnh Giao diện người dùng hệ thống bị tắt. Ví dụ: các ứng dụng không thể ẩn thanh trạng thái nếu đang chạy ở chế độ nhiều cửa sổ (xem Kiểm soát chế độ hiển thị giao diện người dùng hệ thống).

Hệ thống sẽ bỏ qua các thay đổi đối với thuộc tính android:screenOrientation.

Các truy vấn và lệnh gọi lại của chế độ nhiều cửa sổ

Lớp Activity cung cấp các phương thức sau để hỗ trợ chế độ nhiều cửa sổ chế độ:

  • isInMultiWindowMode(): Cho biết hoạt động có nằm trong chế độ nhiều cửa sổ.

  • isInPictureInPictureMode(): Cho biết hoạt động có nằm trong chế độ hình trong hình.

  • onMultiWindowModeChanged(): Hệ thống gọi phương thức này bất cứ khi nào hoạt động chuyển sang hoặc thoát khỏi chế độ nhiều cửa sổ. Hệ thống truyền phương thức giá trị true nếu hoạt động chuyển sang chế độ nhiều cửa sổ hoặc false nếu hoạt động sẽ rời khỏi chế độ nhiều cửa sổ.

  • onPictureInPictureModeChanged(): Hệ thống sẽ gọi phương thức này bất cứ khi nào hoạt động chuyển sang hoặc bị thoát khỏi chế độ hình trong hình. Hệ thống truyền phương thức có giá trị true nếu hoạt động chuyển sang chế độ hình trong hình false nếu hoạt động đang thoát khỏi chế độ hình trong hình.

Lớp Fragment sẽ hiển thị phiên bản của nhiều phương thức trong số này; ví dụ: Fragment.onMultiWindowModeChanged().

Chế độ Hình trong hình

Để đưa một hoạt động vào chế độ hình trong hình, hãy gọi enterPictureInPictureMode() Phương thức này không có hiệu lực nếu thiết bị có không hỗ trợ chế độ hình trong hình. Để biết thêm thông tin, hãy xem bài viết Thêm video bằng hình trong hình (PiP).

Hoạt động mới ở chế độ nhiều cửa sổ

Khi khởi chạy một hoạt động mới, bạn có thể cho biết rằng hoạt động mới đó sẽ được hiển thị bên cạnh quảng cáo hiện tại nếu có thể. Sử dụng cờ ý định FLAG_ACTIVITY_LAUNCH_ADJACENT cho hệ thống biết phải tạo hoạt động mới trong một cửa sổ liền kề, vì vậy hai hoạt động sẽ chia sẻ màn hình. Chiến lược phát hành đĩa đơn hệ thống sẽ cố gắng hết sức để thực hiện điều này, nhưng không đảm bảo sẽ xảy ra.

Nếu thiết bị ở chế độ hình dạng tuỳ ý và bạn đang khởi chạy một hoạt động mới, bạn có thể chỉ định phương diện và vị trí màn hình của hoạt động mới bằng cách gọi ActivityOptions.setLaunchBounds(). Phương thức này không có hiệu lực nếu thiết bị không ở chế độ nhiều cửa sổ.

Ở API cấp 30 trở xuống, nếu bạn khởi chạy một hoạt động trong ngăn xếp tác vụ, hoạt động thay thế hoạt động trên màn hình, kế thừa tất cả hoạt động ở chế độ nhiều cửa sổ các thuộc tính. Nếu bạn muốn chạy hoạt động mới dưới dạng một cửa sổ riêng trong chế độ nhiều cửa sổ, bạn phải chạy chế độ này trong ngăn xếp tác vụ mới.

Android 12 (API cấp 31) cho phép các ứng dụng phân tách một cửa sổ thao tác của ứng dụng thành nhiều hoạt động. Bạn sẽ quyết định cách ứng dụng hiển thị các hoạt động (toàn màn hình, hiển thị cạnh nhau hoặc xếp chồng lên nhau) bằng cách tạo một tệp XML hoặc thực hiện lệnh gọi API Jetpack WindowManager.

Kéo và thả

Người dùng có thể kéo và thả dữ liệu từ một hoạt động sang một hoạt động khác trong khi hai hoạt động đang chia sẻ màn hình. (Trước Android 7.0, người dùng chỉ có thể kéo và thả dữ liệu trong một hoạt động). Để nhanh chóng thêm hỗ trợ cho việc chấp nhận bị thả nội dung, hãy xem API DropHelper. Để thực hiện thao tác kéo và thả toàn diện hướng dẫn, hãy xem Bật tính năng kéo và thả.

Nhiều phiên bản

Mỗi hoạt động gốc có một tác vụ riêng, chạy trên một quá trình riêng và hiển thị trong cửa sổ riêng. Để khởi chạy một thực thể mới của ứng dụng trong một cửa sổ riêng, bạn có thể bắt đầu các hoạt động mới bằng cờ FLAG_ACTIVITY_NEW_TASK. Bạn có thể kết hợp cửa sổ này với một số thuộc tính nhiều cửa sổ để yêu cầu một vị trí cụ thể cho cửa sổ mới. Ví dụ: ứng dụng mua sắm có thể hiển thị nhiều cửa sổ để so sánh sản phẩm.

Android 12 (API cấp 31) cho phép bạn khởi chạy 2 thực thể của một hoạt động cạnh nhau trong cùng một cửa sổ tác vụ.

Nếu bạn muốn cho phép người dùng bắt đầu một phiên bản khác của ứng dụng từ trình chạy ứng dụng hoặc thanh tác vụ, hãy đảm bảo rằng Hoạt động của trình chạy đặt android:resizeableActivity="true" và không sử dụng chế độ chạy để ngăn chặn việc xuất hiện nhiều thực thể. Ví dụ: một hoạt động singleInstancePerTask có thể được tạo thực thể nhiều lần trong các tác vụ khác nhau khi Đã đặt FLAG_ACTIVITY_MULTIPLE_TASK hoặc FLAG_ACTIVITY_NEW_DOCUMENT.

Đừng nhầm lẫn bố cục nhiều phiên bản với một bố cục nhiều bảng điều khiển, chẳng hạn như danh sách-chi tiết bản trình bày sử dụng SlidingPaneLayout, chạy bên trong một cửa sổ.

Lưu ý rằng khi nhiều phiên bản đang chạy trong các cửa sổ riêng biệt trên một thiết bị gập, một hoặc nhiều phiên bản có thể được gửi tới nền nếu tư thế của thiết bị đó thay đổi. Ví dụ: giả sử một thiết bị được mở ra và có hai thực thể ứng dụng đang chạy trong hai cửa sổ ở hai bên nếp gấp màn hình. Khi thiết bị gập lại, một trong các thực thể đó có thể bị chấm dứt thay vì cố gắng điều chỉnh các cửa sổ cho cả hai phiên bản trên màn hình nhỏ hơn.

Xác minh chế độ nhiều cửa sổ

Dù ứng dụng của bạn có nhắm đến API cấp 24 trở lên hay không, bạn cũng nên xác minh cách ứng dụng đó hoạt động ở chế độ nhiều cửa sổ trong trường hợp người dùng cố gắng mở chế độ này ở chế độ nhiều cửa sổ trên thiết bị chạy Android 7.0 trở lên.

Kiểm tra thiết bị

Các thiết bị chạy Android 7.0 (API cấp 24) trở lên có hỗ trợ chế độ nhiều cửa sổ.

API cấp 23 trở xuống

Khi người dùng cố gắng sử dụng ứng dụng ở chế độ nhiều cửa sổ, hệ thống sẽ buộc đổi kích thước ứng dụng, trừ khi ứng dụng khai báo một hướng cố định.

Nếu ứng dụng không khai báo một hướng cố định, bạn nên khởi chạy ứng dụng trên một thiết bị chạy Android 7.0 trở lên và cố gắng đặt ứng dụng đó vào chế độ chia đôi màn hình. Xác minh rằng trải nghiệm người dùng có thể chấp nhận được khi ứng dụng bị buộc đổi kích thước.

Nếu ứng dụng khai báo một hướng cố định, bạn nên tìm cách đặt ứng dụng ở chế độ nhiều cửa sổ. Xác minh rằng khi bạn làm như vậy thì ứng dụng sẽ ở chế độ toàn màn hình.

API cấp 24 đến 30

Nếu ứng dụng của bạn nhắm đến các API cấp 24 đến 30 và không tắt tính năng hỗ trợ chế độ nhiều cửa sổ, hãy xác minh hành vi sau đây ở cả chế độ chia đôi màn hình và chế độ hình dạng tùy ý:

  • Khởi chạy ứng dụng ở chế độ toàn màn hình, sau đó chuyển sang chế độ nhiều cửa sổ bằng cách nhấn và giữ nút Recents (Gần đây). Xác minh rằng ứng dụng chuyển đúng cách.

  • Khởi chạy ứng dụng ngay ở chế độ nhiều cửa sổ và xác minh rằng ứng dụng khởi chạy đúng cách. Bạn có thể khởi chạy một ứng dụng ở chế độ nhiều cửa sổ bằng cách nhấn nút Recents (Gần đây), sau đó nhấn và giữ thanh tiêu đề của ứng dụng và kéo ứng dụng đến một trong các vùng được đánh dấu trên màn hình.

  • Đổi kích thước ứng dụng của bạn ở chế độ chia đôi màn hình bằng cách kéo phần chia màn hình. Xác minh ứng dụng đổi kích thước mà không gặp sự cố và các phần tử giao diện người dùng cần thiết hiển thị.

  • Nếu bạn đã chỉ định kích thước tối thiểu cho ứng dụng, hãy thử đổi kích thước để kích thước cửa sổ nhỏ hơn các kích thước đó. Xác minh rằng bạn không thể đổi kích thước ứng dụng thành nhỏ hơn kích thước tối thiểu được chỉ định thứ nguyên.

  • Thông qua tất cả các kiểm thử, hãy xác minh rằng hiệu năng của ứng dụng ở mức chấp nhận được. Cho xác minh rằng việc cập nhật giao diện người dùng không có độ trễ quá lâu sau khi ứng dụng được đổi kích thước.

API cấp 31 trở lên

Nếu ứng dụng của bạn nhắm đến API cấp 31 trở lên và chiều rộng tối thiểu của hoạt động chính và chiều cao tối thiểu đều nhỏ hơn hoặc bằng kích thước tương ứng của khu vực hiển thị hiện có, xác minh tất cả các hành vi được liệt kê đối với API cấp 24 đến hết 30.

Danh sách kiểm thử

Để xác minh hiệu năng của ứng dụng ở chế độ nhiều cửa sổ, hãy thử các thao tác sau. Bạn nên thử các thao tác này ở cả chế độ chia đôi màn hình và chế độ hình dạng tuỳ ý, trừ trường hợp có lưu ý khác.

  • Chuyển vào và rời khỏi chế độ nhiều cửa sổ.

  • Chuyển từ ứng dụng của bạn sang ứng dụng khác và xác minh rằng ứng dụng đó hoạt động đúng cách khi quảng cáo hiển thị nhưng không hoạt động. Ví dụ: nếu ứng dụng của bạn là đang phát video, hãy xác minh rằng video tiếp tục phát khi người dùng tương tác với ứng dụng khác.

  • Ở chế độ chia đôi màn hình, hãy thử di chuyển trình chia màn hình để làm cho ứng dụng của bạn vừa hoạt động vừa lớn hơn và nhỏ hơn. Hãy thử các thao tác này ở cả bên cạnh và một thao tác ở trên các cấu hình khác. Xác minh rằng ứng dụng không gặp sự cố, điều cần thiết chức năng rõ ràng và thao tác đổi kích thước không mất quá nhiều thời gian.

  • Thực hiện một số thao tác đổi kích thước một cách liên tiếp. Xác minh rằng ứng dụng của bạn không gặp sự cố hoặc rò rỉ bộ nhớ. Trình phân tích bộ nhớ của Android Studio cung cấp thông tin về mức sử dụng bộ nhớ của ứng dụng (xem bài viết Kiểm tra bộ nhớ của ứng dụng bằng Trình phân tích bộ nhớ).

  • Dùng ứng dụng của bạn như bình thường trong một số cấu hình cửa sổ, và xác minh rằng ứng dụng hoạt động đúng cách. Xác minh rằng văn bản có thể đọc được và Các phần tử trên giao diện người dùng không quá nhỏ để tương tác.

Đã tắt tính năng hỗ trợ nhiều cửa sổ

Ở API cấp 24 đến 30, nếu bạn tắt tính năng hỗ trợ nhiều cửa sổ bằng cách thiết lập android:resizeableActivity="false" thân mến, bạn nên chạy ứng dụng của mình trên một thiết bị chạy Android 7.0 đến 11 và cố gắng đặt ứng dụng ở chế độ chia đôi màn hình và chế độ hình dạng tuỳ ý. Xác minh rằng khi bạn làm vậy, ứng dụng vẫn ở chế độ toàn màn hình .

Tài nguyên khác

Để biết thêm thông tin về tính năng hỗ trợ chế độ nhiều cửa sổ trong Android, hãy xem:

Đề xuất cho bạn * Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt * Chế độ tương thích với thiết bị * Hỗ trợ khả năng đổi kích thước màn hình lớn * Xử lý các thay đổi về cấu hình