Thiết kế thích ứng/đáp ứng bằng khung hiển thị

Bố cục thích ứng mang lại trải nghiệm người dùng được tối ưu hoá bất kể kích thước màn hình. Triển khai các bố cục thích ứng để cho phép dựa trên chế độ xem để hỗ trợ mọi kích thước màn hình, hướng và các cấu hình, bao gồm cả các cấu hình có thể đổi kích thước như nhiều cửa sổ chế độ xem.

Thiết kế đáp ứng

Bước đầu tiên để hỗ trợ nhiều hệ số hình dạng thiết bị là tạo một bố cục thích ứng với các biến thể về lượng không gian hiển thị có sẵn cho ứng dụng của bạn.

ConstraintLayout

Cách tốt nhất để tạo bố cục thích ứng là sử dụng ConstraintLayout làm bố cục cơ sở cho giao diện người dùng. ConstraintLayout cho phép bạn chỉ định vị trí và kích thước của mỗi thành phần hiển thị theo mối quan hệ không gian với thành phần hiển thị trong bố cục. Sau đó, tất cả khung hiển thị có thể di chuyển và đổi kích thước cùng nhau dưới dạng các thay đổi về không gian hiển thị.

Cách dễ nhất để tạo bố cục với ConstraintLayout là sử dụng Layout Editor (Trình chỉnh sửa bố cục) trong Android Studio. Layout Editor cho phép bạn kéo các thành phần hiển thị mới vào bố cục, áp dụng các điều kiện ràng buộc tương ứng với khung hiển thị mẹ và khung hiển thị đồng cấp, cũng như thiết lập khung hiển thị thuộc tính—tất cả mà không cần chỉnh sửa bất kỳ XML nào một cách thủ công.

Hình 3. Layout Editor (Trình chỉnh sửa bố cục) trong Android Studio cho thấy ConstraintLayout.

Để biết thêm thông tin, hãy xem bài viết Tạo giao diện người dùng thích ứng bằng ConstraintLayout.

Chiều rộng và chiều cao đáp ứng

Để đảm bảo bố cục của bạn thích ứng với nhiều kích thước hiển thị, hãy sử dụng wrap_content, match_parent hoặc 0dp (match constraint) cho chiều rộng và chiều cao của thành phần khung hiển thị thay vì giá trị được cố định giá trị trong mã:

  • wrap_content: Thành phần hiển thị này thiết lập kích thước để phù hợp với nội dung của thành phần hiển thị đó.
  • match_parent: Thành phần hiển thị này mở rộng nhiều nhất có thể trong thành phần hiển thị mẹ.
  • 0dp (match constraint): Trong ConstraintLayout, tương tự như match_parent. Chế độ xem này sẽ chiếm tất cả không gian có sẵn trong hạn chế.

Ví dụ:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/lorem_ipsum" />

Hình 4 cho thấy cách chiều rộng và chiều cao của TextView điều chỉnh khi màn hình thay đổi chiều rộng theo hướng thiết bị.

Hình 4. TextView thích ứng.

TextView đặt chiều rộng để lấp đầy tất cả không gian có sẵn (match_parent) và chiều cao của nó chính xác bằng chiều cao của ngăn chứa văn bản (wrap_content), cho phép khung hiển thị thích ứng với các màn hình khác nhau và số lượng văn bản khác nhau.

Nếu đang sử dụng LinearLayout, bạn cũng có thể mở rộng các chế độ xem con dựa trên bố cục trọng số để các thành phần hiển thị được lấp đầy theo tỷ lệ không gian có sẵn. Tuy nhiên, việc sử dụng các trọng số trong LinearLayout lồng nhau đòi hỏi hệ thống thực hiện nhiều lần truyền bố cục để xác định kích thước của mỗi lần truyền làm chậm hiệu suất của giao diện người dùng.

ConstraintLayout có thể tạo gần như tất cả các bố cục có thể bằng LinearLayout mà không ảnh hưởng đến hiệu suất, nên hãy chuyển đổi các biến đổi được lồng LinearLayout đến ConstraintLayout. Sau đó, bạn có thể xác định bố cục có trọng số kèm quy tắc ràng buộc .

Thiết kế thích ứng

Bố cục của ứng dụng phải luôn thích ứng với nhiều kích thước hiển thị. Tuy nhiên, ngay cả bố cục thích ứng cũng không thể cung cấp trải nghiệm người dùng tốt nhất mọi thiết bị hoặc màn hình ở chế độ nhiều cửa sổ. Ví dụ: giao diện người dùng mà bạn cho điện thoại, có thể không cung cấp trải nghiệm người dùng tối ưu trên máy tính bảng. Thiết kế thích ứng cung cấp bố cục thay thế được tối ưu hoá cho những thứ nguyên hiển thị.

SlidingPaneLayout cho các giao diện người dùng dạng danh sách-chi tiết

Giao diện người dùng chi tiết về danh sách thường cung cấp trải nghiệm người dùng khác trên màn hình có kích thước khác nhau. Trên màn hình lớn, danh sách và ngăn chi tiết thường nằm cạnh nhau. Khi một mục trong danh sách được chọn, thông tin của mục đó sẽ hiện trong ngăn chi tiết mà không làm thay đổi giao diện người dùng (hai ngăn vẫn được giữ nguyên) cạnh nhau. Tuy nhiên, trên màn hình nhỏ, hai ngăn này được hiển thị riêng biệt, mỗi ngăn chiếm toàn bộ khu vực hiển thị. Khi một mục trong ngăn danh sách đã chọn, ngăn chi tiết (chứa thông tin của mục đã chọn) sẽ thay thế ngăn danh sách. Thao tác quay lại thay thế ngăn chi tiết bằng danh sách.

SlidingPaneLayout quản lý logic để xác định trải nghiệm nào trong số hai trải nghiệm người dùng phù hợp với kích thước cửa sổ hiện tại:

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/item_navigation" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

Thuộc tính layout_widthlayout_weight của hai khung hiển thị có trong SlidingPaneLayout xác định hành vi của SlidingPaneLayout. Trong ví dụ này, nếu cửa sổ đủ lớn (ít nhất là 580 dp) để hiển thị cả hai chế độ xem, thì các ngăn được hiển thị cạnh nhau. Tuy nhiên, nếu chiều rộng cửa sổ nhỏ hơn 580 dp, các ngăn trượt lên nhau để chiếm toàn bộ ứng dụng cửa sổ.

Nếu chiều rộng cửa sổ lớn hơn tổng chiều rộng tối thiểu đã chỉ định (580 dp), Bạn có thể dùng các giá trị layout_weight để định kích thước hai ngăn theo tỷ lệ. Trong Ví dụ: ngăn danh sách luôn rộng 280dp vì không có trọng số. Tuy nhiên, ngăn chi tiết luôn lấp đầy bất kỳ không gian ngang nào vượt quá 580dp vì về chế độ cài đặt layout_weight của khung hiển thị.

Tài nguyên bố cục thay thế

Để điều chỉnh thiết kế giao diện người dùng cho phù hợp với nhiều kích thước màn hình, hãy dùng các bố cục thay thế được xác định theo resource bộ hạn định.

Hình 5. Cùng một ứng dụng sử dụng các bố cục khác nhau cho nhiều kích thước màn hình.

Bạn có thể cung cấp bố cục thích ứng, dành riêng cho màn hình bằng cách tạo thêm res/layout/ thư mục trong mã nguồn của ứng dụng. Tạo một thư mục cho mỗi cấu hình màn hình yêu cầu bố cục khác. Sau đó, hãy thêm một màn hình bộ hạn định cấu hình thành tên thư mục layout (ví dụ: layout-w600dp cho màn hình có chiều rộng trống là 600 dp).

Những chuỗi định cấu hình đại diện cho không gian hiển thị có sẵn cho giao diện người dùng ứng dụng của bạn. Hệ thống xem xét mọi thành phần trang trí hệ thống (chẳng hạn như thanh điều hướng) và các thay đổi về cấu hình cửa sổ (chẳng hạn như nhiều cửa sổ) chế độ) khi chọn bố cục cho ứng dụng.

Để tạo bố cục thay thế trong Android Studio, hãy xem phần Sử dụng biến thể bố cục để tối ưu hoá cho nhiều loại màn hình Phát triển giao diện người dùng bằng Khung hiển thị.

Bộ hạn định có chiều rộng nhỏ nhất

Bộ hạn định kích thước màn hình có chiều rộng nhỏ nhất cho phép bạn cung cấp lựa chọn thay thế bố cục cho màn hình có chiều rộng tối thiểu được đo bằng giá trị không phụ thuộc vào mật độ pixel (dp).

Bằng cách mô tả kích thước màn hình là số đo dp, Android cho phép bạn tạo được thiết kế cho các kích thước hiển thị cụ thể mà không cần quan tâm đến mật độ pixel khác nhau.

Ví dụ: bạn có thể tạo một bố cục có tên là main_activity được tối ưu hoá để điện thoại và máy tính bảng bằng cách tạo các phiên bản khác nhau của tệp trong các phiên bản khác nhau thư mục:

res/layout/main_activity.xml           # For phones (smaller than 600dp smallest width)
res/layout-sw600dp/main_activity.xml   # For 7" tablets (600dp wide or wider)

Bộ hạn định chiều rộng nhỏ nhất chỉ định kích thước nhỏ nhất trong số hai cạnh của màn hình, bất kể hướng hiện tại của thiết bị là gì, vì vậy đây là một cách để chỉ định kích thước hiển thị tổng thể có sẵn cho bố cục của bạn.

Dưới đây là cách các giá trị chiều rộng nhỏ nhất tương ứng với kích thước màn hình thông thường:

  • 320dp: Màn hình điện thoại nhỏ (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, v.v.)
  • 480dp: Màn hình điện thoại lớn ~5 inch (480x800 mdpi).
  • 600dp: 7 inch máy tính bảng (600 x 1024 mdpi)
  • 720dp: 10 inch máy tính bảng (720x1280 mdpi, 800x1280 mdpi, v.v.)

Hình sau đây cung cấp thông tin chi tiết hơn về mức độ khác nhau về dp trên màn hình chiều rộng tương ứng với các kích thước và hướng màn hình khác nhau.

Hình 6. Điểm chuyển đổi chiều rộng đề xuất để hỗ trợ các kích thước màn hình khác nhau.

Giá trị cho bộ hạn định chiều rộng nhỏ nhất là dp vì điều quan trọng là lượng không gian hiển thị có sẵn sau khi hệ thống tính đến mật độ pixel (không phải độ phân giải pixel thô).

Kích thước bạn chỉ định bằng cách sử dụng bộ hạn định tài nguyên như chiều rộng nhỏ nhất là chứ không phải kích thước màn hình thực tế. Thay vào đó, các kích thước chỉ định chiều rộng hoặc chiều cao theo đơn vị dp có sẵn cho cửa sổ ứng dụng. Hệ thống Android có thể sử dụng một số màn hình hiển thị giao diện người dùng hệ thống (chẳng hạn như thanh hệ thống ở cuối hoặc thanh trạng thái ở trên cùng), vì vậy, một số màn hình có thể không có sẵn cho bố cục của bạn. Nếu bạn dùng ứng dụng ở chế độ nhiều cửa sổ, ứng dụng chỉ có quyền truy cập vào kích thước của cửa sổ chứa ứng dụng. Khi cửa sổ được đổi kích thước, nó sẽ kích hoạt cấu hình thay đổi với kích thước cửa sổ mới, điều này cho phép hệ thống chọn tệp bố cục phù hợp. Vì vậy, nguồn lực kích thước bộ hạn định mà bạn khai báo chỉ nên xác định không gian mà ứng dụng của bạn cần. Hệ thống tính đến mọi không gian mà giao diện người dùng hệ thống sử dụng khi cung cấp không gian cho bố cục của mình.

Bộ hạn định chiều rộng có sẵn

Thay vì thay đổi bố cục dựa trên chiều rộng nhỏ nhất của màn hình, bạn có thể muốn thay đổi bố cục dựa trên chiều rộng hoặc chiều cao hiện có. Ví dụ: bạn có thể muốn sử dụng bố cục hai ngăn bất cứ khi nào màn hình cung cấp chiều rộng tối thiểu là 600dp. Chiều rộng này có thể thay đổi tuỳ thuộc vào theo hướng ngang hoặc dọc. Trong trường hợp đó, bạn nên sử dụng chiều rộng có sẵn như sau:

res/layout/main_activity.xml         # For phones (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # For 7" tablets or any screen with 600dp available width
                                     # (possibly landscape phones)

Nếu bạn lo ngại về chiều cao có sẵn cho ứng dụng của mình, bạn có thể sử dụng chiều cao có sẵn. Ví dụ: layout-h600dp cho các màn hình có tại chiều cao màn hình tối thiểu là 600dp.

Bộ hạn định hướng

Mặc dù bạn có thể hỗ trợ tất cả các biến thể kích thước bằng cách chỉ sử dụng tổ hợp bộ hạn định chiều rộng nhỏ nhấtchiều rộng có sẵn, bạn có thể cũng muốn thay đổi trải nghiệm người dùng khi người dùng chuyển đổi giữa chế độ màn hình dọc và hướng ngang.

Do đó, bạn có thể thêm bộ hạn định port hoặc land vào thư mục bố cục của mình tên. Chỉ cần đảm bảo bộ hạn định hướng xuất hiện sau bộ hạn định kích thước. Ví dụ:

res/layout/main_activity.xml                # For phones
res/layout-land/main_activity.xml           # For phones in landscape
res/layout-sw600dp/main_activity.xml        # For 7" tablets
res/layout-sw600dp-land/main_activity.xml   # For 7" tablets in landscape

Để biết thêm thông tin về tất cả các bộ hạn định cấu hình màn hình, hãy xem phần Ứng dụng tổng quan về các tài nguyên.

Các lớp kích thước cửa sổ

Các lớp kích thước cửa sổ là các điểm ngắt khung nhìn giúp bạn tạo thích ứng của bạn. Điểm ngắt xác định khu vực hiển thị có sẵn cho ứng dụng là nhỏ gọn, trung bình hoặc mở rộng. Chiều rộng và chiều cao được chỉ định riêng, vì vậy, ứng dụng của bạn luôn có lớp kích thước cửa sổ cho chiều rộng và lớp kích thước cửa sổ cho chiều cao.

Để áp dụng bố cục thích ứng theo phương thức lập trình, hãy làm như sau:

  • Tạo tài nguyên bố cục dựa trên điểm ngắt lớp kích thước cửa sổ
  • Tính toán các lớp kích thước cửa sổ chiều rộng và chiều cao của ứng dụng bằng cách sử dụng WindowSizeClass#compute() qua Jetpack WindowManager thư viện
  • Tăng cường tài nguyên bố cục cho các lớp kích thước cửa sổ hiện tại

Để biết thêm thông tin, hãy xem phần Kích thước cửa sổ lớp học.

Thành phần giao diện người dùng được mô-đun hóa sử dụng mảnh

Khi thiết kế ứng dụng cho nhiều kích thước màn hình, hãy dùng các mảnh để trích xuất logic giao diện người dùng thành các thành phần riêng biệt để đảm bảo bạn hành vi trùng lặp trên giao diện người dùng trên các hoạt động. Sau đó, bạn có thể kết hợp các mảnh để tạo bố cục nhiều ngăn trên màn hình lớn hoặc bạn có thể đặt các mảnh trong các hoạt động riêng biệt trên màn hình nhỏ.

Ví dụ: mẫu danh sách-chi tiết (xem SlidingPaneLayout ở trên) có thể được triển khai bằng một mảnh chứa danh sách và một mảnh khác chứa mục danh sách chi tiết. Trên màn hình lớn, các mảnh có thể hiển thị cạnh nhau; về các màn hình nhỏ riêng lẻ, lấp đầy màn hình.

Để tìm hiểu thêm, hãy xem thông tin tổng quan về Mảnh.

Nhúng hoạt động

Nếu ứng dụng bao gồm nhiều hoạt động, tính năng nhúng hoạt động cho phép bạn dễ dàng tạo giao diện người dùng thích ứng.

Tính năng nhúng hoạt động hiển thị nhiều hoạt động hoặc nhiều thực thể của cùng một hoạt động đồng thời trong cửa sổ tác vụ của ứng dụng. Trên màn hình lớn, các hoạt động có thể hiển thị cạnh nhau; trên các màn hình nhỏ, xếp chồng một ứng dụng lên trên của mục khác.

Bạn sẽ xác định cách ứng dụng hiển thị các hoạt động bằng cách tạo một XML tệp cấu hình mà hệ thống sử dụng để xác định tệp cấu hình phù hợp. dựa trên kích thước hiển thị. Ngoài ra, bạn có thể thực hiện các thao tác Jetpack API WindowManager cuộc gọi.

Tính năng nhúng hoạt động hỗ trợ các thay đổi về hướng thiết bị và thiết bị có thể gập lại, xếp chồng và huỷ xếp các hoạt động khi thiết bị xoay hoặc gập lại và mở ra.

Để biết thêm thông tin, hãy xem phần Hoạt động nhúng.

Kích thước màn hình và tỷ lệ khung hình

Kiểm thử ứng dụng trên nhiều kích thước màn hình và tỷ lệ khung hình để đảm bảo giao diện người dùng điều chỉnh theo tỷ lệ một cách chính xác.

Android 10 (API cấp 29) trở lên hỗ trợ nhiều tỷ lệ khung hình. Các kiểu dáng có thể gập lại có thể khác nhau từ màn hình cao, hẹp, chẳng hạn như 21:9 khi gập lại thành hình vuông tỷ lệ khung hình 1:1 khi mở ra.

Để đảm bảo khả năng tương thích với nhiều thiết bị nhất có thể, hãy kiểm thử ứng dụng của bạn nhiều tỷ lệ khung hình sau đây nhất có thể:

Hình 7. Nhiều tỷ lệ khung hình của màn hình.

Nếu bạn không có quyền truy cập vào thiết bị cho tất cả các kích thước màn hình khác nhau mà bạn muốn để kiểm thử, bạn có thể sử dụng Trình mô phỏng Android để mô phỏng hầu như mọi kích thước màn hình.

Nếu muốn thử nghiệm trên một thiết bị thực tế nhưng không có thiết bị, bạn có thể sử dụng Phòng thử nghiệm Firebase để truy cập trong trung tâm dữ liệu của Google.

Tài nguyên khác