為RecyclerView添加item的點擊事件

RecyclerView側(cè)重的是布局的靈活性耘斩,雖說可以替代ListView但是連基本的點擊事件都沒有范嘱,這篇文章就來詳細(xì)講解如何為RecyclerView的item添加點擊事件,順便復(fù)習(xí)一下觀察者模式曹抬。

其實在這篇文章中已經(jīng)提到如何實現(xiàn)材部,但是里面有很多不規(guī)范的地方寝贡,而且沒有完整的代碼。

最終目的

模擬ListView的setOnItemClickListener()方法兵睛,調(diào)用者只須調(diào)用類似于setOnItemClickListener的東西就能獲得被點擊item的相關(guān)數(shù)據(jù)肯骇。

原理

為RecyclerView的每個子item設(shè)置setOnClickListener窥浪,然后在onClick中再調(diào)用一次對外封裝的接口,將這個事件傳遞給外面的調(diào)用者笛丙。而“為RecyclerView的每個子item設(shè)置setOnClickListener”在Adapter中設(shè)置漾脂。其實直接在onClick中也能完全處理item的點擊事件,但是這樣會破壞代碼的邏輯胚鸯。

步驟

adapter中

自定義一個繼承自RecyclerView.Adapter的MyAdapter骨稿。

1.在MyAdapter中定義如下接口,模擬ListView的OnItemClickListener:

//define?interface

publicstaticinterfaceOnItemClickListener{

voidonItemClick(Viewview,intposition);

}

聲明一個這個接口的變量

privateOnItemClickListenermOnItemClickListener=null;

在onCreateViewHolder()中為每個item添加點擊事件

@Override

publicViewHolderonCreateViewHolder(ViewGroupviewGroup,intviewType){

Viewview=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);

ViewHoldervh=newViewHolder(view);

//將創(chuàng)建的View注冊點擊事件

view.setOnClickListener(this);

returnvh;

}

將點擊事件轉(zhuǎn)移給外面的調(diào)用者:

@Override

publicvoidonClick(Viewv){

if(mOnItemClickListener!=null){

//注意這里使用getTag方法獲取position

mOnItemClickListener.onItemClick(v,(int)v.getTag());

}

}

注意上面調(diào)用接口的onItemClick()中的v.getTag()方法,這需要在onBindViewHolder()方法中設(shè)置和item的position

@Override

publicvoidonBindViewHolder(ViewHolderviewHolder,intposition){

viewHolder.mTextView.setText(datas[position]);

//將position保存在itemView的Tag中姜钳,以便點擊時進(jìn)行獲取

viewHolder.itemView.setTag(position);

}

最后暴露給外面的調(diào)用者坦冠,定義一個設(shè)置Listener的方法():

publicvoidsetOnItemClickListener(OnItemClickListenerlistener){

this.mOnItemClickListener=listener;

}

以上所有步驟都發(fā)生在自定義的adapter中,典型的觀察者模式哥桥,有點繞的地方在于辙浑,這里涉及到兩個觀察者模式的使用,view的setOnClickListener本來就是觀察者模式拟糕,我們將這個觀察者模式的事件監(jiān)聽傳遞給了我們自己的觀察者模式判呕。

在Activity中使用

mRecyclerView=(RecyclerView)findViewById(R.id.my_recycler_view);

//創(chuàng)建默認(rèn)的線性LayoutManager

mLayoutManager=newLinearLayoutManager(this);

mRecyclerView.setLayoutManager(mLayoutManager);

//如果可以確定每個item的高度是固定的,設(shè)置這個選項可以提高性能

mRecyclerView.setHasFixedSize(true);

//創(chuàng)建并設(shè)置Adapter

mAdapter=newMyAdapter(data);

mRecyclerView.setAdapter(mAdapter);

mAdapter.setOnItemClickListener(newOnItemClickListener(){

@Override

publicvoidonItemClick(Viewview,intposition){

Toast.makeText(MainActivity.this,data[position],600).show();

}

});

完整代碼

MyAdapter.java

packagecom.example.recyclerviewdemo;

importandroid.support.v7.widget.RecyclerView;

importandroid.util.Log;

importandroid.view.LayoutInflater;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.widget.TextView;

publicclassMyAdapterextendsRecyclerView.AdapterimplementsView.OnClickListener{

privateString[]datas;

publicMyAdapter(String[]datas){

this.datas=datas;

}

privateOnItemClickListenermOnItemClickListener=null;

//define?interface

publicstaticinterfaceOnItemClickListener{

voidonItemClick(Viewview,intposition);

}

@Override

publicViewHolderonCreateViewHolder(ViewGroupviewGroup,intviewType){

Viewview=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item,viewGroup,false);

ViewHoldervh=newViewHolder(view);

//將創(chuàng)建的View注冊點擊事件

view.setOnClickListener(this);

returnvh;

}

@Override

publicvoidonBindViewHolder(ViewHolderviewHolder,intposition){

viewHolder.mTextView.setText(datas[position]);

//將position保存在itemView的Tag中送滞,以便點擊時進(jìn)行獲取

viewHolder.itemView.setTag(position);

}

@Override

publicvoidonClick(Viewv){

if(mOnItemClickListener!=null){

//注意這里使用getTag方法獲取position

mOnItemClickListener.onItemClick(v,(int)v.getTag());

}

}

publicvoidsetOnItemClickListener(OnItemClickListenerlistener){

this.mOnItemClickListener=listener;

}

//獲取數(shù)據(jù)的數(shù)量

@Override

publicintgetItemCount(){

returndatas.length;

}

//自定義的ViewHolder侠草,持有每個Item的的所有界面元素

publicstaticclassViewHolderextendsRecyclerView.ViewHolder{

publicTextViewmTextView;

publicViewHolder(Viewview){

super(view);

mTextView=(TextView)view.findViewById(R.id.text);

}

}

}

item.xml

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="50dip"

>

android:id="@+id/text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

/>

MainActivity.java

packagecom.example.recyclerviewdemo;

importcom.example.recyclerviewdemo.MyAdapter.OnItemClickListener;

importandroid.support.v7.app.ActionBarActivity;

importandroid.support.v7.widget.LinearLayoutManager;

importandroid.support.v7.widget.RecyclerView;

importandroid.os.Bundle;

importandroid.view.Menu;

importandroid.view.MenuItem;

importandroid.view.View;

importandroid.widget.Toast;

publicclassMainActivityextendsActionBarActivity{

privateRecyclerViewmRecyclerView;

privateLinearLayoutManagermLayoutManager;

privateMyAdaptermAdapter;

privateString[]data=newString[]{"aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb","aa","bb"};

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mRecyclerView=(RecyclerView)findViewById(R.id.my_recycler_view);

//創(chuàng)建默認(rèn)的線性LayoutManager

mLayoutManager=newLinearLayoutManager(this);

mRecyclerView.setLayoutManager(mLayoutManager);

//如果可以確定每個item的高度是固定的,設(shè)置這個選項可以提高性能

mRecyclerView.setHasFixedSize(true);

//創(chuàng)建并設(shè)置Adapter

mAdapter=newMyAdapter(data);

mRecyclerView.setAdapter(mAdapter);

mAdapter.setOnItemClickListener(newOnItemClickListener(){

@Override

publicvoidonItemClick(Viewview,intposition){

Toast.makeText(MainActivity.this,data[position],600).show();

}

});

}

@Override

publicbooleanonCreateOptionsMenu(Menumenu){

//?Inflate?the?menu;?this?adds?items?to?the?action?bar?if?it?is?present.

getMenuInflater().inflate(R.menu.main,menu);

returntrue;

}

@Override

publicbooleanonOptionsItemSelected(MenuItemitem){

//?Handle?action?bar?item?clicks?here.?The?action?bar?will

//?automatically?handle?clicks?on?the?Home/Up?button,?so?long

//?as?you?specify?a?parent?activity?in?AndroidManifest.xml.

intid=item.getItemId();

if(id==R.id.action_settings){

returntrue;

}

returnsuper.onOptionsItemSelected(item);

}

}

activity_main.xml

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

android:id="@+id/my_recycler_view"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scrollbars="vertical"/>

總結(jié)

在ListView中我們是調(diào)用ListView的setOnItemClickListener:

mListView.setOnItemClickListener(newOnItemClickListener(){

publicvoidonItemClick(AdapterViewparent,Viewv,intposition,longid){

...

}

});

而在我們這里是調(diào)用mAdapter的setOnItemClickListener累澡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梦抢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子愧哟,更是在濱河造成了極大的恐慌奥吩,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕊梧,死亡現(xiàn)場離奇詭異霞赫,居然都是意外死亡,警方通過查閱死者的電腦和手機肥矢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門端衰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甘改,你說我怎么就攤上這事旅东。” “怎么了十艾?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵抵代,是天一觀的道長。 經(jīng)常有香客問我忘嫉,道長荤牍,這世上最難降的妖魔是什么案腺? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮康吵,結(jié)果婚禮上劈榨,老公的妹妹穿的比我還像新娘。我一直安慰自己晦嵌,他們只是感情好同辣,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耍铜,像睡著了一般邑闺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棕兼,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天陡舅,我揣著相機與錄音,去河邊找鬼伴挚。 笑死靶衍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茎芋。 我是一名探鬼主播颅眶,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼田弥!你這毒婦竟也來了涛酗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤偷厦,失蹤者是張志新(化名)和其女友劉穎商叹,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體只泼,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡剖笙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了请唱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弥咪。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖十绑,靈堂內(nèi)的尸體忽然破棺而出聚至,到底是詐尸還是另有隱情,我是刑警寧澤本橙,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布晚岭,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坦报。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一狂鞋、第九天 我趴在偏房一處隱蔽的房頂上張望片择。 院中可真熱鬧,春花似錦骚揍、人聲如沸字管。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘲叔。三九已至,卻和暖如春抽活,著一層夾襖步出監(jiān)牢的瞬間硫戈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工下硕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丁逝,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓梭姓,卻偏偏與公主長得像霜幼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子誉尖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容