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

Các ứng dụng Android cần hỗ trợ một hệ sinh thái không ngừng mở rộng gồm nhiều 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. Bất kể người dùng đang làm gì, trải nghiệm đó phải 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 khung 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, một ứ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, một ứng dụng nằm trong một cửa sổ có thể thay đổi kích thước. Thậm chí có thể có nhiều 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: dựa vào việc thiết bị đó có kích thước hoặc tỷ lệ khung hình nhất định, hay cả hai? Khi xuất hiện các kiểu dáng mới, những định nghĩa này có thể thay đổi và điểm khác biệt nêu trên sẽ không còn quan trọng.

Thay vì thử bất kỳ chiến lược nào trước đó, hãy dùng các điểm ngắt và lớp 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 kiểu dáng, hãy tìm những giá trị ngưỡng mà theo đó các nhánh quyết định cấp cao ở các hướng khác nhau. Để đạt được mục tiêu này, lưới bố cục thích ứng của Material Design sẽ cung cấp các điểm ngắt cho chiều rộng và chiều cao, giú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á được gọi là lớp kích thước cửa sổ. Do sự phổ biến của thao tá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 mọi 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 lớp kích thước cửa sổ, hãy xem bài viết 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ục thiế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 ý rằng "ổn định" không nhất thiết có nghĩa là khung hiển thị luôn hiện lên mà thay vào đó, khung này vẫn giữ nguyên vị trí trong khi các khung hiển thị nội dung khác có thể sẽ 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 ngăn trượt không hiện trên màn hình, nhưng ngăn trượt này vẫn luôn ở đó.

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 lớp kích thước để quyết định vị trí đặt những phần tử đó. Lớp này mô tả khoảng trống còn lại cho 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. Những bố cục đủ điều kiện sẽ dùng các điểm ngắt chiều rộng như 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. Nhiều trình quản lý bố cục dành cho các lớp kích thước cửa sổ khác nhau.

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 phân biệt những 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ì 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: Ngăn bổ trợ, khung hiển thị chi tiết danh sách

Sử dụng ngăn bổ trợ. Ngăn bổ 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. Thường thì loại này sử dụng 1/3 phần màn hình ở phía dưới cùng để 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ị ngăn. Sau đây là một vài phương án thay thế để bạn xem xét:

  • 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 ngăn bổ trợ.

Tạo bố cục 2 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 khung hiển thị chi tiết danh sách để hiển thị cả hai tính năng cạnh nhau theo bố cục 2 ngăn. Không giống như ngăn bổ trợ, ngăn chi tiết của khung hiển thị chi tiết 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.

Hãy sử dụng tiện ích SlidingPaneLayout dành riêng cho việc triển khai khung hiển thị chi tiết 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).

Tài nguyên khác