Quản lý cửa sổ

ChromeOS hỗ trợ các ứng dụng Android ở nhiều cửa sổ. Hệ thống kết xuất các ứng dụng vào vùng chứa cửa sổ có kích thước được xác định theo hệ số hình dạng của thiết bị, như trong hình 1.

Hình 1. Cửa sổ ứng dụng trên các thiết bị khác nhau.

Điều quan trọng là bạn phải thiết kế bố cục phù hợp với nhiều kích thước màn hình. Nếu bạn tuân theo các nguyên tắc của Android để hỗ trợ nhiều kích thước màn hình, thì ứng dụng của bạn cũng sẽ hoạt động tốt khi chạy trên ChromeOS.

Trang này cho biết cách đảm bảo cửa sổ ứng dụng khởi chạy chính xác, đổi kích thước mượt mà và hiển thị tất cả nội dung của cửa sổ khi kích thước thay đổi.

Kích thước phát hành ban đầu

Ứng dụng có thể yêu cầu kích thước khởi chạy ban đầu theo các cách sau:

  • Chỉ sử dụng kích thước khởi chạy trong môi trường máy tính để bàn. Điều này giúp trình quản lý cửa sổ cung cấp cho bạn các giới hạn và hướng thích hợp. Để cho biết một lựa chọn ưu tiên khi dùng ở chế độ máy tính, hãy thêm các thẻ meta sau vào <activity>:
<meta-data android:name="WindowManagerPreference:FreeformWindowSize"
           android:value="[phone|tablet|maximize]" />
<meta-data android:name="WindowManagerPreference:FreeformWindowOrientation"
           android:value="[portrait|landscape]" />
  • Sử dụng giới hạn khởi chạy tĩnh. Sử dụng <layout> bên trong mục kê khai của hoạt động để chỉ định kích thước bắt đầu "cố định", như trong ví dụ sau:
<layout android:defaultHeight="500dp"
            android:defaultWidth="600dp"
            android:gravity="top|end"
            android:minHeight="450dp"
            android:minWidth="300dp" />
  • Sử dụng giới hạn khởi chạy động. Một hoạt động có thể tạo và sử dụng ActivityOptions.setLaunchBounds(Rect) khi tạo một hoạt động mới. Bằng cách chỉ định một hình chữ nhật trống, ứng dụng của bạn có thể được tối đa hoá.

Đổi kích thước cửa sổ

Trong ChromeOS, người dùng có thể đổi kích thước cửa sổ của ứng dụng theo cách thông thường: bằng cách kéo góc dưới bên phải, như minh hoạ trong hình 2.

Hình 2. Cửa sổ ứng dụng có thể đổi kích thước.

Có hai lựa chọn để xử lý việc đổi kích thước cửa sổ khi sử dụng lớp View:

  • Phản hồi linh hoạt các thay đổi về cấu hình bằng cách gọi onConfigurationChanged(..). Ví dụ: bạn có thể thêm android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" vào tệp kê khai của hoạt động. Để biết thêm thông tin về cách xử lý các thay đổi về cấu hình, hãy đọc bài viết Xử lý các thay đổi về cấu hình.
  • Để hệ thống khởi động lại hoạt động. Trong trường hợp này, hãy triển khai onSaveInstanceState và sử dụng thành phần cấu trúc ViewModel để khôi phục trạng thái đã lưu trước đó.

Khi dùng Jetpack Compose, hành vi đổi kích thước phụ thuộc vào cách định cấu hình hoạt động của bạn. Nếu xử lý các thay đổi một cách linh động, quá trình kết hợp lại sẽ được kích hoạt khi kích thước cửa sổ thay đổi. Nếu hoạt động được hệ thống bắt đầu lại, thì quá trình kết hợp ban đầu sẽ diễn ra sau khi khởi động lại. Dù bằng cách nào, điều quan trọng là bạn phải tạo bố cục Compose thích ứng với việc thay đổi kích thước cửa sổ. Đừng giả định kích thước cố định.

Kích thước cửa sổ

Yêu cầu các hoạt động đọc kích thước cửa sổ mỗi khi bắt đầu và sắp xếp nội dung theo cấu hình hiện tại.

Để xác định cấu hình hiện tại, hãy gọi getResources().getConfiguration() trên hoạt động hiện tại. Đừng sử dụng cấu hình của hoạt động ở chế độ nền hoặc tài nguyên hệ thống. Hoạt động trong nền không có kích thước và cấu hình hệ thống có thể chứa nhiều cửa sổ có kích thước và hướng xung đột với nhau, do đó không thể trích xuất dữ liệu hữu dụng nào.

Lưu ý rằng kích thước cửa sổ và kích thước màn hình không giống nhau. Để biết kích thước cửa sổ trong DP, hãy sử dụng Activity.getResources().getConfiguration().screenWidthActivity.getResources().getConfiguration().screenHeight. Bạn có thể không bao giờ cần sử dụng kích thước màn hình.

Giới hạn nội dung

Giới hạn nội dung của một cửa sổ có thể thay đổi sau khi đổi kích thước. Ví dụ: khu vực trong cửa sổ mà ứng dụng sử dụng có thể thay đổi nếu cửa sổ quá lớn không thể vừa với màn hình. Hãy làm theo các nguyên tắc sau:

  • Các ứng dụng dùng quy trình bố cục của Android sẽ tự động được bố trí trong không gian có sẵn.
  • Các ứng dụng gốc cần đọc khu vực có sẵn và theo dõi các thay đổi về kích thước để tránh có các thành phần trên giao diện người dùng không thể truy cập. Gọi các phương thức sau để xác định kích thước ban đầu hiện có cho nền tảng này:

    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()

    Có thể thực hiện việc giám sát liên tục bằng cách sử dụng đối tượng tiếp nhận dữ liệu:

    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • Thêm trình nghe vào view.addOnLayoutChangeListener(findViewById(android.R.id.content))

    Nếu ứng dụng đang điều chỉnh tỷ lệ trước hình minh hoạ, hãy thực hiện việc này mỗi khi độ phân giải thay đổi.

Đổi kích thước mẫu tự do

ChromeOS cho phép tuỳ ý đổi kích thước mọi cửa sổ: người dùng có thể thay đổi chiều rộng, chiều cao và vị trí của cửa sổ trên màn hình. Nhiều ứng dụng Android được viết mà không lưu ý đến việc đổi kích thước biểu mẫu tuỳ ý. Hãy cân nhắc những vấn đề sau:

  • Vị trí màn hình có thể thay đổi. Luôn sử dụng hệ thống để thực hiện các phép biến đổi toạ độ giữa các cửa sổ và màn hình giữa các cửa sổ.
  • Nếu bạn đang sử dụng hệ thống khung hiển thị của Android, bố cục cửa sổ của bạn sẽ tự động thay đổi khi kích thước của cửa sổ thay đổi.
  • Nếu không sử dụng hệ thống khung hiển thị và chiếm đoạt nền tảng, thì ứng dụng của bạn phải tự xử lý các thay đổi về kích thước.
  • Đối với các ứng dụng gốc, hãy sử dụng thành phần mLastContent hoặc sử dụng khung hiển thị nội dung để xác định kích thước ban đầu.
  • Khi ứng dụng đang chạy, hãy theo dõi các sự kiện onContentRectChangedNative hoặc onGlobalLayout để phản ứng với các thay đổi về kích thước.
  • Khi kích thước của ứng dụng thay đổi, hãy điều chỉnh kích thước hoặc tải lại bố cục, hình minh hoạ và cập nhật các khu vực nhập.

Chế độ toàn màn hình

Chế độ toàn màn hình hoạt động giống như trên Android phiên bản gốc. Nếu cửa sổ không che toàn màn hình, thì các yêu cầu sàng lọc toàn bộ (ẩn tất cả các phần tử trên giao diện người dùng hệ thống) sẽ bị bỏ qua. Khi ứng dụng được phóng to, các phương thức, bố cục và chức năng thông thường sẽ được thực hiện ở chế độ toàn màn hình. Các thành phần trên giao diện người dùng hệ thống (thanh điều khiển cửa sổ và kệ) sẽ bị ẩn.

Hướng màn hình

Hướng phổ biến nhất của ứng dụng Android là dọc, vì đó là cách giữ hầu hết các điện thoại. Mặc dù dọc phù hợp với điện thoại, nhưng với máy tính xách tay và máy tính bảng, nhưng chế độ dọc lại được ưu tiên hơn. Để có được kết quả tốt nhất cho ứng dụng của bạn, hãy cân nhắc việc hỗ trợ cả hai hướng.

Một số ứng dụng Android giả định rằng khi một thiết bị được giữ ở chế độ dọc, giá trị xoay là Surface.ROTATION_0. Điều này có thể đúng với hầu hết các thiết bị Android. Tuy nhiên, khi ứng dụng ở chế độ ARC nhất định, giá trị xoay cho hướng dọc có thể không phải là Surface.ROTATION_0.

Để nhận được giá trị xoay chính xác trong khi đọc gia tốc kế hoặc các cảm biến tương tự, hãy sử dụng phương thức Display.getRotation() và hoán đổi trục cho phù hợp.

Hướng và hoạt động gốc

Cửa sổ Chromebook bao gồm một ngăn xếp các cửa sổ hoạt động. Mỗi cửa sổ trong ngăn xếp có cùng kích thước và hướng.

Thay đổi đột ngột về hướng và kích thước gây nhầm lẫn trong môi trường máy tính để bàn. Trình quản lý cửa sổ Chromebook tránh việc này theo cách tương tự như chế độ song song của Android: hoạt động ở cuối ngăn xếp kiểm soát thuộc tính của tất cả hoạt động phía trên nó. Điều này có thể dẫn đến các tình huống không mong muốn, khi đó một hoạt động mới bắt đầu nằm dọc và không thể đổi kích thước lại trở thành hướng ngang và có thể đổi kích thước.

Chế độ thiết bị có ảnh hưởng như sau: ở chế độ máy tính bảng, hướng sẽ không bị khoá và mỗi cửa sổ giữ nguyên hướng riêng như bình thường trên Android.

Nguyên tắc hướng

Hãy làm theo các nguyên tắc sau để xử lý hướng:

  • Nếu bạn chỉ hỗ trợ một hướng, hãy thêm thông tin vào tệp kê khai để trình quản lý cửa sổ biết trước khi khởi động ứng dụng. Khi bạn chỉ định hướng, hãy chỉ định cả hướng cảm biến (nếu có thể). Chromebook thường là thiết bị có thể chuyển đổi và ứng dụng bị lật ngược là trải nghiệm kém cho người dùng.
  • Cố gắng duy trì với một hướng đã chọn. Tránh yêu cầu một hướng trong tệp kê khai và đặt một hướng khác theo phương thức lập trình sau này.
  • Hãy cẩn thận thay đổi hướng dựa trên kích thước cửa sổ. Người dùng có thể bị mắc kẹt trong cửa sổ có kích thước dọc nhỏ và không thể quay lại cửa sổ ngang lớn hơn.
  • Chrome có các chế độ điều khiển cửa sổ để chuyển đổi giữa tất cả các bố cục có sẵn. Bằng cách chọn đúng tuỳ chọn hướng, bạn có thể đảm bảo rằng người dùng có bố cục phù hợp sau khi khởi chạy ứng dụng. Nếu ứng dụng có chế độ dọc và ngang, hãy đặt ứng dụng mặc định thành ngang, nếu có thể. Sau khi đặt, tuỳ chọn này sẽ được ghi nhớ trên cơ sở từng ứng dụng.
  • Cố gắng tránh các thay đổi hướng không cần thiết. Ví dụ: nếu hướng hoạt động là hướng dọc, nhưng ứng dụng gọi setRequestedOrientation(LANDSCAPE) trong thời gian chạy, thì việc này sẽ dẫn đến việc đổi kích thước cửa sổ một cách không cần thiết, gây khó chịu cho người dùng và có thể khởi động lại ứng dụng mà ứng dụng không xử lý được. Bạn nên đặt hướng một lần, chẳng hạn như trong tệp kê khai và chỉ thay đổi hướng nếu cần.

Lưu ý khác

Dưới đây là một số điều khác cần cân nhắc khi làm việc với các ứng dụng Android trong ChromeOS:

  • Không gọi finish() trong phương thức onDestroy của hoạt động của bạn. Điều này khiến ứng dụng đóng khi đổi kích thước và không khởi động lại.
  • Không sử dụng các loại cửa sổ không tương thích, chẳng hạn như TYPE_KEYGUARDTYPE_APPLICATION_MEDIA.
  • Giúp hoạt động khởi động lại nhanh chóng bằng cách lưu các đối tượng đã được phân bổ trước đó vào bộ nhớ đệm.
  • Nếu bạn không muốn người dùng đổi kích thước ứng dụng, hãy chỉ định android:resizeableActivity=false trong tệp kê khai.
  • Hãy kiểm thử ứng dụng của bạn để đảm bảo ứng dụng xử lý các thay đổi về kích thước cửa sổ một cách thích hợp.