Kiến thức cơ bản về Kotlin cho Android 07.3: GridLayout với RecyclerView

Lớp học lập trình này thuộc khoá học Kiến thức cơ bản về Kotlin cho Android. Bạn sẽ nhận được nhiều giá trị nhất qua khoá học này nếu thực hiện các lớp học lập trình theo trình tự. Tất cả lớp học lập trình của khoá học đều được liệt kê trên trang đích của lớp học lập trình Kiến thức cơ bản về cách tạo ứng dụng Android bằng Kotlin.

Giới thiệu

Một trong những điểm mạnh chính của RecyclerView là cho phép bạn sử dụng trình quản lý bố cục để kiểm soát và sửa đổi chiến lược bố cục. LayoutManager quản lý cách sắp xếp các mục trong RecyclerView.

RecyclerView đi kèm với trình quản lý bố cục có sẵn cho các trường hợp sử dụng phổ biến. Ví dụ: bạn có thể dùng LinearLayout cho danh sách ngang và dọc hoặc GridLayout cho lưới. Đối với các trường hợp sử dụng phức tạp hơn, bạn cần triển khai một LayoutManager tuỳ chỉnh.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách hiển thị dữ liệu bằng bố cục dạng lưới thay vì danh sách, dựa trên ứng dụng theo dõi giấc ngủ trong lớp học lập trình trước. (Nếu không có ứng dụng từ lớp học lập trình trước, bạn có thể tải mã khởi đầu cho lớp học lập trình này.)

Kiến thức bạn cần có

Bạn cần thông thạo:

  • Tạo giao diện người dùng cơ bản bằng Activity, FragmentsViews
  • Điều hướng giữa các mảnh và sử dụng safeArgs để truyền dữ liệu giữa các mảnh
  • Xem các mô hình, nhà máy mô hình và các phép biến đổi
  • LiveData và người quan sát của họ
  • Cách tạo cơ sở dữ liệu Room, tạo DAO và xác định các thực thể
  • Cách sử dụng coroutine cho các tác vụ cơ sở dữ liệu và các tác vụ chạy trong thời gian dài khác
  • Cách triển khai RecyclerView cơ bản bằng Adapter, ViewHolder và bố cục thành phần
  • Cách triển khai liên kết dữ liệu cho RecyclerView
  • Cách tạo và sử dụng phương thức điều hợp liên kết để chuyển đổi dữ liệu

Kiến thức bạn sẽ học được

  • Cách sử dụng một LayoutManager khác để thay đổi cách dữ liệu của bạn xuất hiện trong RecyclerView
  • Cách tạo bố cục lưới cho dữ liệu giấc ngủ

Bạn sẽ thực hiện

  • Dựa trên ứng dụng sleep-tracker trong lớp học lập trình trước trong loạt lớp học lập trình này.
  • Thay thế danh sách dữ liệu giấc ngủ do RecyclerView hiển thị trong ứng dụng bằng một lưới dữ liệu giấc ngủ.

Ứng dụng theo dõi giấc ngủ có 2 màn hình, được biểu thị bằng các mảnh, như trong hình dưới đây.

Màn hình đầu tiên (xuất hiện ở bên trái) có các nút để bắt đầu và dừng theo dõi. Màn hình này cho thấy một số dữ liệu về giấc ngủ của người dùng. Nút Xoá sẽ xoá vĩnh viễn tất cả dữ liệu mà ứng dụng đã thu thập cho người dùng. Màn hình thứ hai (ở bên phải) là màn hình chọn mức đánh giá chất lượng giấc ngủ.

Ứng dụng này sử dụng một cấu trúc đơn giản với bộ điều khiển giao diện người dùng, mô hình hiển thị và LiveData, cùng một cơ sở dữ liệu Room để duy trì dữ liệu về giấc ngủ.

Dữ liệu giấc ngủ được hiển thị trong RecyclerView. Trong lớp học lập trình này, bạn sẽ thay đổi ứng dụng để sử dụng GridLayout. Màn hình cuối cùng sẽ có dạng như ảnh chụp màn hình dưới đây.

Trong một lớp học lập trình trước, khi thêm RecyclerView vào fragment_sleep_tracker.xml, bạn đã thêm một LinearLayoutManager mà không tuỳ chỉnh gì. Mã này hiển thị dữ liệu dưới dạng danh sách dọc.

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

LinearLayoutManager là trình quản lý bố cục đơn giản và phổ biến nhất cho RecyclerView, đồng thời hỗ trợ cả vị trí ngang và dọc của các khung hiển thị con. Ví dụ: bạn có thể dùng LinearLayoutManager để tạo một băng chuyền gồm những hình ảnh mà người dùng di chuyển theo chiều ngang.

GridLayout

Một trường hợp sử dụng phổ biến khác là cần cho người dùng thấy nhiều dữ liệu, bạn có thể thực hiện việc này bằng cách sử dụng GridLayout. GridLayoutManager cho RecyclerView bố trí dữ liệu dưới dạng lưới có thể cuộn, như minh hoạ dưới đây.

Từ góc độ thiết kế, GridLayout là phù hợp nhất đối với các danh sách có thể được biểu thị dưới dạng biểu tượng hoặc hình ảnh, chẳng hạn như danh sách trong một ứng dụng duyệt xem ảnh. Trong ứng dụng theo dõi giấc ngủ, bạn có thể hiển thị mỗi đêm ngủ dưới dạng một lưới gồm các biểu tượng lớn. Thiết kế này sẽ giúp người dùng xem nhanh thông tin tổng quan về chất lượng giấc ngủ.

Cách GridLayout trình bày các mục

GridLayout sắp xếp các mục trong một lưới gồm các hàng và cột. Với chức năng cuộn theo chiều dọc (theo mặc định), mỗi mục trong một hàng sẽ chiếm một "span". (Trong trường hợp này, một span tương đương với chiều rộng của một cột.)

Trong hai ví dụ đầu tiên minh hoạ dưới đây, mỗi hàng được tạo thành từ ba span. Theo mặc định, GridLayoutManager bố trí mỗi mục trong một span cho đến khi hết số span mà bạn chỉ định. Khi đạt đến số lượng span chỉ định, các mục sẽ chuyển xuống dòng tiếp theo.

Theo mặc định, mỗi mục chiếm một khoảng, nhưng bạn có thể làm cho một mục rộng hơn bằng cách chỉ định số lượng khoảng mà mục đó sẽ chiếm. Ví dụ: mục trên cùng trong màn hình bên phải nhất (hiển thị bên dưới) chiếm 3 khoảng.

Trong nhiệm vụ này, bạn sẽ lấy RecyclerView mà bạn đã hoàn thành trong bài tập trước và cập nhật để hiển thị dữ liệu bằng GridLayoutManager. Bạn có thể tiếp tục sử dụng ứng dụng theo dõi giấc ngủ trong lớp học lập trình trước hoặc tải ứng dụng RecyclerViewGridLayout-Starter xuống qua GitHub.

Bước 1: Thay đổi LayoutManager

  1. Nếu cần, hãy tải ứng dụng RecyclerViewGridLayout-Starter cho lớp học lập trình này xuống từ GitHub rồi mở dự án trong Android Studio.
  2. Mở tệp bố cục fragment_sleep_tracker.xml.
  3. Xoá trình quản lý bố cục khỏi định nghĩa sleep_list RecyclerView.

Đoạn mã cần xoá:

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager
  1. Mở SleepTrackerFragment.kt.
  2. Trong OnCreateView(), ngay trước câu lệnh return, hãy tạo một GridLayoutManager mới theo chiều dọc, từ trên xuống dưới với 3 khoảng.

    Hàm khởi tạo GridLayoutManager nhận tối đa 4 đối số: một ngữ cảnh (là activity), số khoảng (số cột trong bố cục dọc mặc định), hướng (mặc định là dọc) và liệu đó có phải là bố cục đảo ngược hay không (mặc định là false).
val manager = GridLayoutManager(activity, 3)
  1. Bên dưới dòng đó, hãy yêu cầu RecyclerView sử dụng GridLayoutManager này. RecyclerView nằm trong đối tượng liên kết và có tên là sleepList. (Xem fragment_sleep_tracker.xml.)
binding.sleepList.layoutManager = manager

Bước 2: Thay đổi bố cục

Bố cục hiện tại trong list_item_sleep_night.xml hiển thị dữ liệu bằng cách sử dụng toàn bộ hàng cho mỗi đêm. Trong bước này, bạn sẽ xác định một bố cục mặt hàng hình vuông nhỏ gọn hơn cho lưới.

  1. Mở list_item_sleep_night.xml.
  2. Xoá sleep_length TextView vì thiết kế mới không cần đến thành phần này.
  3. Di chuyển quality_string TextView để nó xuất hiện bên dưới ImageView. Để làm được điều đó, bạn phải cập nhật khá nhiều thứ. Sau đây là bố cục cuối cùng cho quality_string TextView:
<TextView
   android:id="@+id/quality_string"
   android:layout_width="0dp"
   android:layout_height="20dp"
   android:textAlignment="center"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toEndOf="@+id/quality_image"
   app:layout_constraintHorizontal_bias="0.0"
   app:layout_constraintStart_toStartOf="@+id/quality_image"
   app:layout_constraintTop_toBottomOf="@+id/quality_image"
   tools:text="Excellent!!!"
   app:sleepQualityString="@{sleep}" />
  1. Trong chế độ xem Design (Thiết kế), hãy xác minh rằng quality_string TextView được đặt bên dưới ImageView.

Vì đã sử dụng tính năng liên kết dữ liệu, nên bạn không cần thay đổi bất cứ điều gì trong Adapter. Đoạn mã này sẽ hoạt động và danh sách của bạn sẽ hiển thị dưới dạng một lưới.

  1. Chạy ứng dụng và quan sát cách dữ liệu giấc ngủ xuất hiện trong một lưới.

    Xin lưu ý rằng ConstraintLayout vẫn chiếm toàn bộ chiều rộng. GridLayoutManager giúp chế độ xem của bạn có chiều rộng cố định, dựa trên khoảng. GridLayoutManager cố gắng hết sức để đáp ứng mọi ràng buộc khi bố trí lưới, thêm khoảng trắng hoặc cắt các mục.
  1. Trong SleepTrackerFragment, trong đoạn mã tạo GridLayoutManager, hãy thay đổi số lượng khoảng cho GridLayoutManger thành 1. Chạy ứng dụng và bạn sẽ nhận được một danh sách.
val manager = GridLayoutManager(activity, 1)
  1. Thay đổi số lượng khoảng cho GridLayoutManager thành 10 rồi chạy ứng dụng. Bạn sẽ thấy rằng GridLayoutManager sẽ vừa 10 mục trong một hàng, nhưng các mục hiện đã bị cắt.
  2. Thay đổi số lượng khoảng thành 5 và hướng thành GridLayoutManager.VERTICAL. Chạy ứng dụng và chú ý đến cách bạn có thể di chuyển theo chiều ngang. Bạn sẽ cần một bố cục khác để có thể hiển thị tốt.
val manager = GridLayoutManager(activity, 5, GridLayoutManager.HORIZONTAL, false)
  1. Đừng quên đặt số lượng khoảng trống về 3 và hướng về dọc!

Dự án Android Studio: RecyclerViewGridLayout

  • Trình quản lý bố cục quản lý cách sắp xếp các mục trong RecyclerView.
  • RecyclerView đi kèm với các trình quản lý bố cục có sẵn cho các trường hợp sử dụng phổ biến như LinearLayout cho danh sách ngang và dọc, và GridLayout cho lưới.
  • Đối với các trường hợp sử dụng phức tạp hơn, hãy triển khai một LayoutManager tuỳ chỉnh.
  • Từ góc độ thiết kế, GridLayout phù hợp nhất để dùng cho danh sách các mục có thể được biểu thị dưới dạng biểu tượng hoặc hình ảnh.
  • GridLayout sắp xếp các mục trong một lưới gồm các hàng và cột. Với chức năng cuộn theo chiều dọc, mỗi mục trong một hàng sẽ chiếm một "khoảng".
  • Bạn có thể tuỳ chỉnh số lượng khoảng mà một mục chiếm, tạo ra các lưới thú vị hơn mà không cần trình quản lý bố cục tuỳ chỉnh.
  • Tạo một bố cục mục cho một mục trong lưới và trình quản lý bố cục sẽ lo việc sắp xếp các mục.
  • Bạn có thể đặt LayoutManager cho RecyclerView trong tệp bố cục XML chứa phần tử <RecyclerView> hoặc theo cách lập trình.

Các khoá học của Udacity:

Tài liệu dành cho nhà phát triển Android:

Phần này liệt kê các bài tập về nhà cho học viên của lớp học lập trình này trong phạm vi khoá học có người hướng dẫn. Người hướng dẫn phải thực hiện các việc sau đây:

  • Giao bài tập về nhà nếu cần.
  • Trao đổi với học viên về cách nộp bài tập về nhà.
  • Chấm điểm bài tập về nhà.

Người hướng dẫn có thể sử dụng các đề xuất này ít hoặc nhiều tuỳ ý và nên giao cho học viên bất kỳ bài tập về nhà nào khác mà họ cảm thấy phù hợp.

Nếu bạn đang tự học các lớp học lập trình, hãy sử dụng những bài tập về nhà này để kiểm tra kiến thức của mình.

Trả lời các câu hỏi sau

Câu hỏi 1

Trình quản lý bố cục nào sau đây do Android cung cấp? Hãy chọn mọi câu trả lời phù hợp.

LinearLayouManager

GridLayoutManager

CircularLayoutManager

StaggeredGridLayoutManager

Câu hỏi 2

"Khoảng thời gian" là gì?

▢ Kích thước của lưới sẽ do GridLayoutManager tạo.

▢ Chiều rộng của một cột trong lưới.

▢ Kích thước của một mục trong lưới.

▢ Số cột trong một lưới có hướng dọc.

Bắt đầu bài học tiếp theo: 7.4: Tương tác với các mục trong RecyclerView