Bổ sung tính năng Item Click cho RecyclerView trong Android
RecyclerView là 1 biến thể của ListView , nhưng được nâng cấp trở nên linh hoạt hơn , mạnh mẽ hơn nhiều. Tuy nhiên, RecyclerView không thấy bổ sung sự kiện OnItemClickListener , mà cái đó là vô cùng cần thiết , giả sử có 1 danh sách mà muốn tap vào để xem chi tiết thì phải làm sao ? Đừng lo, trong bài hướng dẫn nhỏ này , mình xin chia sẻ với các bạn 1 tips.
Các bước đầu tiên để tạo giao diện chứa RecyclerView
Bước đầu tiên đương nhiên là tạo một Project và add Support Design library vào gradle, trong này có cả RecyclerView rồi, nếu bạn muốn gọn nhẹ thì cài library Recycler riêng
Tiếp theo , add RecyclerView vào activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="edmt.dev.androidrecyclerviewclick.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Xong rồi , chúng ta hãy tạo 1 file layout_item_recyclerview.xml để custom giao diện của item hiển thị trong RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:padding="20dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtDescription"
android:text="Description"
android:textColor="#000"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Bắt tay vào để tạo tính năng Item Click cho RecyclerView
Bây giờ chúng ta tạo một interface đặt tên là "ItemClickListener"
public interface ItemClickListener {
void onClick(View view, int position,boolean isLongClick);
}
Và tất nhiên , RecyclerView không thể thiếu RecyclerView.Adapter được , mà thằng RecyclerView.Adapter lại không thể thiếu Recycler.ViewHolder được , ta phải tạo 2 thằng này luôn Tạo lớp RecyclerAdapter
package edmt.dev.androidrecyclerviewclick;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by reale on 2/22/2017.
*/
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener
{
public TextView txt_description;
private ItemClickListener itemClickListener;
public RecyclerViewHolder(View itemView) {
super(itemView);
txt_description = (TextView)itemView.findViewById(R.id.txtDescription);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener)
{
this.itemClickListener = itemClickListener;
}
@Override
public void onClick(View v) {
itemClickListener.onClick(v,getAdapterPosition(),false);
}
@Override
public boolean onLongClick(View v) {
itemClickListener.onClick(v,getAdapterPosition(),true);
return true;
}
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
private List<String> listData = new ArrayList<>();
private Context context;
public RecyclerAdapter(List<String> listData, Context context) {
this.listData = listData;
this.context = context;
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.layout_item_recycler_view,parent,false);
return new RecyclerViewHolder(itemView);
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.txt_description.setText(listData.get(position));
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onClick(View view, int position, boolean isLongClick) {
if(isLongClick)
Toast.makeText(context, "Long Click: "+listData.get(position), Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, " "+listData.get(position), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return listData.size();
}
}
Trong lớp này , chỉ cần chú ý đoạn này
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener // Implement 2 sự kiện onClick và onLongClick
{
public TextView txt_description; // Khai báo biến
private ItemClickListener itemClickListener; // Khai báo interface
public RecyclerViewHolder(View itemView) {
super(itemView);
txt_description = (TextView)itemView.findViewById(R.id.txtDescription); // tiến hành tìm view và assign địa chỉ
itemView.setOnClickListener(this); // Mấu chốt ở đây , set sự kiên onClick cho View
itemView.setOnLongClickListener(this); // Mấu chốt ở đây , set sự kiên onLongClick cho View
}
//Tạo setter cho biến itemClickListenenr
public void setItemClickListener(ItemClickListener itemClickListener)
{
this.itemClickListener = itemClickListener;
}
@Override
public void onClick(View v) {
itemClickListener.onClick(v,getAdapterPosition(),false); // Gọi interface , false là vì đây là onClick
}
@Override
public boolean onLongClick(View v) {
itemClickListener.onClick(v,getAdapterPosition(),true); // Gọi interface , true là vì đây là onLongClick
return true;
}
}
Ở trên ta có thể hiểu là , khi ViewHolder được gọi , nó sẽ inflate cái layout_item_recyclerview của chúng ta và chúng ta lợi dụng điểm này để set sự kiện onClick và onLongClick (nếu cần) cho nó
Sau đó , ở phương thức onBindViewHolder() của Adapter , chúng ta tiến hành hiện thực sự kiện onClick hoặc onLongClick
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
holder.txt_description.setText(listData.get(position));
holder.setItemClickListener(new ItemClickListener() {
@Override
public void onClick(View view, int position, boolean isLongClick) {
if(isLongClick)
Toast.makeText(context, "Long Click: "+listData.get(position), Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, " "+listData.get(position), Toast.LENGTH_SHORT).show();
}
});
}
Okay , và ở MainActivity ta chỉ việc code
package edmt.dev.androidrecyclerviewclick;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView.LayoutManager layoutManager;
private List<String> listData = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupList();
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
RecyclerAdapter adapter = new RecyclerAdapter(listData,this);
recyclerView.setAdapter(adapter);
}
private void setupList() {
for(int i = 1;i<=10;i++)
listData.add("Click me "+i);
}
}
Và kết quả :
Và các bạn có thể tha hồ mà replace Toast message với code của các bạn , có thể là chuyển activity , có thể xóa item... tùy ý
Chúc các bạn thành công!!!
Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!