給RecyclerView封裝個(gè)Adapter吧(更優(yōu)雅的添加點(diǎn)擊事件)

給RecyclerView封裝個(gè)Adapter吧(更優(yōu)雅的添加點(diǎn)擊事件)


RecyclerView強(qiáng)大,好用鹃唯,但是使用率很高的ItemClickListener卻沒有添加。

- 你想要控制其顯示的方式,請(qǐng)通過布局管理器LayoutManager

- 你想要控制Item間的間隔(可繪制)滑臊,請(qǐng)通過ItemDecoration

- 你想要控制Item增刪的動(dòng)畫,請(qǐng)通過ItemAnimator

- 你想要控制點(diǎn)擊箍铲、長(zhǎng)按事件雇卷,請(qǐng)自己寫(擦,這點(diǎn)尼瑪颠猴。)

無疑讓我們?cè)谛老仓卸嗔艘唤z疑慮关划。有的哥們干脆從入門到放棄了。其實(shí)這也是這個(gè)框架的強(qiáng)大之處——定制翘瓮。

其中一個(gè)原因是RecyclerView的Item支持動(dòng)畫贮折。舉個(gè)栗子。如果你開啟了RecyclerView的Item動(dòng)畫资盅,當(dāng)你刪除了position位于1的Item之后调榄, 此時(shí)位于23456...的position會(huì)向前一格變成12345,而被刪除的那個(gè)view也會(huì)留在RecycleView上繼續(xù)執(zhí)行動(dòng)畫直到結(jié)束呵扛,于是這時(shí)候RecycleView中會(huì)留有兩個(gè)position為1的View....此時(shí)點(diǎn)擊那個(gè)被刪除的view的話就蛋疼了每庆。。因?yàn)锳dapter中已經(jīng)沒有這個(gè)item了今穿,如果用position 1去adapter中取的話缤灵,得到的是原來positon為2的那個(gè)item.....

還有就是RecyclerView負(fù)責(zé)控制/框架,LayoutManager負(fù)責(zé)計(jì)算布局,假設(shè)將ItemClickListener放到RecyclerView上凤价,如果要實(shí)現(xiàn)點(diǎn)擊事件鸽斟,首先需要確定每一個(gè)item的點(diǎn)擊區(qū)域。但是RecyclerView無法知道每一個(gè)item的點(diǎn)擊區(qū)域利诺,因?yàn)長(zhǎng)ayoutManager是可以由開發(fā)者來實(shí)現(xiàn)的富蓄,也就是說兩個(gè)View的區(qū)域是允許重疊的。如果點(diǎn)了A和B重疊區(qū)域到底是觸發(fā)A還是B慢逾,又必須要由LayoutManager來決定立倍。所以還不如直接放到LayoutManager中,但如果放到LayoutManager中的話需要給RecyclerView添加OnTouchListener侣滩,看上去又很別扭(要是外部給RecyclerView設(shè)置OnTouchListener會(huì)覆蓋掉這個(gè)導(dǎo)致ItemClickListener失效)口注。所以干脆交給開發(fā)者,你長(zhǎng)按或者點(diǎn)擊君珠,自己實(shí)現(xiàn)寝志。。策添。

點(diǎn)擊事件的實(shí)現(xiàn)材部,有常見的三種方法:

通過 RecyclerView已有的方法 addOnItemTouchListener()實(shí)現(xiàn)

在創(chuàng)建 ItemView時(shí)添加點(diǎn)擊監(jiān)聽

當(dāng) ItemViewattachRecyclerView時(shí)實(shí)現(xiàn)

從以上三種方式的實(shí)現(xiàn)過程可知:

三種均可實(shí)現(xiàn) ItemView的點(diǎn)擊事件和長(zhǎng)按事件的監(jiān)聽.

第一種方式可以很方便獲取用戶點(diǎn)擊的坐標(biāo).并且節(jié)省資源

第二種和第三種方式可以很方便對(duì) ItemView中的子 View進(jìn)行監(jiān)聽

第一種方式和第三種方式可以寫在單獨(dú)的類中,相對(duì)于第二種寫在 Adapter的方式可使代碼更獨(dú)立整潔,

既然RecyclerViewrecycle這么優(yōu)雅的解耦唯竹,我們肯定要選個(gè)解耦的方案乐导。而RecycleViewd的API也提供了RecyclerView.addOnItemTouchListener方法。so浸颓,我們選擇第一種方案:

OnItemTouchListener 源碼:

···

public static interface OnItemTouchListener {

? ? ?public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e);?

? ? ?public void onTouchEvent(RecyclerView rv, MotionEvent e);?

? ? ?public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept); }

···

此接口還提供了一個(gè)實(shí)現(xiàn)類,且官方推薦使用該實(shí)現(xiàn)類 SimpleOnItemTouchListener:

/**

* An implementation of {@linkRecyclerView.OnItemTouchListener} that has empty method bodies and

* default return values.

*

* You may prefer to extend this class if you don't need to override all methods. Another

* benefit of using this class is future compatibility. As the interface may change, we'll

* always provide a default implementation on this class so that your code won't break when

* you update to a new version of the support library.

*/

public static class SimpleOnItemTouchListener implements RecyclerView.OnItemTouchListener {?

? ? @Override?

? ? public

boolean onInterceptTouchEvent(RecyclerViewrv,MotionEvente){returnfalse;}

@Override

public void onTouchEvent(RecyclerViewrv,MotionEvente){}

@Override

public void onRequestDisallowInterceptTouchEvent(booleandisallowIntercept){}}

在觸摸接口中,當(dāng)觸摸時(shí)會(huì)回調(diào)一個(gè) MotionEvent對(duì)象,看到MotionEvent然后想到了什么物臂?通過使用 GestureDetectorCompat來解析用戶的操作!GestureDetectorCompat就是處理手勢(shì)的類:手勢(shì)探測(cè)器产上,它比GestureDetector能更好兼容低版本的api棵磷,但使用方法是一致的。而GestureDetectorCompat還提供了一個(gè)外部類SimpleOnGestureListener蒂秘,這個(gè)類實(shí)現(xiàn)了上面GestureDetectorCompat接口的所有方法泽本,但全都是空實(shí)現(xiàn),這樣繼承SimpleOnGestureListener的時(shí)候就不用實(shí)現(xiàn)每一個(gè)方法了姻僧,我們需要點(diǎn)擊和長(zhǎng)按,只需要實(shí)現(xiàn):

boolean onSingleTapUp(MotionEvent e)voidonLongPress(MotionEvent e)

然后根據(jù)點(diǎn)擊的坐標(biāo)得到viewhoder:

View childView=recyclerView.findChildViewUnder(e.getX(),e.getY());if(childView!=null){RecyclerView.ViewHoldervh=recyclerView.getChildViewHolder(childView);onItemClick(vh);//點(diǎn)擊回掉}

全部代碼:

public abstract class OnRecyclerItemClickListener extends RecyclerView.SimpleOnItemTouchListener{

private GestureDetectorCompatmGestureDetector;

private RecyclerViewrecyclerView;

public OnRecyclerItemClickListener(finalRecyclerViewrecyclerView){

this.recyclerView=recyclerView;

mGestureDetector=new GestureDetectorCompat(recyclerView.getContext(),newGestureDetector.SimpleOnGestureListener(){

@Override

public boolean onSingleTapUp(MotionEvente){

View childView=recyclerView.findChildViewUnder(e.getX(),e.getY());if(childView!=null){

RecyclerView.ViewHoldervh=recyclerView.getChildViewHolder(childView);

onItemClick(vh);}

return true;}

@Override

public void onLongPress(MotionEvente){

View childView=recyclerView.findChildViewUnder(e.getX(),e.getY());

if(childView!=null){

RecyclerView.ViewHoldervh=recyclerView.getChildViewHolder(childView);onItemLongClick(vh);}}});}//點(diǎn)擊事件交給mGestureDetector處理@Override public boolean onInterceptTouchEvent(RecyclerViewrv,MotionEvente){mGestureDetector.onTouchEvent(e);returnfalse;}//點(diǎn)擊回掉public abstract void onItemClick(RecyclerView.ViewHoldervh);//長(zhǎng)按監(jiān)聽public abstract void onItemLongClick(RecyclerView.ViewHoldervh);}

使用:

recyclerView.addOnItemTouchListener(newOnRecyclerItemClickListener(recyclerView){

@Override?

public void onItemClick(RecyclerView.ViewHoldervh){

intadapterPosition=vh.getAdapterPosition();//當(dāng)前item的位置Log.i(TAG,"onItemClick: "+adapterPosition);}

@Override

public void onItemLongClick(RecyclerView.ViewHoldervh){Log.i(TAG,"onItemLongClick: ");}});

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蒲牧,一起剝皮案震驚了整個(gè)濱河市撇贺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冰抢,老刑警劉巖松嘶,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異挎扰,居然都是意外死亡翠订,警方通過查閱死者的電腦和手機(jī)巢音,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尽超,“玉大人官撼,你說我怎么就攤上這事∷扑” “怎么了傲绣?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)巩踏。 經(jīng)常有香客問我秃诵,道長(zhǎng),這世上最難降的妖魔是什么塞琼? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任菠净,我火速辦了婚禮,結(jié)果婚禮上彪杉,老公的妹妹穿的比我還像新娘毅往。我一直安慰自己,他們只是感情好在讶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布煞抬。 她就那樣靜靜地躺著,像睡著了一般构哺。 火紅的嫁衣襯著肌膚如雪革答。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天曙强,我揣著相機(jī)與錄音残拐,去河邊找鬼。 笑死碟嘴,一個(gè)胖子當(dāng)著我的面吹牛溪食,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播娜扇,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼错沃,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了雀瓢?” 一聲冷哼從身側(cè)響起枢析,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刃麸,沒想到半個(gè)月后醒叁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年把沼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啊易。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饮睬,死狀恐怖租谈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情续捂,我是刑警寧澤垦垂,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站牙瓢,受9級(jí)特大地震影響劫拗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矾克,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一页慷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胁附,春花似錦酒繁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至弓候,卻和暖如春郎哭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背菇存。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工夸研, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人依鸥。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓亥至,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贱迟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子姐扮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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