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

Ứ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ị khác nhau.

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 đề cập đến bố cục sử dụng tối ưu không gian có sẵn và điều chỉnh khi nó thay đổi. Có nhiều cách điều chỉnh: đơn giản như tăng kích thước của chế độ xem, đặt lại vị trí để dễ tiếp cận chế độ xem đó hơn, hiển thị hoặc ẩn chế độ xem bổ sung hoặc kết hợp các chế độ xem này.

Tính liên tục đề cập đến 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 người dùng hiện đang tham gia tiếp tục diễn ra mà không bị gián đoạn. Do thay đổi về kích thước có thể khiến toàn bộ hệ phân cấp chế độ xem bị phá hủy và tái tạo, nên điều quan trọng là người dùng không nên làm mất vị trí hoặc dữ liệu của mình.

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 nà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ị hiển thị cửa sổ ứng dụng có kích thước khác nhau.
Hình 1. Kích thước cửa sổ có thể khác với thiết bị thực tế hoặc kích thước màn hình.

Do đó, tránh việc khóa ứ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à loại 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, sử dụng kích thước cửa sổ khi đưa ra quyết định cấp cao 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 các giá trị ngưỡng mà những quyết định cấp cao này phân nhánh theo các hướng khác nhau. Để đạt được mục tiêu này, nguyên tắc của Material Design (Thiết kế nội dung) cung cấp 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 hóa được gọi là loại kích thước cửa sổ. Do sự phổ biến của việc cuộn dọc, hầu hết các ứng dụng chủ yếu chú tâm đến loại kích thước chiều rộng, vì vậy hầu hết các ứng dụng đều có thể được tối ưu hóa 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 phần Hỗ trợ các kích thước màn hình khác nhau.)

Các thành phần trên giao diện người dùng ổn định

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, hoạt động sử dụng bottom bar (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 các kích thước khác nhau

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 với các kích thước khác nhau, bạn có thể sử dụng 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, trong đó 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 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 để điều chỉnh 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, Hình ảnh chính

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 để nó dễ truy 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ể hiển thị nhiều nội dung hơn. Tuy nhiên, hãy lưu ý 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ặcFlexboxLayoutManagerkhi 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ách các trình quản lý bố cục khác nhau, bố trí ứng dụng khác nhau dựa trên lớp kích thước chiều rộng.
Hình 2. Sử dụng LayoutManager khác nhau 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 để hiển thị nhiều nội dung hơn và dễ dàng phân biệt các ranh giới của mục hơn.

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ì bố cục có nhiều cách để ràng buộc kích thước bao gồm của chế độ xem con bằng tỷ lệ phần trăm hoặc việc thực thi tỷ lệ khung hình và để đặt vị trí con liên quan vào đó hoặc vị trí 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 thị nội dung khi thông thường bạn sẽ chỉ truy cập được thông qua hoạt động tương tác bổ sung 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ác chế độ xem 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 đó yêu cầu tập trung 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 hiển thị 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 hiển thị 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 có thể 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ợ, Chế độ xem 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ợ hiển thị thêm nội dung hoặc các hành động 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ường, các chiều rộng này sẽ 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 thị 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 menu (trình đơn) hoặc cửa sổ bật lên bằng cách nhấn vào biểu tượng menu
Các hình ảnh minh họa về DrawerLayout, BottomSheetBehavior và menu (trình đơn) tùy chọ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à hiển thị một danh sách các mục (như danh bạ hoặc kết quả tìm kiếm) và 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 chế độ xem chi tiết về danh sách để hiển thị 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 chế độ xem chi tiết về danh sách là một phần tử độc lập có thể hiển thị độc lập trên màn hình nhỏ hơn.

Sử dụng tiện ích SlidingPaneLayout dành riêng cho việc triển khai chế độ xem chi tiết về danh sách. Tiện ích này tự động tính toán liệu có đủ khoảng trống để hiển thị cả hai ngăn này với nhau 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, thì 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 hiển thị 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. SlidingPaneLayout hiển thị ngăn trượt chi tiết ở đầu ngăn danh sách trên một thiết bị có màn hình nhỏ.
Hình 5. SlidingPaneLayout hiển thị 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 các 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 của mình. Bạn có thể đọc thêm về chức năng này trong phần Thao tác trên giao diện người dùng thích ứng.