Làm thế nào để bổ sung tính năng Item Click cho RecyclerView ?
Trước tiên , cho những ai chưa biết Recycler View là gì , mình xin trích dẫn từ tài liệu "danh môn chính phái" của Google Developer Widget RecyclerView là một phiên bản nâng cao và linh hoạt hơn của ListView. Widget này là một bộ chứa để hiển thị các tập dữ liệu lớn có thể được cuộn rất hiệu ...
Trước tiên , cho những ai chưa biết Recycler View là gì , mình xin trích dẫn từ tài liệu "danh môn chính phái" của Google Developer
Widget RecyclerView là một phiên bản nâng cao và linh hoạt hơn của ListView. Widget này là một bộ chứa để hiển thị các tập dữ liệu lớn có thể được cuộn rất hiệu quả bằng cách duy trì một số dạng xem hữu hạn. Sử dụng widget RecyclerView khi bạn có các bộ sưu tập dữ liệu với phần tử thay đổi vào thời gian chạy dựa vào hành động của người dùng hoặc sự kiện mạng.
Ok , đọc sơ qua vậy chúng ta tạm hiểu là 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.
Nhưng có cái trắc trở là , hoặc có thể kiến thức của mình hạn hẹp , 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ì chịu sao ?
Không sao , trong bài hướng dẫn nhỏ này , mình xin chia sẻ với các bạn 1 tips
Đầu tiên , tạo 1 dự án , add Support Design library vào gradle , trong này có cả RecyclerView rồi , nếu 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_awidth="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_awidth="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 cái 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_awidth="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_awidth="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
Vậy là ta đã xong phần vỏ , giờ là phần ruột nè , tạo 1 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
lass 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