Lập trình với Recyclerview trong Android – Bài 1

Hiện nay bất kỳ app nào có hiển thị dữ liệu dạng danh sách hay grid thì 100% app đó sử dụng Recyclerview bởi vì nó là cái tiên tiến nhất mà Google cung cấp cho ta làm việc với Android.

Khi làm việc với iOS thì chắc chắn bạn phải thành thạo Tableview và tương tự vậy trong Android bạn phải thành thạo Recyclerview. Trong series này mình gọi Recyclerview là danh sách.

Đô Trịnh chấm com rất hào hứng khi chia sẻ với bạn series về chủ đề quan trọng này dù để draft từ rất lâu rồi :). Theo dõi và thực hành theo chắc chắn chúng ta sẽ thành công.

Bài viết đầu tiên trong series này chúng ta sẽ tiến hành cài đặt và hiển thị một danh sách đơn giản chỉ có tên, trong các bài tới chúng ta sẽ hiển thị danh sách phức tạp hơn như giao diện chat, giao diện của Facebook… những giao diện mà chúng ta hay bắt gặp.

Ví dụ đây tường cá nhân Facebook họ cũng dùng Recyclerview:

Lập trình với Recyclerview trong Android

Lập trình với Recyclerview trong Android

Lập trình với Recyclerview trong Android
Lập trình với Recyclerview trong Android

Hay chính Play Store họ cũng đang dùng:

Lập trình với Recyclerview trong Android
Lập trình với Recyclerview trong Android

Công cụ phát triển ở đây mình sẽ dùng:

  • Hệ điều hành macOS 10.14 mới nhất.
  • Android Studio 3.5 Beta 3 mới nhất.
  • Recyclerview-v7:28 mới nhất.
  • Ngôn ngữ Java (Nếu bạn thích dùng Kotlin thì cũng tương tự thôi không khó đâu).

Nào bắt đầu thôi. Nhìn qua những thứ chúng ta phải làm:

  1. Cài Recyclerview.
  2. Nhúng Recyclerview vào activity_main.xml.
  3. Thiết kế giao diện cho 1 row trong Recyclerview.
  4. Cài đặt Adapter để hiển thị Recyclerview.

Cài đặt Recyclerview

Đầu tiên chúng ta cần phải cài Recyclerview thông qua Gradle một cách tự động, để cài chỉ cần thêm vào file Gradle (Recyclerview/app/build.gradle) của ứng dụng như sau:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:cardview-v7:28.0.0'
}

Bên cạnh Recyclerview chúng ta cũng cài thêm Constraint Layout để hỗ trợ thiết kế nhiều màn hình – rất tiện lợi, Cardview để hỗ trợ thiết kế giao diện từng row trong Recyclerview.

Nhúng Recyclerview vào activity_main.xml

Sau khi cài đặt chúng ta cần nhúng RecyclerView vào nơi mà danh sách sẽ được hiển thị.

Tạo file activity_main.xml ở đường dẫn Recyclerview/app/src/main/res/layout/activity_main.xml  như sau:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@android:color/white">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Dotrinh.com"
        android:textColor="@android:color/black"
        android:textSize="33sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cùng với Recyclerview series"
        android:textColor="@android:color/black"
        android:textSize="23sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/myRecycleView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView2"
        tools:listitem="@layout/row_item" />
</android.support.constraint.ConstraintLayout>

Thiết kế giao diện cho 1 row trong Recyclerview

Tiếp đến ta sẽ thiết nội dung 1 row. Trong bài đầu tiên này chúng ta sẽ hiển thị tạm 1 dòng text đơn giản, trong bài sau hoặc bài sau nữa chúng ta sẽ kết hợp cả ảnh và text.

Ta tạo file row_item.xml tại Recyclerview/app/src/main/res/layout/row_item.xml với nội dung như sau:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:layout_margin="8dp"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    app:cardCornerRadius="11dp">


    <TextView
        android:id="@+id/rowItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginStart="20dp"
        android:text="test.com"
        android:textColor="@android:color/holo_blue_dark"
        android:textSize="23sp" />

</android.support.v7.widget.CardView>

Cài đặt Adapter

Adapter nghĩa là bộ điều hợp hoặc là bộ cung cấp dữ liệu giống như cục sạc cho laptop, mobile vậy.

Nghĩa bằng tiếng Việt khó diễn tả nên chúng ta cứ dùng luôn từ Adapter.

Tạo 1 inner class hoặc file tách biệt đều được, trong bài viết này mình sẽ tạo luôn trong MainActivity để đỡ phải chuyển tab qua chuyển tab lại.

Ta tạo file MainActivity.java như sau:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView myRecycleView = findViewById(R.id.myRecycleView);
        myRecycleView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        myRecycleView.setAdapter(new ChildAdapter());
    }

    public class ChildAdapter extends RecyclerView.Adapter<ChildAdapter.ChildViewHolder> {

        @Override
        public int getItemCount() {
            return 50;
        }

        public ChildAdapter.ChildViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item, parent, false);
            return new ChildViewHolder(itemView);

        }

        @Override
        public void onBindViewHolder(@NonNull ChildAdapter.ChildViewHolder holder, int position) { // Ham nay dc goi lai moi lan khi refresh recyclerview
            holder.rowItem.setText((position + 1) + " Dotrinh.com");
        }

        // VIEW HOLDER
        class ChildViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

            CardView card_view;
            TextView rowItem;

            ChildViewHolder(@NonNull View itemView) {
                super(itemView);
                card_view = itemView.findViewById(R.id.cardView);
                rowItem = itemView.findViewById(R.id.rowItem);
                card_view.setOnClickListener(this);
            }

            @Override
            public void onClick(View v) {
                LogI("OK" + getAdapterPosition());
            }
        }

    }
}

Mình sẽ giải thích như sau:

Trong hàm onCreate()

RecyclerView myRecycleView = findViewById(R.id.myRecycleView);
myRecycleView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
myRecycleView.setAdapter(new ChildAdapter());

Mục đích đoạn này là tìm cái RecyclerView, cấu hình layout cho nó dạng danh sách theo chiều dọc và không lộn ngược danh sách. Cuối dùng là set adapter cho nó bằng cái adapter mình đang tạo. Chúng ta có thể hiển thị dạng grid ở đây với đoạn code sau:

myRecycleView.setLayoutManager(new GridLayoutManager(this, 6)); 6 là số cột.

Ngoài cấu hình RecyclerView trong code java thì chúng ta có thể cấu hình trong xml như sau:

app:layoutManager="android.support.v7.widget.GridLayoutManager"
app:spanCount="2"
tools:layoutManager="GridLayoutManager"

Tiếp đến là class ChildAdapter

Có 4 thứ bắt buộc phải có đó là getItemCount, onCreateViewHolder, onBindViewHolder, ChildViewHolder.

Hàm getItemCount: là xác định số lượng row sẽ hiển thị trong toàn bộ RecyclerView. Nếu bạn lấy dữ liệu từ database thì cần count tại đây.

Hàm onCreateViewHolder: là hàm xác định xem tại dòng hiện tại đang được hiện trên màn hình sẽ sử dụng layout nào. Hàm này sẽ lấy layout của row mà mình đã tạo bên trên.

Hàm onBindViewHolder:

  • Khi mở RecyclerView lần đầu: Sẽ chạy từng dòng một, nếu màn hình hiển thị đc 6 dòng nó sẽ chạy 1 lúc 6 lần. Cái này phụ thuộc vào màn hình điện thoại từng người.
  • Sẽ chạy khi scroll, nếu scroll lên 1 dòng nó sẽ chạy 1 lần chứ ko chạy hết 6 lần, tương tự khi scroll xuống dưới. Đại khái là nó sẽ chạy lại khi cái dòng cần hiển thị chưa được hiển thị. Cách này sẽ giúp Android tối ưu và chạy mượt hơn, nếu ta load ra 1000 dòng hay 1 triệu dòng chắc chắn sẽ die app.
  • Ở đây ta có thể tìm các view như TextView, ImageView trong row đó để hiển thị dữ liệu từ database.

Lớp ChildViewHolder: dùng để tìm các view thực sự trong file xml và nghe ngóng sự kiện click hay touch.

Và bây giờ bạn build xem kết quả như thế nào.

Nếu bạn muốn nói gì đó hãy để lại comment chúng ta cùng trao đổi. Hẹn bạn ở bài tiếp theo trong chuỗi bài viết này.

Mã nguồn toàn bộ series mình đặt ở github, hãy checkout ở đây https://github.com/dotrinhdev/Recyclerview

Chúng ta tham khảo thêm ở đây:

https://developer.android.com/guide/topics/ui/layout/recyclerview

Xem toàn bộ bài viết liên quan đến chủ đề:

  1. Lập trình với Recyclerview trong Android – Bài 2
  2. Lập trình với Recyclerview trong Android – Bài 3
  3. Lập trình với Recyclerview trong Android – Bài 4 (Đang chuẩn bị)
  4. Lập trình với Recyclerview trong Android – Bài 5 (Đang chuẩn bị)

Các bài viết không xem thì tiếc:

Chia sẻ là sexy

Có 2 bình luận trong bài viết “Lập trình với Recyclerview trong Android – Bài 1”

Thảo luận

This site uses Akismet to reduce spam. Learn how your comment data is processed.