前言:
最近比較有空,把之前做的一些東西整理一下。其中還有一個RecyclerView的外接點擊事件,就是模擬ListView的setOnItemClickListener的方法。
RecyclerView的點擊事件通常都直接寫在onBindViewHolder內,直接對holder內的元件寫onClick。
但如果要拉到activity內寫就要額外製作了。
我把上一部的DEMO拿來做示範。
DEMO下載: https://drive.google.com/open?id=0Byk75IYx-dKXNXEzdzlzUEwzc3M
今日實作
簡單步驟:
一、在RecyclerView內holder這個方法必須implements View.OnClickListener 寫onClick方法二、寫interface方法,在方法內寫onClickHello 抓取view和position
三、在RecyclerView內宣告剛剛寫的interface這方法
四、寫setListener讓activity使用回調
五、在holder內註冊你元件的監聽事件
完成!
這樣就可以在activity內調用adapter的點擊事件了
一、在RecyclerViewAdapter內holder這個方法必須implements View.OnClickListener 寫onClick方法
//1、implements View.OnClickListener 寫onClick方法 class dataHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private ImageView imageView; private TextView textView; public dataHolder(View itemView) { super(itemView); imageView = (ImageView) itemView.findViewById(R.id.image_view); textView = (TextView) itemView.findViewById(R.id.text_view); //5、註冊監聽事件 itemView.setOnClickListener(this); textView.setOnClickListener(this); } @Override public void onClick(View view) { if (clickListener != null) clickListener.onClickHello(view, getAdapterPosition()); } }二、寫interface方法,在方法內寫onClickHello 抓取view和position
寫在RecyclerViewAdapter內。
//2、寫interface 方法 在方法內寫onClcikHello 抓取view和position public interface onItemClickListener { void onClickHello(View view, int position); }
三、在RecyclerView內宣告剛剛寫的interface這方法
private onItemClickListener clickListener;//3、在元件這註冊
四、寫setListener讓activity使用回調
//4、寫setListener讓activity使用回調 public void setOnItemClickListener(onItemClickListener listener) { this.clickListener = listener; }
五、在holder內註冊你元件的監聽事件
//1、implements View.OnClickListener 寫onClick方法 class dataHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private ImageView imageView; private TextView textView; public dataHolder(View itemView) { super(itemView); imageView = (ImageView) itemView.findViewById(R.id.image_view); textView = (TextView) itemView.findViewById(R.id.text_view); //5、註冊監聽事件 itemView.setOnClickListener(this); textView.setOnClickListener(this); } @Override public void onClick(View view) { if (clickListener != null) clickListener.onClickHello(view, getAdapterPosition()); } }
Adapter完成後,讓我們把畫面轉到MainActivity.java內,開始使用它吧!
dataAdapter.setOnItemClickListener(new DataAdapter.onItemClickListener() { @Override public void onClickHello(View view, final int position) { Toast.makeText(MainActivity.this, "點擊事件position = " + position, Toast.LENGTH_SHORT).show(); } });
完整Adapter程式碼:
class DataAdapter extends RecyclerView.Adapter<DataAdapter.dataHolder> implements Filterable { private final static String TAG = DataAdapter.class.getSimpleName(); //元件 private Context context; private ArrayList<Data> datalists;//是會變動的陣列,用來顯示正個recyclerView的資料 private ArrayList<Data> filterDatas;//固定陣列,用來和filter比對用的。 private MyFliter myFliter;//讓mainActivity能使用adapter呼叫篩選功能 private onItemClickListener clickListener;//3、在元件這註冊 //2、寫interface 方法 在方法內寫onClcikHello 抓取view和position public interface onItemClickListener { void onClickHello(View view, int position); } //4、寫setListener讓activity使用回調 public void setOnItemClickListener(onItemClickListener listener) { this.clickListener = listener; } //建構子 public DataAdapter(Context context) { this.context = context; } //implements Filterable的必定覆寫的方法,讓我們在activity內能呼叫他 @Override public Filter getFilter() { if (myFliter == null) { myFliter = new MyFliter(); } return myFliter; } //1、implements View.OnClickListener 寫onClick方法 class dataHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private ImageView imageView; private TextView textView; public dataHolder(View itemView) { super(itemView); imageView = (ImageView) itemView.findViewById(R.id.image_view); textView = (TextView) itemView.findViewById(R.id.text_view); //5、註冊監聽事件 itemView.setOnClickListener(this); textView.setOnClickListener(this); } @Override public void onClick(View view) { if (clickListener != null) clickListener.onClickHello(view, getAdapterPosition()); } } //讓我們在activity內能讀取或更新adapter內data的資料 public void setData(ArrayList<Data> datalists) { this.datalists = datalists; filterDatas = datalists; notifyDataSetChanged(); } @Override public DataAdapter.dataHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); dataHolder dh = new dataHolder(view); return dh; } @Override public void onBindViewHolder(DataAdapter.dataHolder holder, int position) { Glide.with(context) .load(datalists.get(position).getImageUrl()) .placeholder(R.drawable.default_image) .into(holder.imageView); if (!TextUtils.isEmpty(datalists.get(position).getTitle())) holder.textView.setText(datalists.get(position).getTitle()); else holder.textView.setText("暫無資料"); } @Override public int getItemCount() { return datalists == null ? 0 : datalists.size(); } //實作自己的篩選Filter class MyFliter extends Filter { @Override protected FilterResults performFiltering(CharSequence filterContent) { ArrayList<Data> filterData = new ArrayList<>(); //先判斷filterContent是不是null才進入 if (filterContent != null && filterContent.toString().trim().length() > 0) { Log.d(TAG, "確認是否為空值。 filterData.size = " + filterData.size()); //這回圈是在判斷你輸入的文字(filterContent)是否有在filterDatas陣列內有相關的文字,逐條搜尋。 for (int i = 0; i < filterDatas.size(); i++) { String content = filterDatas.get(i).getTitle(); Log.d(TAG, "確認是否進入for迴圈 content = " + content); if (content.contains(String.valueOf(filterContent))) { Log.d(TAG, "確認輸入文字是否相同。"); Data data = new Data(); data.setImageUrl(filterDatas.get(i).getImageUrl()); data.setTitle(filterDatas.get(i).getTitle()); filterData.add(data); } } } else { filterData = filterDatas; Log.d(TAG, "確認什麼都沒打 filterDatas = datalists = " + filterData.size()); } FilterResults filterResults = new FilterResults(); filterResults.count = filterData.size(); filterResults.values = filterData; Log.d(TAG, "final size = " + filterResults.count); return filterResults; } @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) { datalists = (ArrayList<Data>) filterResults.values; if (filterResults.count > 0) { notifyDataSetChanged(); } else { Data data = new Data(); data.setTitle("沒有結果"); datalists.add(data); notifyDataSetChanged(); } } } }
請問:不要寫點擊事件,是要能點擊後開啟另一個activity,要怎麼寫呢???
回覆刪除謝謝。
兩種做法
回覆刪除一、寫點擊事件,然後再A actiity內調用,然後startActivity(...);開啟另外一個activity
二、直接在RecyclerView Adapter內的onBindViewHolder直接對你的item做onClicklistener。
在調用Adapter的時候要順便把Context這參數帶到Adapter內
ex: MyAdapter ma = new MyAdapter(context);
然後在onClickListner內使用 context.startActivity(...);
您好,
回覆刪除請問如何在點擊時取得Item內容? 如, Item內有多個textView,點擊後目前可以取得position,但是被點的該列內容該如何取得呢?
謝謝
在上述的程式碼中 onClickHello 更改參數 帶入你要的data
刪除public interface onItemClickListener {
刪除void onClickHello(View view, int position,data);
}