欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中解決RecyclerView各種點(diǎn)擊事件的方法

 更新時(shí)間:2018年05月22日 10:09:16   作者:小小程序員Eric  
這篇文章主要介紹了Android中解決RecyclerView各種點(diǎn)擊事件的方法,完美解決RecyclerView點(diǎn)擊事件、長(zhǎng)按事件、子項(xiàng)點(diǎn)擊事件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

完美解決RecyclerView點(diǎn)擊事件、長(zhǎng)按事件、子項(xiàng)點(diǎn)擊事件

自從Google推出了RecyclerView之后,便可以完全取代ListView,個(gè)人感覺唯一的美中不足是對(duì)于itemView的各種點(diǎn)擊事件不夠完美。觀點(diǎn)只代表個(gè)人看法。應(yīng)最近項(xiàng)目需求實(shí)現(xiàn)itemView的子項(xiàng)點(diǎn)擊事件,便寫篇博客記錄一下,若是能夠幫到你,我深感榮幸。接下來,便對(duì)RecyclerView進(jìn)行簡(jiǎn)單的封裝,使得它更方便實(shí)現(xiàn)各種點(diǎn)擊事件。

我們都知道,對(duì)與RecyclerView的使用,是創(chuàng)建一個(gè)adapter類,然后在adapter類中再創(chuàng)建一個(gè)ViewHolder的內(nèi)部類。我們要做的,正是對(duì)這兩個(gè)類進(jìn)行封裝,讓其實(shí)現(xiàn)itemView點(diǎn)擊事件、長(zhǎng)按事件、子項(xiàng)點(diǎn)擊事件。

首先,我的處理方式是,對(duì)于開發(fā)者來說,只需要對(duì)adapter進(jìn)行setxxx()方法的調(diào)用,例如設(shè)置itemView的點(diǎn)擊事件:adapter.setOnRecyclerViewItemClickListener(...);對(duì)該方法傳入自定義的接口即可。也就是說,我們需要自定義一個(gè)adapter類。那我們就先創(chuàng)建一個(gè)類,命名為BaseRecylerAdapter,此后,我們也應(yīng)當(dāng)創(chuàng)建一個(gè)BaseViewHolder類,接下來開始搞事情。

BaseRecylerAdapter類

public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter<BaseViewHolder>
  implements View.OnClickListener
  ,View.OnLongClickListener {

 private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener;
 private OnRecyclerViewItemLongClickListener onRecyclerViewItemLongClickListener;
 private OnSubViewClickListener onSubViewClickListener;

 @Override
 public void onBindViewHolder(BaseViewHolder holder, int position) {
  holder.itemView.setTag(position);
  holder.onBind(position);
  if (onRecyclerViewItemClickListener != null) {
   holder.itemView.setOnClickListener(this);
  }
  if (onRecyclerViewItemLongClickListener != null) {
   holder.itemView.setOnClickListener(this);
  }
  if (onSubViewClickListener != null) {
   holder.setSubViewClickListener(onSubViewClickListener,position);
  }
 }

 public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener onRecyclerViewItemClickListener) {
  this.onRecyclerViewItemClickListener = onRecyclerViewItemClickListener;
 }

 public void setOnRecyclerViewItemLongClickListener(OnRecyclerViewItemLongClickListener onRecyclerViewItemLongClickListener) {
  this.onRecyclerViewItemLongClickListener = onRecyclerViewItemLongClickListener;
 }

 public void setOnSubViewClickListener(OnSubViewClickListener listener){
  this.onSubViewClickListener = listener;
 }

 @Override
 public void onClick(View v) {
  if (v.getTag() != null) {
   int position = (int) v.getTag();
   onRecyclerViewItemClickListener.onItemClick(position);
  }
 }

 @Override
 public boolean onLongClick(View v) {
  if (v.getTag() != null){
   int position = (int)v.getTag();
   onRecyclerViewItemLongClickListener.onItemLongClick(position);
  }
  return true;
 }

 public interface OnRecyclerViewItemClickListener {
  void onItemClick(int position);
 }

 public interface OnSubViewClickListener{
  void onSubViewClick(View v, int position);
 }

 public interface OnRecyclerViewItemLongClickListener {
  void onItemLongClick(int position);
 }

}

可以看到我們?cè)陬愔袆?chuàng)建了三個(gè)接口類

public interface OnRecyclerViewItemClickListener {
  void onItemClick(int position);
 }

 public interface OnSubViewClickListener{
  void onSubViewClick(View v, int position);
 }

 public interface OnRecyclerViewItemLongClickListener {
  void onItemLongClick(int position);
 }

這三個(gè)接口便是用于點(diǎn)擊事件的回調(diào),看名字就能分別出各自的功能。itemView的點(diǎn)擊回調(diào)public interface OnRecyclerViewItemClickListener,itemView的長(zhǎng)按public interface OnRecyclerViewItemLongClickListener,子項(xiàng)View的點(diǎn)擊回調(diào)public interface OnSubViewClickListener。都是點(diǎn)擊事件的處理,沒有點(diǎn)擊發(fā)送怎么行呢,對(duì)吧!所以,這個(gè)類還實(shí)現(xiàn)了View.OnClickListener View.OnLongClickListener 這兩個(gè)接口,本別實(shí)現(xiàn)itemView的點(diǎn)擊事件和長(zhǎng)按事件。

可以看到,BaseRecyclerAdapter繼承自RecyclerView.Adapter<BaseViewHolder>,此時(shí)我們只需要實(shí)現(xiàn)onBindViewHolder 這個(gè)方法即可。來分析這個(gè)方法。

@Override
 public void onBindViewHolder(BaseViewHolder holder, int position) {
  holder.itemView.setTag(position);
  holder.onBind(position);
  if (onRecyclerViewItemClickListener != null) {
   holder.itemView.setOnClickListener(this);
  }
  if (onRecyclerViewItemLongClickListener != null) {
   holder.itemView.setOnClickListener(this);
  }
  if (onSubViewClickListener != null) {
   holder.setSubViewClickListener(onSubViewClickListener,position);
  }
 }

可以看出 這個(gè)方法里都是操作我們自定義的BaseViewHolder類。接下來就是三個(gè)空判斷,也就是說,我們?nèi)羰菦]有設(shè)置相應(yīng)的點(diǎn)擊事件,就不會(huì)初始化對(duì)應(yīng)的點(diǎn)擊事件,這樣的處理方式還是很常見的。處理這個(gè)點(diǎn)擊事件最麻煩的就是position的問題,因此我們使用的技巧是,對(duì)View對(duì)象設(shè)置tag的方式。查看源碼便知道,View有個(gè)方法 setTag(Object obj); 我們就可以將對(duì)應(yīng)的position賦值給這個(gè)tag,我們使用View的getTag() 方法就可以得到對(duì)應(yīng)點(diǎn)擊View的position了。在BaseRecylerAdapter類實(shí)現(xiàn)的點(diǎn)擊接口和長(zhǎng)按接口就可以知道這樣的操作,類容如下。

 @Override
 public void onClick(View v) {
  if (v.getTag() != null) {
   int position = (int) v.getTag();
   onRecyclerViewItemClickListener.onItemClick(position);
  }
 }

 @Override
 public boolean onLongClick(View v) {
  if (v.getTag() != null){
   int position = (int)v.getTag();
   onRecyclerViewItemLongClickListener.onItemLongClick(position);
  }
  return true;
 }

BaseViewHolder類

public abstract class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
 private BaseRecyclerAdapter.OnSubViewClickListener onSubViewClickListener;
 public BaseViewHolder(View itemView) {
  super(itemView);
  findViewById(itemView);
 }

 /**
  * 傳入子項(xiàng)點(diǎn)擊事件所需參數(shù)
  * @param listener 自定義的接口
  * @param tagPosition tag
  */
 public void setSubViewClickListener(BaseRecyclerAdapter.OnSubViewClickListener listener, int tagPosition){
  this.onSubViewClickListener = listener;
  initSubViewClick(tagPosition);
 }

 /**
  * 通過id匹配控件(開發(fā)者自行實(shí)現(xiàn))
  * @param itemView 父布局
  */
 abstract protected void findViewById(View itemView);

 /**
  * 用于裝載數(shù)據(jù)(開發(fā)者自行實(shí)現(xiàn))
  * @param position 當(dāng)前位置
  */
 abstract protected void onBind(int position);

 /**
  * 初始化子項(xiàng)的點(diǎn)擊事件(為子項(xiàng)設(shè)置tag)
  * @param tagPosition tag
  */
 protected void initSubViewClick(int tagPosition){

 }

 /**
  * 實(shí)現(xiàn)子項(xiàng)點(diǎn)擊事件的轉(zhuǎn)發(fā)
  * @param v
  */
 @Override
 public void onClick(View v) {
  if (v.getTag() != null) {
   int position = (int) v.getTag();
   onSubViewClickListener.onSubViewClick(v,position);
  }
 }
}

這是個(gè)抽象類,也就是說,在使用的時(shí)候需要實(shí)現(xiàn)其中的抽象方法。為了邏輯清晰,我在這里寫了兩個(gè)抽象方法

/**
  * 通過id匹配控件(開發(fā)者自行實(shí)現(xiàn))
  * @param itemView 父布局
  */
 abstract protected void findViewById(View itemView);

 /**
  * 用于裝載數(shù)據(jù)(開發(fā)者自行實(shí)現(xiàn))
  * @param position 當(dāng)前位置
  */
 abstract protected void onBind(int position);

看注釋也就很清楚這兩個(gè)方法的作用是什么,這里就不多說了。

到此,我們已經(jīng)實(shí)現(xiàn)了itemView的點(diǎn)擊和長(zhǎng)按事件,接下來我們來實(shí)現(xiàn)對(duì)itemView子項(xiàng)的點(diǎn)擊事件。

在BaseViewHolder類中,也實(shí)現(xiàn)了一個(gè)View的點(diǎn)擊事件接口。子項(xiàng)的點(diǎn)擊方式和itemView的點(diǎn)擊事件是一樣的套路,使用tag。接下來我們來看個(gè)例子,就明白了。

public class RecyclerAdapterMyActivity extends BaseRecyclerAdapter{
 private List<MyActivityBean> list;
 public RecyclerAdapterMyActivity(List<MyActivityBean>list){
  this.list = list;
 }


 @Override
 public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_myactivity_activity,parent,false);
  ViewHolder holder = new ViewHolder(view);
  return holder;
 }


 @Override
 public int getItemCount() {
  return list.size();
 }

 public class ViewHolder extends BaseViewHolder {
  private TextView tv_name,tv_title,tv_content;
  private Button activityBtnChat;
  private Button activityBtnCancel;
  ViewHolder(View itemView) {
   super(itemView);
  }

  @Override
  protected void findViewById(View itemView) {
   tv_name = itemView.findViewById(R.id.tv_my_activity_name);
   tv_title = itemView.findViewById(R.id.tv_my_activity_title);
   tv_content = itemView.findViewById(R.id.tv_my_activity_content);
   activityBtnChat = itemView.findViewById(R.id.activity_btn_chat);
   activityBtnCancel = itemView.findViewById(R.id.activity_btn_cancel);

  }

  @Override
  protected void onBind(int position) {
   MyActivityBean bean = list.get(position);
   tv_name.setText(bean.getName());
   tv_title.setText(bean.getTitle());
   tv_content.setText(bean.getContent());
  }

  @Override
  protected void initSubViewClick(int tagPosition) {
   activityBtnChat.setTag(tagPosition);
   activityBtnCancel.setTag(tagPosition);
   activityBtnChat.setOnClickListener(this);
   activityBtnCancel.setOnClickListener(this);
  }
 }
}

這段代碼是最近項(xiàng)目中的一小段代碼。其中,adapter類繼承BaseRecyclerAdapter,viewHolder類繼承BaseViewHolder。尤其要注意的是ViewHolder的構(gòu)造方法中一定要有super(itemView); 其余的方法都會(huì)按照正確的邏輯執(zhí)行。若要實(shí)現(xiàn)itemView的子項(xiàng)點(diǎn)擊事件,需要重寫父類的initSubViewClick(int tagPosition) ; 方法。其中參數(shù)tagPosition便是對(duì)應(yīng)的itemVIew處于RecyclerView中的位置。在這里是為兩個(gè)button添加點(diǎn)擊事件,先為其設(shè)置tag,再設(shè)置點(diǎn)擊事件,我們這里的setOnClickListener(this) ;  參數(shù)傳的是this,是因?yàn)?,我們?cè)俑割愔袑?shí)現(xiàn)了View的onClick(View v); 方法。

這樣,我們便完成了各類點(diǎn)擊事件。

使用方法也很簡(jiǎn)單,就是直接操作你的adapter就可以了,調(diào)用adapter.setXxxx(...) 即可方便地實(shí)現(xiàn)各種點(diǎn)擊事件。當(dāng)然,要是你地需求是Touchu事件,或子項(xiàng)地長(zhǎng)按事件等,都可以通過這樣類似地方式來實(shí)現(xiàn)。

最后

方法不止一種,這樣地操作方式,這只是我的一種思考。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • com.android.support版本沖突解決方法

    com.android.support版本沖突解決方法

    在本篇文章里小編給大家整理的是關(guān)于com.android.support版本沖突解決方法以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-09-09
  • Android實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼功能

    Android實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼功能

    這篇文章主要介紹了Android實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Android自定義圓角柱狀圖

    Android自定義圓角柱狀圖

    這篇文章主要為大家詳細(xì)介紹了Android自定義圓角柱狀圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 模擬按Home鍵退出應(yīng)用的簡(jiǎn)單方法(分享)

    模擬按Home鍵退出應(yīng)用的簡(jiǎn)單方法(分享)

    下面小編就為大家?guī)硪黄M按Home鍵退出應(yīng)用的簡(jiǎn)單方法(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • Android實(shí)現(xiàn)檢測(cè)實(shí)體按鍵事件并屏蔽

    Android實(shí)現(xiàn)檢測(cè)實(shí)體按鍵事件并屏蔽

    這篇文章主要介紹了Android實(shí)現(xiàn)檢測(cè)實(shí)體按鍵事件并屏蔽 ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • android圖片壓縮的3種方法實(shí)例

    android圖片壓縮的3種方法實(shí)例

    這篇文章介紹了android圖片壓縮的3種方法實(shí)例,有需要的朋友可以參考一下
    2013-09-09
  • Kotlin?LinearLayout與RelativeLayout布局使用詳解

    Kotlin?LinearLayout與RelativeLayout布局使用詳解

    Kotlin?的基本特性就先寫到這里,我們這個(gè)系列的定位是基礎(chǔ),也就是能用就好,夠用就好,我們不會(huì)舉太多的例子,但是這些都是最經(jīng)常用到的特性。從這節(jié)開始就是Kotlin和android?進(jìn)行結(jié)合,使用Kotlin進(jìn)行安卓應(yīng)用的開發(fā)了
    2022-12-12
  • Android設(shè)計(jì)模式系列之組合模式

    Android設(shè)計(jì)模式系列之組合模式

    這篇文章主要介紹了Android設(shè)計(jì)模式系列之組合模式的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • Android開發(fā)之ListView、GridView 詳解及示例代碼

    Android開發(fā)之ListView、GridView 詳解及示例代碼

    本文主要介紹Android開發(fā)之ListView、GridView,這里整理了相關(guān)資料及簡(jiǎn)單示例代碼,幫助大家學(xué)習(xí)參考,有需要的小伙伴可以參考下
    2016-08-08
  • android基本控件ToggleButton&Switch使用指南

    android基本控件ToggleButton&Switch使用指南

    本文給大家匯總介紹了android的2個(gè)基本控件ToggleButton和Switch的使用方法,非常的詳細(xì),有需要的小伙伴可以參考下。
    2016-01-01

最新評(píng)論