前言:
最近比較有空,把之前做的一些東西整理一下。其中還有一個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);
}