Di chuyển giao diện người dùng sang bố cục thích ứng

Stay organized with collections Save and categorize content based on your preferences.

Ứng dụng Android hỗ trợ hệ sinh thái không ngừng mở rộng của các yếu tố kiểu dáng thiết bị. Giao diện người dùng của ứng dụng phải thích ứng với nhiều kích thước màn hình cũng như hướng và trạng thái thiết bị.

Giao diện người dùng thích ứng tập trung vào các nguyên tắc linh hoạt và liên tục.

Tính linh hoạt tức là việc bố cục sử dụng tối ưu không gian có sẵn và điều chỉnh khi không gian thay đổi. Có nhiều cách điều chỉnh: đơn giản như tăng kích thước của thành phần hiển thị, đặt lại vị trí để dễ tiếp cận thành phần hiển thị đó hơn, hiện hoặc ẩn các thành phần hiển thị bổ sung hoặc kết hợp các cách này.

Tính liên tục tức là trải nghiệm người dùng liền mạch khi chuyển đổi từ kích thước cửa sổ này sang kích thước cửa sổ khác. Trải nghiệm hiện tại của người dùng tiếp tục diễn ra mà không bị gián đoạn. Do sự thay đổi về kích thước có thể khiến toàn bộ hệ phân cấp thành phần hiển thị bị huỷ bỏ và tái tạo, nên điều quan trọng là người dùng không bị mất vị trí hoặc dữ liệu của họ.

Những điều nên tránh

Tránh sử dụng giá trị vật lý, phần cứng để đưa ra quyết định về bố cục. Việc đưa ra quyết định dựa trên một giá trị cố định có thể hấp dẫn, nhưng trong nhiều trường hợp, các giá trị này không hữu ích khi xác định không gian hoạt động của giao diện người dùng.

Trên máy tính bảng, ứng dụng có thể chạy ở chế độ nhiều cửa sổ khi chia sẻ màn hình với một ứng dụng khác. Trên Chrome OS, ứng dụng nằm trong một cửa sổ có thể thay đổi kích thước. Thậm chí có nhiều hơn một màn hình vật lý, chẳng hạn như với thiết bị có thể gập lại hoặc thiết bị có nhiều màn hình. Trong những trường hợp như vậy, kích thước màn hình thực tế không liên quan đến việc quyết định nội dung hiển thị.

Nhiều thiết bị cho thấy cửa sổ ứng dụng ở nhiều kích thước.
Hình 1. Kích thước cửa sổ có thể khác với kích thước màn hình hoặc thiết bị thực tế.

Do đó, hãy tránh việc khoá ứng dụng theo một hướng hoặc tỷ lệ khung hình cụ thể. Mặc dù thiết bị có thể nằm ở một hướng cụ thể, ứng dụng cũng có thể ở một hướng khác dựa trên kích thước của cửa sổ. Chẳng hạn như trên máy tính bảng nằm ngang khi sử dụng chế độ nhiều cửa sổ, ứng dụng có thể ở chế độ dọc vì ứng dụng cao hơn chiều rộng.

Ngoài ra, tránh cố xác định thiết bị là điện thoại hay máy tính bảng. Tiêu chí để một thiết bị được xem là máy tính bảng có phần khá chủ quan: nghĩa là nó dựa trên kích thước hoặc tỷ lệ khung hình nhất định hay kết hợp cả hai? Khi xuất hiện hệ số hình dạng, những định nghĩa này dễ dàng thay đổi và sự khác biệt đó không còn quan trọng nữa.

Thay vì dựa vào bất kỳ tiêu chí nào ở trên, hãy chú trọng vào yếu tố điểm ngắt và loại kích thước cửa sổ.

Điểm ngắt và lớp kích thước cửa sổ

Phần thực tế của màn hình được phân bổ cho ứng dụng của bạn là cửa sổ của ứng dụng Cửa sổ này có thể chiếm toàn bộ màn hình hoặc một phần màn hình. Vì vậy, hãy sử dụng kích thước cửa sổ khi đưa ra quyết định tổng thể về bố cục của ứng dụng.

Khi thiết kế cho nhiều hệ số hình dạng, hãy tìm những giá trị ngưỡng có thể làm thay đổi phương hướng của những quyết định tổng thể như vậy. Để đạt được mục tiêu này, nguyên tắc của Material Design đưa ra các điểm ngắt về chiều rộng và chiều cao, cho phép bạn liên kết các kích thước thô thành các nhóm riêng biệt được chuẩn hoá gọi là lớp kích thước cửa sổ. Do sự phổ biến của việc cuộn theo chiều dọc, hầu hết ứng dụng chủ yếu chú tâm đến lớp kích thước chiều rộng, vì vậy hầu hết ứng dụng đều có thể được tối ưu hoá cho tất cả kích thước màn hình bằng cách chỉ xử lý một vài điểm ngắt. (Để biết thêm thông tin về các loại kích thước cửa sổ hãy xem nội dung Hỗ trợ nhiều kích thước màn hình.)

Thành phần ổn định trên giao diện người dùng

Nguyên tắc về bố cụcthiết kế Material Design xác định vị trí cho thanh ứng dụng, mục điều hướng và nội dung. Thông thường, hai phần tử đầu tiên là các phần tử giao diện người dùng ổn định là gốc rễ (hoặc gần như vậy) của chế độ xem. Lưu ý "ổn định" không nhất thiết có nghĩa là chế độ xem luôn hiển thị, thay vào đó, chế độ này vẫn được giữ nguyên trong khi các chế độ xem nội dung khác có thể di chuyển hoặc thay đổi. Chẳng hạn: một phần tử điều hướng có thể nằm trong một sliding drawer (ngăn trượt màn hình) hiện không hiển thị trên màn hình, nhưng nó luôn có ở đó.

Các phần tử ổn định có thể thích ứng và thường chiếm toàn bộ chiều rộng hoặc chiều cao của cửa sổ, vì vậy, hãy chọn các loại kích thước để quyết định vị trí đặt các phần tử đó. Nó sẽ phác họa khoảng trống còn lại cho phần nội dung. Trong đoạn mã sau đây, hoạt động sử dụng thanh dưới cùng cho màn hình nhỏ gọn và thanh ứng dụng trên cùng cho màn hình lớn hơn. Bố cục đủ điều kiện sử dụng các điểm ngắt chiều rộng như được mô tả ở trên.

<!-- res/layout/main_activity.xml -->

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- content view(s) -->

    <com.google.android.material.bottomappbar.BottomAppBar
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ... />
</androidx.constraintlayout.widget.ConstraintLayout>

<!-- res/layout-w600dp/main_activity.xml -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        ... />

    <!-- content view(s) -->
</androidx.constraintlayout.widget.ConstraintLayout>

Nội dung

Sau khi bạn định vị các thành phần giao diện người dùng ổn định, hãy sử dụng không gian còn lại cho nội dung, chẳng hạn như sử dụng NavHostFragment cùng với biểu đồ điều hướng của ứng dụng. Hãy xem phầnThao tác trên giao diện người dùng thích ứng để biết thêm các điểm cần cân nhắc khác.

Đảm bảo tất cả dữ liệu đều có sẵn cho nhiều kích thước

Hầu hết các khung ứng dụng hiện nay đều sử dụng mô hình dữ liệu tách biệt với các thành phần Android xây dựng nên giao diện người dùng (Hoạt động, mảnh và chế độ xem). Với Jetpack, vai trò này thường được thực hiện bởi ViewModels, lớp này có thêm một lợi ích là cho phép dữ liệu tồn tại qua các thay đổi về cấu hình (xem phầnTổng quan về ViewModel để biết thêm thông tin).

Khi triển khai bố cục thích ứng trên nhiều kích thước, có thể bạn muốn sử dụng một mô hình dữ liệu khác dựa trên kích thước hiện tại. Tuy nhiên, điều này đi ngược lại nguyên tắc luồng dữ liệu một chiều. Dữ liệu sẽ truyền xuống Chế độ xem và các sự kiện như lượt tương tác của người dùng sẽ truyền lên. Việc tạo phần phụ thuộc theo hướng khác (tức là mô hình dữ liệu phụ thuộc vào cấu hình của lớp giao diện người dùng) khiến việc này trở nên phức tạp hơn. Khi ứng dụng thay đổi kích thước, bạn phải chuyển đổi mô hình dữ liệu sang một mô hình khác.

Thay vào đó, hãy để mô hình dữ liệu điều chỉnh cho phù hợp với lớp kích thước lớn nhất. Sau đó, bạn có thể hiển thị, ẩn hoặc đặt lại vị trí nội dung trong giao diện người dùng sao cho phù hợp với lớp kích thước hiện tại. Dưới đây là một vài chiến lược bạn có thể sử dụng khi quyết định cách hoạt động của bố cục khi chuyển đổi giữa các lớp kích thước.

Mở rộng nội dung

Bố cục chuẩn: Nguồn cấp dữ liệu

Không gian mở rộng có thể đơn giản là cơ hội để làm cho mọi thứ lớn hơn và định dạng lại nội dung để dễ tiếp cập hơn.

Phóng to bộ sưu tập. Nhiều ứng dụng hiển thị một tập hợp các mục trong một vùng chứa cuộn, chẳng hạn như RecyclerView hoặc ScrollView. Cho phép một vùng chứa tự động trở nên lớn hơn có nghĩa là có thể cho thấy nhiều nội dung hơn. Tuy nhiên, hãy để ý đến nội dung trong vùng chứa để không bị kéo giãn quá mức hoặc bị méo hình. Ví dụ: với RecyclerView, hãy cân nhắc sử dụng một trình quản lý bố cục khác như GridLayoutManager,StaggeredGridLayoutManager, hoặc FlexboxLayout khi chiều rộng không nhỏ gọn.

Một thiết bị được đóng lại và mở ra cho thấy các cách bố trí ứng dụng của các trình quản lý bố cục dựa trên lớp kích thước chiều rộng.
Hình 2. Các cách bố trí ứng dụng của các trình quản lý bố cục dựa trên lớp kích thước chiều rộng.

Các mục riêng lẻ cũng có thể sử dụng kích thước hoặc hình dạng khác để cho thấy nhiều nội dung hơn và dễ dàng hơn trong việc phân biệt các ranh giới của mục.

Nhấn mạnh phần tử chính. Nếu bố cục có một tiêu điểm cụ thể, chẳng hạn như hình ảnh hoặc video, hãy mở rộng bố cục đó khi cửa sổ ứng dụng mở rộng để duy trì sự tập trung của người dùng. Bạn có thể sắp xếp lại các phần tử hỗ trợ khác xung quanh hoặc bên dưới chế độ xem hình ảnh chính.

Có nhiều cách để tạo một bố cục như vậy, nhưng ConstraintLayout đặc biệt phù hợp cho mục đích này vì lớp này cung cấp nhiều cách để ràng buộc kích thước của thành phần hiển thị con (bao gồm cả ràng buộc theo tỷ lệ phần trăm, hoặc thực thi tỷ lệ khung hình) và để đặt vị trí theo thành phần con có liên quan hoặc thành phần con khác. Tìm hiểu thêm về tất cả các khả năng này trong bài viết Tạo Giao diện người dùng thích ứng bằng ConstraintLayout.

Hiển thị nội dung có thể thu gọn theo mặc định. Khi có không gian, hãy hiện nội dung mà thường thì chỉ truy cập được thông qua tương tác bổ sung của người dùng như nhấn, cuộn hoặc cử chỉ. Ví dụ: nội dung xuất hiện trong giao diện thẻ khi thu gọn có thể được sắp xếp lại thành cột hoặc danh sách khi có thêm không gian.

Mở rộng lề. Nếu không gian quá lớn đến mức bạn không thể tạo ra sự bắt mắt ngay cả sau khi sử dụng toàn bộ nội dung, hãy mở rộng lề của bố cục để nội dung vẫn ở chính giữa và cá thành phần hiển thị riêng lẻ có kích thước và khoảng cách tự nhiên.

Ngoài ra, thành phần toàn màn hình có thể biến đổi thành giao diện người dùng hộp thoại nổi. Điều này đặc biệt phù hợp khi thành phần đó đòi hỏi tiêu điểm riêng để hoàn thành một nhiệm vụ tức thì cho người dùng, chẳng hạn như soạn email hoặc tạo sự kiện trên lịch.

Điện thoại tiêu chuẩn trình bày hộp thoại ở chế độ toàn màn hình, trong khi điện thoại có thể gập lại và mở ra trình bày hộp thoại dưới dạng một cửa sổ nổi.
Hình 3. Hộp thoại toàn màn hình chuyển thành hộp thoại chuẩn với chiều rộng trung bình và mở rộng.

Thêm nội dung

Bố cục chuẩn: Bảng điều khiển hỗ trợ, thành phần hiển thị chi tiết danh sách

Sử dụng bảng điều khiển hỗ trợ. Bảng điều khiển hỗ trợ trình bày thêm nội dung hoặc thao tác theo ngữ cảnh liên quan đến nội dung chính, chẳng hạn như nhận xét trong một tài liệu hoặc các mục trong danh sách phát nhạc. Thường thì loại này sử dụng 1/3 dưới cùng của màn hình để mở rộng chiều cao hoặc 1/3 cạnh dưới cùng để mở rộng chiều rộng.

Một điều quan trọng cần lưu ý là nơi đặt nội dung này khi không có đủ không gian để hiện bảng điều khiển. Sau đây là một vài phương án thay thế để bạn khám phá:

  • Ngăn bên ở cạnh sau sử dụng DrawerLayout
  • Ngăn dưới cùng sử dụng BottomSheetBehavior
  • Bạn có thể truy cập trình đơn hoặc cửa sổ bật lên bằng cách nhấn vào biểu tượng trình đơn
Hình 4. Những cách khác để trình bày nội dung bổ sung trong một bảng điều khiển hỗ trợ.

Tạo bố cục hai ngăn. Các màn hình lớn có thể hiển thị kết hợp các tính năng thường xuất hiện riêng biệt trên các màn hình nhỏ hơn. Cách thức tương tác phổ biến trong nhiều ứng dụng là cho thấy một danh sách các mục (như danh bạ hoặc kết quả tìm kiếm) rồi chuyển sang phần chi tiết của một mục khi mục đó được chọn. Thay vì phóng to danh sách cho các màn hình lớn hơn, hãy sử dụng thành phần hiển thị chi tiết về danh sách để cho thấy cả hai tính năng cạnh nhau theo bố cục hai ngăn. Không giống như bảng điều khiển hỗ trợ, ngăn chi tiết của thành phần hiển thị chi tiết về danh sách là một phần tử độc lập có thể xuất hiện độc lập trên màn hình nhỏ hơn.

Hãy sử dụng tiện ích SlidingPaneLayout dành riêng cho việc triển khai thành phần hiển thị chi tiết về danh sách. Tiện ích này tự động tính toán xem liệu có đủ khoảng trống để hiện cả hai ngăn này cùng lúc dựa trên giá trị layout_width được chỉ định cho hai ngăn hay không, và mọi không gian còn lại có thể được phân bố bằng cách sử dụng layout_weight. Khi không đủ không gian, mỗi ngăn sẽ sử dụng toàn bộ chiều rộng của bố cục và ngăn chi tiết sẽ trượt ra khỏi màn hình hoặc ở đầu ngăn danh sách.

SlidingPaneLayout cho thấy cả hai ngăn của bố cục chi tiết danh sách trên thiết bị có màn hình rộng.
Hình 5. SlidingPaneLayout cho thấy hai ngăn có chiều rộng mở rộng và một ngăn có chiều rộng thu gọn.

Tạo bố cục hai ngăn chứa thêm thông tin chi tiết về cách sử dụng SlidingPaneLayout. Ngoài ra, xin lưu ý cách thức này có thể ảnh hưởng đến cách bạn sắp xếp biểu đồ điều hướng (xem nội dung Điều hướng trên giao diện người dùng thích ứng).