Hướng dẫn RecyclerView trong Android- Phần 2: Layout và Adapter

0
297
Bài này thuộc phần 2 của 3 phần trong series Hướng dẫn toàn tập RecyclerView trong Android

RecyclerView-trong-android-p2

Như bài viết trước, mình đã giới thiệu kiến thức cơ bản về RecyclerView như tại sao lại sử dụng RecyclerView, ưu điểm và nhược điểm là gì? Và đừng quên download project mẫu mà mình tạo để cùng thực hành trong suốt series bài viết này nhé

Để tiếp series về RecyclerView, bài viết này mình tiếp tục tìm hiểu kỹ hơn về RecyclerView, Layout và cách tạo Adapter nhé

Tìm hiểu sơ lược về RecyclerView và Layouts

Sự xuất hiện của RecyclerView đã thay đổi mọi thứ. Mặc dù Adapter vẫn được sử dụng như ListView hay GridView. Tuy nhiên, có đôi chút thay đổi về việc tạo ViewHolders để lưu trữ các references view trong bộ nhớ.

Nhắc lại về cơ chế hoạt động của ViewHolders: Trong trường hợp bạn cần một View mới, nó sẽ tự động tạo ra ViewHolder object mới để inflate layout và giữ references đó (có thể hiểu như một dạng cache dữ liệu), hoặc nếu View đó đã được tạo trước đó thì nó sẽ tái sử dụng đối tượng từ stack.

Bây giờ bạn đã hiểu vì sao nó được gọi là một RecyclerView rồi chứ?

Một điều thú vị khác khi sử dụng RecyclerView là chúng có các animations mặc định mà bạn không cần tự tạo thêm.

Nhờ có ViewHolder, RecyclerView có thể biết chính xác animation nào được apply cho item nào. Ngoài ra, bạn có thể tạo ra animation của riêng bạn và apply chúng khi cần thiết.

Yếu tố cuối cùng và thú vị nhất của RecyclerView là LayoutManager. Đối tượng này xác định position của item trong RecyclerView và cho bạn biết khi nào cần tái sử dụng các item.

Layout Managers có ba thành phần mặc định:

  • LinearLayoutManager: danh sách các items của bạn trông giống như một ListView thông thường
  • GridLayoutManager: danh sách các items của bạn được định dạng kiểu lưới tương tự như GridView
  • StaggeredGridLayoutManager: danh sách các item của bạn được định dạng theo kiểu lưới so-le.

Và tất nhiên, từ yêu cầu thực tế nếu muốn thêm một chút tùy chỉnh, bạn cũng có thể tạo riêng mình một LayoutManager để sử dụng với RecyclerView.

Hy vọng rằng những điều trên sẽ giải đáp tất cả các thắc mắc của bạn. Bây giờ, vào nhiệm vụ chính nào!

Tạo RecyclerView

Để tạo một RecyclerView trong Android, bạn cần chia công việc thành  4 bước:

  1. Khai báo RecyclerView trong một layout và sau đó add reference trong Activity
  2. Tạo một layout XML tùy chỉnh cho RecyclerView để có thể sử dụng cho từng Items
  3. Tạo Viewholder cho các View items. Sau đó tạo Adapter để đổ dữ liệu vào các View item để hiển thị ra màn hình
  4. Gắn Adapter vào RecyclerView.

Bước thứ 1 có vẻ khá quen thuộc. Mở file layout activity_main.xml, và thêm đoạn mã dưới đây:

<android.support.v7.widget.RecyclerView
  android:id="@+id/recyclerView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:scrollbars="vertical"/>
Lưu ý: Bạn đang sử dụng v7 support library tương thích với các thiết bị cũ. Trong start project mà các bạn download ở trên thì mình đã thêm RecyclerView Support Library. Các bạn có thể kiểm tra trong build.gradle.

Mở MainActivity.kt khai báo những properties dưới đây ở đầu class

private lateinit var linearLayoutManager: LinearLayoutManager

onCreate(), thêm dòng dưới đây vào bên dưới hàm setContentView:

linearLayoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = linearLayoutManager

Android Studio sẽ nhắc bạn import gói kotlinx.android.synthetic.main.activity_main. *cho recyclerView. Bạn có thể thắc mắc làm thế nào để có reference đến recyclerView như mọi lần vẫn làm với Listview mà không tìm thấy view phía trên, đó có phải là findViewById ()?

Trong project mẫu của mình đã được cấu hình để sử dụng plugin Kotlin Android Extensions. Plugin này cho phép import views trong layout dưới dạng ” synthetic “.

import kotlinx.android.synthetic.main.activity_main.*

Với cách làm trên thì  recyclerView sẽ là extension property của  Activity và cũng cùng kiểu như được khai báo trong activity_main.xml. Plugin này loại bỏ khá nhiều mã boilerplate và giảm thiểu nguy cơ xảy ra lỗi. (Tuy nhiên, nếu bạn chưa quen với cách làm này thì vẫn có thể sử dụng hàm findViewById()thông thường để reference đến RecyclerView)

Như vậy, qua những đoạn code trên thì bạn đã hoàn thành việc khai báo và cấp phát bộ như cho RecyclerView và LayoutManager

Thiết kế layout cho mỗi RecyclerView Item

Ở bước này, công việc của chúng ta là thiết kế layout XML cho mỗi item trong đó. Công đoạn này hoàn toàn giống như khi sử dụng ListView hay GridView

Vào thư mục layout trong project và tạo một file layout mới với tên là recyclerview_item_row.xml và đặt root element là LinearLayout. Trong layout mới của bạn, thêm các phần tử XML sau:

<ImageView
    android:id="@+id/itemImage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="8dp"
    android:layout_weight="3"
    android:adjustViewBounds="true" />

<TextView
    android:id="@+id/itemDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="top|start"
    android:layout_marginTop="8dp"
    android:layout_weight="1"
    tools:text="Some date" />

<TextView
    android:id="@+id/itemDescription"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center|start"
    android:layout_weight="1"
    android:ellipsize="end"
    android:maxLines="5" />

Adapters: Sức mạnh của RecyclerView

Nhấn chuột phải vào thư mục com.raywenderlich.galacticon, chọn New > Kotlin File > Class và đặt tên nó là RecyclerAdapter và chọn kiểu là Class. Sau đó import thư viện hỗ trợ RecyclerView như bên dưới:

import android.support.v7.widget.RecyclerView

Chúng ta sẽ kế thừa (extend) từ RecyclerView.Adapter như sau:

class RecyclerAdapter : RecyclerView.Adapter<RecyclerAdapter.PhotoHolder>()  {}

Sau khi chúng ta chọn kế thừa RecyclerView.Adapter thì Android Studio sẽ yêu cầu bạn override những method bắt buộc. Để tự động tạo các method override đó, đơn giản là đưa chuột vào tên class bị gạch đỏ , sau đó nhấn Option + Return (hoặc Alt + Enter trên PC) để hiển thị menu. Chọn  Implement Methods:

5-Implements-RecyclerView-Adapter-Methods-650x382

Nhấn OK để xác nhận sẽ implement những methods đó.

6-Confirm-RecyclerView-Implemention-Methods-650x381

Những phương pháp này là những hàm để cấu hình và đổ dữ liệu ra View( cũng tương tự như ListView hay GridView). Sau khi chọn implement members thì vẫn còn một lỗi compiler – điều này là do adapter của bạn và các phương thức được yêu cầu xác định bằng cách sử dụng ViewHolder class( PhotoHolder) vẫn chưa được định nghĩa. Đây là điểm khác biệt với ListView, với RecyclerView trong Android thì ViewHolder class là bắt buộc trong adapter.

Với ListView/GridView thì để detect sự kiện click chúng ta sử dụng hàm onItemClickListener. Tuy nhiên,  RecyclerView không cung cấp hàm này. Vậy phải làm sao đây?

Công việc “lắng nghe” các actions bây giờ là trách nhiệm của Item này và các con của nó. Có vẻ giống như điều này làm tốn bộ nhớ hơn, nhưng bù lại, bạn sẽ có được quyền kiểm soát chi tiết và khả năng tùy biến tốt hơn đối với các actions.

Tiếp tục nhé, trong class RecyclerAdapter, thêm một biến có tên là photos để lưu trữ ảnh trong hàm khởi tạo chính:

class RecyclerAdapter(private val photos: ArrayList<Photo>) RecyclerView.Adapter<RecyclerAdapter.PhotoHolder>() {

Làm tốt lắm! Adapter của bạn hiện biết nơi chúng cần tìm dữ liệu. Chẳng mấy chốc bạn sẽ có một ArrayList chứa đầy những bức ảnh thiên văn đẹp nhất!

Tiếp theo, bạn sẽ viết code logic cho các phương thức được thêm tự động nhờ Android Studio trước đó.

Đầu tiên, hàm getItemCount()khá đơn giản và quen thuộc với ListViews hoặc GridViews.

Adapter cần biết tổng số lượng items cần hiển thị. Trong trường hợp này, nếu bạn muốn bộ adapter hiển thị mọi photo bạn đã tải xuống từ NASA’s API, bạn có thể viết code như sau:

override fun getItemCount() = photos.size

Như vậy, qua bài viết này chúng ta đã khởi tạo và cấu hình bước đầu cho Adapter, một thành phần quan trọng trong việc tạo RecyclerView. Bài viết tiếp theo, mình sẽ trình bày tiếp về ViewHolder. Tại sao phải cần đến ViewHolder và các implement ViewHolder trong RecylerView khác với ListView chỗ nào? Các bạn cùng đón đọc nhé

Xem tiếp các bài trong Series
Phần trước: Hướng dẫn toàn tập RecyclerView trong Android- Phần 1: IntroductionPhần kế tiếp: Hướng dẫn toàn tập RecyclerView trong Android- Phần 3: ViewHolder

Bình luận. Đặt câu hỏi cũng là một cách học

avatar
  Theo dõi bình luận  
Thông báo