Kiến thức cơ bản về Kotlin cho Android 07.4: Tương tác với các mục trong 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

Hầu hết các ứng dụng sử dụng danh sách và lưới hiển thị các mục đều cho phép người dùng tương tác với các mục đó. Nhấn vào một mục trong danh sách và xem thông tin chi tiết của mục đó là một trường hợp sử dụng rất phổ biến cho loại hình tương tác này. Để đạt được điều này, bạn có thể thêm trình nghe lượt nhấp để phản hồi các thao tác nhấn của người dùng vào các mục bằng cách hiện một khung hiển thị chi tiết.

Trong lớp học lập trình này, bạn sẽ thêm hoạt động tương tác vào RecyclerView, dựa trên phiên bản mở rộng của ứng dụng theo dõi giấc ngủ trong loạt lớp học lập trình trước.

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

  • Xây dựng giao diện người dùng cơ bản bằng cách sử dụng một hoạt động, các mảnh và thành phần hiển thị.
  • Đ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 hiển thị, các phép biến đổi và LiveData cũng như các đối tượng theo dõi của chúng.
  • Cách tạo cơ sở dữ liệu Room, tạo đối tượng truy cập dữ liệu (DAO) và xác định các thực thể.
  • Cách sử dụng coroutine cho 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 một 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 các phương thức điều hợp liên kết để chuyển đổi dữ liệu.
  • Cách sử dụng GridLayoutManager.

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

  • Cách làm cho các mục trong RecyclerView có thể nhấp vào. Triển khai một trình nghe lượt nhấp để chuyển đến một khung hiển thị chi tiết khi người dùng nhấp vào một mục.

Bạn sẽ thực hiện

  • Xây dựng trên phiên bản mở rộng của ứng dụng TrackMySleepQuality (Theo dõi chất lượng giấc ngủ) trong lớp học lập trình trước đó của loạt bài này.
  • Thêm một trình nghe lượt nhấp vào danh sách và bắt đầu theo dõi hoạt động tương tác của người dùng. Khi một mục trong danh sách được nhấn vào, thao tác này sẽ kích hoạt quá trình điều hướng đến một mảnh có thông tin chi tiết về mục được nhấp. Mã khởi đầu cung cấp mã cho mảnh chi tiết, cũng như mã điều hướng.

Ứng dụng theo dõi giấc ngủ khởi động có 2 màn hình, được biểu thị bằng các mảnh, như minh hoạ trong hình bên dưới.

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ủ.

Trong lớp học lập trình này, bạn sẽ thêm khả năng phản hồi khi người dùng nhấn vào một mục trong lưới, thao tác này sẽ hiển thị một màn hình chi tiết như màn hình bên dưới. Mã cho màn hình này (phân đoạn, mô hình hiển thị và thao tác điều hướng) được cung cấp cùng với ứng dụng khởi đầu và bạn sẽ triển khai cơ chế xử lý lượt nhấp.

Bước 1: Tải ứng dụng khởi đầu

  1. Tải RecyclerViewClickHandler-Starter code xuống từ GitHub rồi mở dự án trong Android Studio.
  2. Tạo bản dựng và chạy ứng dụng theo dõi giấc ngủ khởi đầu.

[Không bắt buộc] Cập nhật ứng dụng nếu bạn muốn sử dụng ứng dụng trong lớp học lập trình trước

Nếu bạn sẽ làm việc trên ứng dụng khởi đầu được cung cấp trong GitHub cho lớp học lập trình này, hãy chuyển sang bước tiếp theo.

Nếu bạn muốn tiếp tục sử dụng ứng dụng theo dõi giấc ngủ mà mình đã tạo trong lớp học lập trình trước, hãy làm theo hướng dẫn bên dưới để cập nhật ứng dụng hiện có sao cho ứng dụng đó có mã cho mảnh màn hình chi tiết.

  1. Ngay cả khi bạn đang tiếp tục với ứng dụng hiện có, hãy lấy mã khởi đầu RecyclerViewClickHandler từ GitHub để có thể sao chép các tệp.
  2. Sao chép tất cả các tệp trong gói sleepdetail.
  3. Trong thư mục layout, hãy sao chép tệp fragment_sleep_detail.xml.
  4. Sao chép nội dung đã cập nhật của navigation.xml. Nội dung này sẽ thêm thành phần điều hướng cho sleep_detail_fragment.
  5. Trong gói database, trong SleepDatabaseDao, hãy thêm phương thức getNightWithId() mới:
/**
 * Selects and returns the night with given nightId.
*/
@Query("SELECT * from daily_sleep_quality_table WHERE nightId = :key")
fun getNightWithId(key: Long): LiveData<SleepNight>
  1. Trong res/values/strings, hãy thêm tài nguyên chuỗi sau:
<string name="close">Close</string>
  1. Dọn dẹp và tạo lại ứng dụng để cập nhật liên kết dữ liệu.

Bước 2: Kiểm tra mã cho màn hình thông tin chi tiết về giấc ngủ

Trong lớp học lập trình này, bạn sẽ triển khai một trình xử lý lượt nhấp để chuyển đến một mảnh cho biết thông tin chi tiết về đêm ngủ đã nhấp. Mã khởi đầu của bạn đã chứa mảnh và biểu đồ điều hướng cho SleepDetailFragment này, vì đây là một đoạn mã khá dài và các mảnh cũng như hoạt động điều hướng không thuộc lớp học lập trình này. Làm quen với đoạn mã sau:

  1. Trong ứng dụng, hãy tìm gói sleepdetail. Gói này chứa mảnh, mô hình hiển thị và nhà máy mô hình hiển thị cho một mảnh hiển thị thông tin chi tiết về một đêm ngủ.

  2. Trong gói sleepdetail, hãy mở và kiểm tra mã cho SleepDetailViewModel. Mô hình hiển thị này lấy khoá cho SleepNight và một DAO trong hàm khởi tạo.

    Phần nội dung của lớp có mã để lấy SleepNight cho khoá đã cho và biến navigateToSleepTracker để kiểm soát thao tác điều hướng quay lại SleepTrackerFragment khi người dùng nhấn nút Đóng.

    Hàm getNightWithId() trả về LiveData<SleepNight> và được xác định trong SleepDatabaseDao (trong gói database).

  3. Trong gói sleepdetail, hãy mở và kiểm tra mã cho SleepDetailFragment. Lưu ý chế độ thiết lập cho tính năng liên kết dữ liệu, mô hình khung hiển thị và đối tượng theo dõi để điều hướng.

  4. Trong gói sleepdetail, hãy mở và kiểm tra mã cho SleepDetailViewModelFactory.

  5. Trong thư mục bố cục, hãy kiểm tra fragment_sleep_detail.xml. Lưu ý rằng biến sleepDetailViewModel được xác định trong thẻ <data> để lấy dữ liệu cần hiển thị trong mỗi khung hiển thị từ mô hình hiển thị.

    Bố cục này chứa một ConstraintLayout chứa một ImageView cho chất lượng giấc ngủ, một TextView cho điểm chất lượng, một TextView cho thời lượng ngủ và một Button để đóng mảnh chi tiết.

  6. Mở tệp navigation.xml. Đối với sleep_tracker_fragment, hãy lưu ý thao tác mới cho sleep_detail_fragment.

    Thao tác mới, action_sleep_tracker_fragment_to_sleepDetailFragment, là thao tác điều hướng từ mảnh trình theo dõi giấc ngủ đến màn hình chi tiết.

Trong nhiệm vụ này, bạn sẽ cập nhật RecyclerView để phản hồi các thao tác nhấn của người dùng bằng cách hiện màn hình chi tiết cho mục được nhấn.

Nhận và xử lý các lượt nhấp là một nhiệm vụ gồm 2 phần: Trước tiên, bạn cần lắng nghe và nhận lượt nhấp, đồng thời xác định mục nào đã được nhấp. Sau đó, bạn cần phản hồi lượt nhấp bằng một hành động.

Vậy đâu là vị trí tốt nhất để thêm trình nghe lượt nhấp cho ứng dụng này?

  • SleepTrackerFragment lưu trữ nhiều khung hiển thị, vì vậy, việc theo dõi các sự kiện nhấp chuột ở cấp phân đoạn sẽ không cho bạn biết mục nào đã được nhấp. Thậm chí, bạn sẽ không biết đó là một mục được nhấp hay một trong những phần tử giao diện người dùng khác.
  • Khi nghe ở cấp RecyclerView, bạn khó có thể xác định chính xác mặt hàng mà người dùng đã nhấp vào trong danh sách.
  • Tốc độ tốt nhất để nhận thông tin về một mục đã nhấp là trong đối tượng ViewHolder, vì đối tượng này đại diện cho một mục trong danh sách.

Mặc dù ViewHolder là nơi tuyệt vời để nghe các lượt nhấp, nhưng thường không phải là nơi thích hợp để xử lý các lượt nhấp đó. Vậy đâu là nơi tốt nhất để xử lý các lượt nhấp?

  • Adapter hiển thị các mục dữ liệu trong thành phần hiển thị, vì vậy, bạn có thể xử lý các lượt nhấp trong trình chuyển đổi. Tuy nhiên, nhiệm vụ của trình chuyển đổi là điều chỉnh dữ liệu để hiển thị chứ không phải xử lý logic của ứng dụng.
  • Thường thì bạn nên xử lý các lượt nhấp trong ViewModel, vì ViewModel có quyền truy cập vào dữ liệu và logic để xác định việc cần xảy ra để phản hồi lượt nhấp.

Bước 1: Tạo một trình nghe lượt nhấp và kích hoạt trình nghe đó từ bố cục mục

  1. Trong thư mục sleeptracker, hãy mở SleepNightAdapter.kt.
  2. Ở cuối tệp, ở cấp cao nhất, hãy tạo một lớp trình nghe mới, SleepNightListener.
class SleepNightListener() {
    
}
  1. Bên trong lớp SleepNightListener, hãy thêm một hàm onClick(). Khi người dùng nhấp vào khung hiển thị hiển thị một mục trong danh sách, khung hiển thị sẽ gọi hàm onClick() này. (Sau này, bạn sẽ đặt thuộc tính android:onClick của khung hiển thị thành hàm này.)
class SleepNightListener() {
    fun onClick() = 
}
  1. Thêm một đối số hàm night thuộc kiểu SleepNight vào onClick(). Khung hiển thị biết mục mà nó đang hiển thị và thông tin đó cần được truyền đi để xử lý lượt nhấp.
class SleepNightListener() {
    fun onClick(night: SleepNight) = 
}
  1. Để xác định chức năng của onClick(), hãy cung cấp một lệnh gọi lại clickListener trong hàm khởi tạo của SleepNightListener và chỉ định lệnh gọi lại đó cho onClick().

    Đặt tên cho lambda xử lý lượt nhấp, clickListener , giúp theo dõi lambda khi lambda được truyền giữa các lớp. Lệnh gọi lại clickListener chỉ cần night.nightId để truy cập vào dữ liệu trong cơ sở dữ liệu. Lớp SleepNightListener đã hoàn tất của bạn sẽ có dạng như mã bên dưới.
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
   fun onClick(night: SleepNight) = clickListener(night.nightId)
}
  1. Mở list_item_sleep_night.xml..
  2. Bên trong khối data, hãy thêm một biến mới để cung cấp lớp SleepNightListener thông qua tính năng liên kết dữ liệu. Đặt name của <variable> mới thành clickListener.. Đặt type thành tên đủ điều kiện của lớp com.example.android.trackmysleepquality.sleeptracker.SleepNightListener, như minh hoạ bên dưới. Giờ đây, bạn có thể truy cập vào hàm onClick() trong SleepNightListener từ bố cục này.
<variable
            name="clickListener"
            type="com.example.android.trackmysleepquality.sleeptracker.SleepNightListener" />
  1. Để theo dõi các lượt nhấp vào bất kỳ phần nào của mục trong danh sách này, hãy thêm thuộc tính android:onClick vào ConstraintLayout.

    Đặt thuộc tính thành clickListener:onClick(sleep) bằng cách sử dụng một hàm lambda liên kết dữ liệu, như minh hoạ dưới đây:
android:onClick="@{() -> clickListener.onClick(sleep)}"

Bước 2: Truyền trình nghe lượt nhấp đến trình giữ khung hiển thị và đối tượng liên kết

  1. Mở SleepNightAdapter.kt.
  2. Sửa đổi hàm khởi tạo của lớp SleepNightAdapter để nhận val clickListener: SleepNightListener. Khi liên kết ViewHolder, bộ chuyển đổi sẽ cần cung cấp trình nghe lượt nhấp này.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  1. Trong onBindViewHolder(), hãy cập nhật lệnh gọi đến holder.bind() để truyền trình nghe lượt nhấp đến ViewHolder. Bạn sẽ gặp lỗi trình biên dịch vì đã thêm một tham số vào lệnh gọi hàm.
holder.bind(getItem(position)!!, clickListener)
  1. Thêm tham số clickListener vào bind(). Để thực hiện việc này, hãy đặt con trỏ vào lỗi rồi nhấn Alt+Enter (Windows) hoặc Option+Enter (Mac) vào lỗi, như trong ảnh chụp màn hình bên dưới.

  1. Bên trong lớp ViewHolder, bên trong hàm bind(), hãy chỉ định trình nghe lượt nhấp cho đối tượng binding. Bạn sẽ thấy lỗi vì cần cập nhật đối tượng liên kết.
binding.clickListener = clickListener
  1. Để cập nhật liên kết dữ liệu, hãy Dọn dẹpTạo lại dự án của bạn. (Bạn cũng có thể cần phải vô hiệu hoá bộ nhớ đệm.) Vì vậy, bạn đã lấy một trình nghe lượt nhấp từ hàm khởi tạo của bộ chuyển đổi và truyền trình nghe đó đến ngăn chứa khung hiển thị và vào đối tượng liên kết.

Bước 3: Hiện thông báo khi một mục được nhấn

Giờ đây, bạn đã có mã để ghi lại lượt nhấp, nhưng bạn chưa triển khai những gì sẽ xảy ra khi một mục trong danh sách được nhấn. Phản hồi đơn giản nhất là hiển thị một thông báo tạm thời cho biết nightId khi người dùng nhấp vào một mục. Điều này xác minh rằng khi người dùng nhấp vào một mục trong danh sách, nightId chính xác sẽ được ghi lại và truyền đi.

  1. Mở SleepTrackerFragment.kt.
  2. Trong onCreateView(), hãy tìm biến adapter. Lưu ý rằng phương thức này cho thấy một lỗi vì hiện tại, phương thức này cần một tham số trình nghe lượt nhấp.
  3. Xác định trình nghe lượt nhấp bằng cách truyền một lambda vào SleepNightAdapter. Lambda đơn giản này chỉ hiển thị một thông báo ngắn cho biết nightId, như minh hoạ dưới đây. Bạn phải nhập Toast. Dưới đây là định nghĩa đầy đủ và mới nhất.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
   Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})
  1. Chạy ứng dụng, nhấn vào các mục và xác minh rằng các mục đó hiển thị thông báo nhanh có nightId chính xác. Vì các mục có giá trị nightId tăng dần và ứng dụng hiển thị đêm gần đây nhất trước tiên, nên mục có nightId thấp nhất nằm ở cuối danh sách.

Trong nhiệm vụ này, bạn sẽ thay đổi hành vi khi người dùng nhấp vào một mục trong RecyclerView, sao cho thay vì hiển thị thông báo, ứng dụng sẽ chuyển đến một mảnh chi tiết cho biết thêm thông tin về đêm đã nhấp.

Bước 1: Điều hướng khi nhấp

Trong bước này, thay vì chỉ hiển thị một thông báo ngắn, bạn sẽ thay đổi lambda của trình nghe lượt nhấp trong onCreateView() của SleepTrackerFragment để truyền nightId đến SleepTrackerViewModel và kích hoạt thao tác điều hướng đến SleepDetailFragment.

Xác định hàm trình xử lý lượt nhấp:

  1. Mở SleepTrackerViewModel.kt.
  2. Bên trong SleepTrackerViewModel, gần cuối, hãy xác định hàm trình xử lý lượt nhấp onSleepNightClicked().
fun onSleepNightClicked(id: Long) {

}
  1. Bên trong onSleepNightClicked(), hãy kích hoạt thao tác điều hướng bằng cách đặt _navigateToSleepDetail thành id được truyền vào của đêm ngủ đã nhấp.
fun onSleepNightClicked(id: Long) {
   _navigateToSleepDetail.value = id
}
  1. Triển khai _navigateToSleepDetail. Như bạn đã làm trước đây, hãy xác định một private MutableLiveData cho trạng thái điều hướng. Và một val có thể truy cập công khai đi kèm.
private val _navigateToSleepDetail = MutableLiveData<Long>()
val navigateToSleepDetail
   get() = _navigateToSleepDetail
  1. Xác định phương thức cần gọi sau khi ứng dụng hoàn tất quá trình điều hướng. Gọi nó là onSleepDetailNavigated() và đặt giá trị của nó thành null.
fun onSleepDetailNavigated() {
    _navigateToSleepDetail.value = null
}

Thêm mã để gọi trình xử lý lượt nhấp:

  1. Mở SleepTrackerFragment.kt rồi di chuyển xuống mã tạo bộ chuyển đổi và xác định SleepNightListener để hiện thông báo.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
   Toast.makeText(context, "${nightId}", Toast.LENGTH_LONG).show()
})
  1. Thêm đoạn mã sau bên dưới thông báo tạm thời để gọi trình xử lý lượt nhấp, onSleepNighClicked(), trong sleepTrackerViewModel khi một mục được nhấn. Truyền nightId để mô hình chế độ xem biết được đêm ngủ nào cần lấy. Bạn sẽ gặp lỗi vì chưa xác định onSleepNightClicked(). Bạn có thể giữ, chú thích hoặc xoá thông báo này tuỳ ý.
sleepTrackerViewModel.onSleepNightClicked(nightId)

Thêm mã để theo dõi lượt nhấp:

  1. Mở SleepTrackerFragment.kt.
  2. Trong onCreateView(), ngay phía trên phần khai báo manager, hãy thêm mã để theo dõi navigateToSleepDetail LiveData mới. Khi navigateToSleepDetail thay đổi, hãy chuyển đến SleepDetailFragment, truyền vào night, sau đó gọi onSleepDetailNavigated(). Vì bạn đã thực hiện việc này trong một lớp học lập trình trước, nên đây là mã:
sleepTrackerViewModel.navigateToSleepDetail.observe(this, Observer { night ->
            night?.let {
              this.findNavController().navigate(
                        SleepTrackerFragmentDirections
                                .actionSleepTrackerFragmentToSleepDetailFragment(night))
               sleepTrackerViewModel.onSleepDetailNavigated()
            }
        })
  1. Chạy mã, nhấp vào một mục và ... ứng dụng gặp sự cố.

Xử lý các giá trị rỗng trong trình chuyển đổi liên kết:

  1. Chạy lại ứng dụng ở chế độ gỡ lỗi. Nhấn vào một mục rồi lọc nhật ký để chỉ hiện Lỗi. Thao tác này sẽ cho thấy một dấu vết ngăn xếp, bao gồm cả nội dung như bên dưới.
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter item

Rất tiếc, dấu vết ngăn xếp không cho thấy rõ nơi kích hoạt lỗi này. Một nhược điểm của tính năng liên kết dữ liệu là tính năng này có thể khiến bạn khó gỡ lỗi mã hơn. Ứng dụng gặp sự cố khi bạn nhấp vào một mục và mã mới duy nhất là để xử lý lượt nhấp.

Tuy nhiên, hoá ra với cơ chế xử lý lượt nhấp mới này, giờ đây, các phương thức điều hợp liên kết có thể được gọi bằng giá trị null cho item. Cụ thể, khi ứng dụng khởi động, LiveData sẽ bắt đầu dưới dạng null, vì vậy, bạn cần thêm các chế độ kiểm tra giá trị rỗng vào từng bộ chuyển đổi.

  1. Trong BindingUtils.kt, đối với mỗi bộ điều hợp liên kết, hãy thay đổi loại đối số item thành có thể rỗng và bao bọc nội dung bằng item?.let{...}. Ví dụ: trình chuyển đổi cho sleepQualityString sẽ có dạng như sau. Tương tự, hãy thay đổi các bộ chuyển đổi khác.
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight?) {
   item?.let {
       text = convertNumericQualityToString(item.sleepQuality, context.resources)
   }
}
  1. Chạy ứng dụng của bạn. Nhấn vào một mục và một chế độ xem chi tiết sẽ mở ra.

Dự án Android Studio: RecyclerViewClickHandler.

Để các mục trong RecyclerView phản hồi với lượt nhấp, hãy đính kèm trình nghe lượt nhấp vào các mục trong danh sách trong ViewHolder và xử lý lượt nhấp trong ViewModel.

Để các mục trong RecyclerView phản hồi với lượt nhấp, bạn cần làm như sau:

  • Tạo một lớp trình nghe nhận một lambda và chỉ định lambda đó cho một hàm onClick().
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) {
   fun onClick(night: SleepNight) = clickListener(night.nightId)
}
  • Thiết lập trình nghe lượt nhấp trên khung hiển thị.
android:onClick="@{() -> clickListener.onClick(sleep)}"
  • Truyền trình nghe lượt nhấp vào hàm khởi tạo của bộ điều hợp, vào trình giữ khung hiển thị và thêm trình nghe đó vào đối tượng liên kết.
class SleepNightAdapter(val clickListener: SleepNightListener):
       ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()
holder.bind(getItem(position)!!, clickListener)
binding.clickListener = clickListener
  • Trong mảnh hiển thị khung hiển thị tái chế, nơi bạn tạo trình chuyển đổi, hãy xác định một trình nghe lượt nhấp bằng cách truyền một lambda đến trình chuyển đổi.
val adapter = SleepNightAdapter(SleepNightListener { nightId ->
      sleepTrackerViewModel.onSleepNightClicked(nightId)
})
  • Triển khai trình xử lý lượt nhấp trong view model. Đối với các lượt nhấp vào mục trong danh sách, thao tác này thường kích hoạt hoạt động điều hướng đến một mảnh chi tiết.

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

Giả sử ứng dụng của bạn chứa một RecyclerView hiển thị các mặt hàng trong danh sách mua sắm. Ứng dụng của bạn cũng xác định một lớp trình nghe lượt nhấp:

class ShoppingListItemListener(val clickListener: (itemId: Long) -> Unit) {
    fun onClick(cartItem: CartItem) = clickListener(cartItem.itemId)
}

Làm cách nào để cung cấp ShoppingListItemListener cho tính năng liên kết dữ liệu? Hãy chọn một danh mục.

▢ Trong tệp bố cục chứa RecyclerView hiển thị danh sách mua sắm, hãy thêm một biến <data> cho ShoppingListItemListener.

▢ Trong tệp bố cục xác định bố cục cho một hàng trong danh sách mua sắm, hãy thêm một biến <data> cho ShoppingListItemListener.

▢ Trong lớp ShoppingListItemListener, hãy thêm một hàm để bật tính năng liên kết dữ liệu:

fun onBinding (cartItem: CartItem) {dataBindingEnable(true)}

▢ Trong lớp ShoppingListItemListener, bên trong hàm onClick(), hãy thêm một lệnh gọi để bật tính năng liên kết dữ liệu:

fun onClick(cartItem: CartItem) = { 
    clickListener(cartItem.itemId)
    dataBindingEnable(true)
}

Câu hỏi 2

Bạn thêm thuộc tính android:onClick ở đâu để các mục trong RecyclerView phản hồi với lượt nhấp? Hãy chọn mọi câu trả lời phù hợp.

▢ Trong tệp bố cục hiển thị RecyclerView, hãy thêm tệp đó vào <androidx.recyclerview.widget.RecyclerView>

▢ Thêm vào tệp bố cục cho một mục trong hàng. Nếu bạn muốn toàn bộ mục có thể nhấp vào được, hãy thêm mục đó vào chế độ xem gốc chứa các mục trong hàng.

▢ Thêm vào tệp bố cục cho một mục trong hàng. Nếu bạn muốn nhấp được một TextView trong mục, hãy thêm vào <TextView>.

▢ Luôn thêm vào tệp bố cục cho MainActivity.

Bắt đầu bài học tiếp theo: 7.5: Tiêu đề trong RecyclerView