RecyclerView dùng để hiển thị danh sách dữ liệu lớn và được tối ưu hóa về bộ nhớ. Bản thân RecyclerView có sẵn LayoutManager để quản lý giao diện và sử dụng lớp Adapter riêng để gắn kết dữ liệu.
RecyclerView sử dung lớp ViewHolder để tham chiếu tới các view con của mỗi phần tử trong danh sách.
Các bước thực hành tạo RecyclerView để hiển thị danh sách sản phẩm đơn giản:
Bước 1: Tạo lớp đối tượng dữ liệu SanPham.java
public class SanPham {
public int id;
public String name;
public SanPham(int id, String name){
this.id = id;
this.name = name;
}
}
Bước 2: Thêm thẻ RecyclerView vào layout main và đặt ID là recyclerview01
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview01"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Bước 3: Tạo layout custom cho từng phần tử đặt tên là custom_item_layout.xml
file này cũng giống như tạo layout cho phần tử trong ListView thông thường. Nên sử dụng layout đơn giản, không nên dùng Relative hay Constraint layout vì nó sẽ gây chậm.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ccc"
android:layout_margin="10dp">
<TextView
android:id="@+id/tv_id"
android:textColor="#BC3636"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_name"
android:textColor="#2196F3"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
LinearLayout>
Bước 4: Tạo file SanPhamViewHolder.java
để làm ViewHolder cho RecyclerView. Lớp này phải kế thừa từ RecyclerView.ViewHolder. Bên trong hàm khởi tạo thì thực hiện ánh xạ các phần tử trong custom_item_layout (file này vừa tạo ở bước 3).
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class SanPhamViewHolder extends RecyclerView.ViewHolder {
public TextView tv_id;
public TextView tv_name;
public SanPhamViewHolder(@NonNull View itemView) {
super(itemView);
tv_id = itemView.findViewById(R.id.tv_id);
tv_name = itemView.findViewById(R.id.tv_name);
}
}
Bước 5: Tạo file adapter là SanPhamAdapter.java
để gắn dữ liệu lên view. Class này được kế thừa từ lớp RecyclerView.Adapter. Khi kế thừa phải chỉ ra kiểu dữ liệu cho từng phần tử trong danh sách. Ở đây đã khai báo lớp SanPhamViewHolder (ở bước 4) là đại diện cho từng phần tử của danh sách, nên adapter phải chỉ ra kiểu dữ liệu là lớp SanPhamViewHolder.
Xem thêm giải thích trong code:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
//Sử dụng Adapter của lớp RecyclerView và phải truyền vào kiểu cấu trúc của phần từng phần tử đó là SanPhamViewHolder
public class SanPhamAdapter extends RecyclerView.Adapter {
Context context;
ArrayList listSP;
// hàm khởi tạo để truyền vào context và danh sách sản phẩm
public SanPhamAdapter(Context ct, ArrayList ds ){
this.context = ct;
this.listSP = ds;
}
///onCreateViewHolder hàm khởi tạo layout cho recyclerview
@NonNull
@Override
public SanPhamViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
// sử dụng layout inflater để gắn file layout custom cho một biến view sau đó gán vào đối tượng Holder là SanPhamViewHOlder
View view_of_item = inflater.inflate(R.layout.custom_item_layout, parent,false);
SanPhamViewHolder sanPhamViewHolder = new SanPhamViewHolder(view_of_item);
return sanPhamViewHolder;
}
@Override
public void onBindViewHolder(@NonNull SanPhamViewHolder holder, int position) {
// hàm dùng gán dữ liệu cho viewHolder
SanPham sp = listSP.get(position); // lấy sản phẩm ở vị trí hiện tại
holder.tv_id.setText(sp.id +""); // cộng thêm chuỗi rỗng để nó tự chuyển id về kiểu chuỗi
holder.tv_name.setText(sp.name); // holder.tv_id, holder.tv_name: Là 2 cái textview
}
@Override
public int getItemCount() {
return listSP.size(); // trả về số lượng phần tử trong danh sách.
}
}
Bước 6: Xử lý trong MainActivity để hiển thị dữ liệu
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView ;
SanPhamAdapter sanPhamAdapter; // cần khai báo ở cấp độ class để sau dùng ở nhiều chỗ khác trong file MainAcitvity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//---------------------------------------
recyclerView = findViewById(R.id.recyclerview01); // ánh xạ view vào biến
// dùng đối tượng layout manager để quản lý
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//--- Tạo dữ liệu demo: Phần này bạn có thể sử dụng SQLite để lấy dữ liệu đưa lên một ArrayList
SanPham sp = new SanPham(1,"Điện thoại");
ArrayList list = new ArrayList();
list.add(sp);
SanPham sp2 = new SanPham(2,"Laptop Dell I7");
list.add(sp2);
SanPham sp3 = new SanPham(3,"Laptop Game MSI");
list.add(sp3);
// tạo adapter và gắn adapter cho recyclerView
sanPhamAdapter = new SanPhamAdapter(this,list);
recyclerView.setAdapter(sanPhamAdapter);
}
}
Chạy thử ứng dụng để xem kết quả.