RecyclerView的超強(qiáng)輔助Graywater——點(diǎn)擊事件

關(guān)于Graywater的系列文章

  1. RecyclerView的超強(qiáng)輔助Graywater——理論篇
  2. RecyclerView的超強(qiáng)輔助Graywater——基礎(chǔ)實操篇
  3. RecyclerView的超強(qiáng)輔助Graywater——點(diǎn)擊事件
  4. RecyclerView的超強(qiáng)輔助Graywater——綜合實操篇

上一篇寫了Graywater的基礎(chǔ)使用湿蛔,但是沒講點(diǎn)擊事件,這一篇文章就把點(diǎn)擊事件給補(bǔ)充上。還是使用的基礎(chǔ)實操篇中的GraywaterPrimaryDemo繼續(xù)寫析苫。

先展示點(diǎn)擊效果圖:

Graywater點(diǎn)擊事件.gif

在RecyclerView中如果需要點(diǎn)擊事件箕戳,我們通常會給RecyclerViewd.Adapter傳入一個我們自定義的接口引用舀射,比如OnItemClickListener自赔。然后在onBindViewHolder()方法中將需要點(diǎn)擊事件的控件,比如Button背犯,實現(xiàn)View的OnClickListener接口坏瘩,再使用我們自定義的方法,最后在MainActivity中實現(xiàn)自定義的接口漠魏。

        holder.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (clickListener != null) {
                    clickListener.onClickItem(position);
                }
            }
        });

Graywater跟前者也是比較相似的倔矾,最大的不同的是Graywater自己提供了一個點(diǎn)擊事件的接口(GraywaterAdapter.ActionListener)和一個點(diǎn)擊事件代理(GraywaterAdapter.ActionListenerDelegate)來管理點(diǎn)擊事件。通過在Binder類中傳入ViewHolder所持有的接口代理柱锹,在ItemBinder中實現(xiàn)接口的act()方法哪自,來完成點(diǎn)擊事件的實現(xiàn)。

實際上奕纫,是GraywaterAdapter.ActionListenerDelegate代理實現(xiàn)了View的OnClickListener接口提陶,然后在onClick方法中在調(diào)用GraywaterAdapter.ActionListener的act方法。

        @Override
        public void onClick(final View v) {
            actionListener.act(model, holder, v, binders, binderIndex, obj);
        }

接下來就一步步的講解怎么實現(xiàn)點(diǎn)擊事件匹层,點(diǎn)擊事件也可以根據(jù)上一篇文章中代碼的順序來寫隙笆。

1. 給需要點(diǎn)擊事件的控件添加id值

每個Item都由一個RelativeLayout作為最外層的控件,里面放了一個TextView和一個ImageView升筏,給RelativeLayout添加android:id="@+id/item_layout"屬性

2. 在對應(yīng)ViewHolder類中添加對應(yīng)的View并創(chuàng)建ActionListenerDelegate的對象

在EntertainViewHolder里面添加RelativeLayout的控件撑柔。

重點(diǎn)!需要在ViewHolder中創(chuàng)建代理對象您访,使用holder來統(tǒng)一管理所有的view和點(diǎn)擊代理對象铅忿。創(chuàng)建ActionListenerDelegate對象時候需要也需要傳入對應(yīng)的model和viewholder的泛型參數(shù),當(dāng)然這里就是EntertainPrimitive和EntertainViewHolder灵汪。

    private GraywaterAdapter.ActionListenerDelegate<EntertainPrimitive, EntertainViewHolder>
            mActionListenerDelegate = new GraywaterAdapter.ActionListenerDelegate<>();

別忘記在最后也要添加對應(yīng)的get方法檀训。

3.在Binder類的bind方法中setOnClickListener()

Graywater官方Demo中,要想實現(xiàn)點(diǎn)擊事件享言,就必須要在bind方法里讓點(diǎn)擊代理getmActionListenerDelegate執(zhí)行update()方法峻凫。看Graywater源碼可以知道update方法實際上就是把相關(guān)參數(shù)都保存下來览露,然后在act方法中把相關(guān)的引用傳過去使用荧琼。

在update方法后,需要點(diǎn)擊事件的View就可以在setOnClickListener()中傳入點(diǎn)擊代理了差牛,最后記得要在unbind()方法中給setOnClickListener()傳入null值做清理命锄。

    @Override
    public void bind(@NonNull EntertainPrimitive model, @NonNull EntertainViewHolder holder, @NonNull List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends EntertainViewHolder>>
            binders, int binderIndex, @NonNull GraywaterAdapter.ActionListener<EntertainPrimitive, EntertainViewHolder> actionListener) {
        Picasso.get().load(model.getUrls().get(binderIndex)).placeholder(R.mipmap.ic_launcher).into(holder.getImg());
        holder.getTitle().setText(model.getTitles().get(binderIndex));

        holder.getmActionListenerDelegate().update(actionListener, model, holder, binders, binderIndex, null);
        holder.getMainLayoutView().setOnClickListener(holder.getmActionListenerDelegate());
    }

    @Override
    public void unbind(@NonNull EntertainViewHolder holder) {
        holder.getMainLayoutView().setOnClickListener(null);
    }

update()方法所需要傳入的參數(shù)基本上就是bind方法中的參數(shù),需要注意的是最后一個Object參數(shù)偏化,這個Object參數(shù)是用來傳遞我們想要傳遞的值的脐恩,類似Intent傳值的作用一樣。一般都用不到侦讨,可以直接傳null被盈。

holder.getmActionListenerDelegate().update(actionListener, model, holder, binders, binderIndex, null);

4.ItemBinder類實現(xiàn)GraywaterAdapter.ActionListener接口析孽,并實現(xiàn)act()方法

EntertainItemBinder需要實現(xiàn)GraywaterAdapter.ActionListener接口,然后就可以在act方法中具體實現(xiàn)我們的點(diǎn)擊事件了只怎。

在GraywaterAdapter.ActionListener接口中需要傳入model的泛型參數(shù)和viewholder的泛型參數(shù),在EntertainItemBinder中怜俐,就傳入對應(yīng)的EntertainPrimitive和EntertainViewHolder身堡。

看一下act方法的實現(xiàn),其實就是類似RecyclerView.Adapter中的實現(xiàn):

    @Override
    public void act(@NonNull EntertainPrimitive model, @NonNull EntertainViewHolder holder, @NonNull View v, @NonNull List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends
            EntertainViewHolder>> binders, int binderIndex, @Nullable Object obj) {
        switch (v.getId()) {
            case R.id.item_layout:
                onItemClickListener.onClickItem(model.getTitles().get(binderIndex));
                break;
        }
    }

5.寫接口傳入拍鲤,MainActivity實現(xiàn)接口

一般在寫點(diǎn)擊事件時贴谎,我們一般會習(xí)慣自定義一個點(diǎn)擊事件接口,這里也不例外季稳,我自定義了一個OnItemClickListener接口擅这。讓MainActivity實現(xiàn)了這個接口,并將接口傳入PrimitiveAdapter中景鼠。

public interface OnItemClickListener {
    void onClickItem(String name);
}

MainActivity實現(xiàn)了onClickItem方法仲翎,就可以使用傳過來的name參數(shù)做相應(yīng)的業(yè)務(wù)處理了。

看一下OnItemClickListener引用的傳遞順序铛漓。

首先是MainActivity

mPrimitiveAdapter = new PrimitiveAdapter(this);    //因為MainActivity實現(xiàn)了OnItemClickListener接口溯香,所以傳入this
mRecyclerView.setAdapter(mPrimitiveAdapter);

再是PrimitiveAdapter的構(gòu)造方法,將OnItemClickListener傳給EntertainItemBinder浓恶。

    public PrimitiveAdapter(OnItemClickListener listener) {
        register(new EntertainViewHolderCreator(), EntertainViewHolder.class);  //將creator和對應(yīng)的viewholder綁定

        EntertainBinder entertainBinder = new EntertainBinder();
        EntertainItemBinder entertainItemBinder = new EntertainItemBinder(entertainBinder, listener);
        register(EntertainPrimitive.class, entertainItemBinder, entertainItemBinder);  //將itemBinder和指定的數(shù)據(jù)類型綁定
    }

注意構(gòu)造方法中的第二個register()方法的第三個參數(shù)也是entertainItemBinder玫坛,從源碼可知,要求傳入的參數(shù)是GraywaterAdapter.ActionListener包晰,也就是在ItemBinder實現(xiàn)該接口后就傳入ItemBinder湿镀,否則就傳入null。

    protected void register(@NonNull final MT modelType,
                            @NonNull final ItemBinder<? extends T, ? extends VH> parts,
                            @Nullable final ActionListener<? extends T, ? extends VH> listener) {
        mItemBinderMap.put(modelType, parts);
        mActionListenerMap.put(modelType, listener);
    }

Graywater有5個基本變量伐憾,mItemBinderMap和mActionListenerMap就是其中兩個勉痴,這兩個變量都是Map類型。Graywater中5個基本變量除開mItems不是字典類型塞耕,其他4個都是這種字典類型蚀腿。這是Graywater的核心,以字典的方式扫外,將model映射到viewholder上莉钙。register就是在匹配映射關(guān)系,將viewholder和viewholdercreator映射起來筛谚。將model映射到ItemBinder上磁玉,將model映射到Actionlistener上,由此來組成第一篇文章中所展示的映射網(wǎng)狀關(guān)系驾讲,并通過映射關(guān)系蚊伞,來快速查找所需要的類席赂。

原理圖1.png

到這里,基本上點(diǎn)擊事件就講完了时迫,有什么錯誤或說的不清楚的地方歡迎大家指正颅停。

P.S.
Graywater 官方Demo Github地址
GraywaterPrimaryDemo Github地址 如果對大家有幫助的話,star就是對我的鼓勵掠拳。

如果對你有幫助的話癞揉,點(diǎn)贊、評論溺欧、贊賞都是對我的鼓勵喊熟,也是支持我寫下去的動力,謝謝姐刁!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芥牌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子聂使,更是在濱河造成了極大的恐慌壁拉,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岩遗,死亡現(xiàn)場離奇詭異扇商,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宿礁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門案铺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人梆靖,你說我怎么就攤上這事控汉。” “怎么了返吻?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵姑子,是天一觀的道長。 經(jīng)常有香客問我测僵,道長街佑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任捍靠,我火速辦了婚禮沐旨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘榨婆。我一直安慰自己磁携,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布良风。 她就那樣靜靜地躺著谊迄,像睡著了一般闷供。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上统诺,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天歪脏,我揣著相機(jī)與錄音,去河邊找鬼粮呢。 笑死唾糯,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鬼贱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼香璃,長吁一口氣:“原來是場噩夢啊……” “哼这难!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起葡秒,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤姻乓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后眯牧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹋岩,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年学少,在試婚紗的時候發(fā)現(xiàn)自己被綠了剪个。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡版确,死狀恐怖扣囊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绒疗,我是刑警寧澤侵歇,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吓蘑,受9級特大地震影響惕虑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜磨镶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一溃蔫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棋嘲,春花似錦酒唉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侄榴。三九已至,卻和暖如春网沾,著一層夾襖步出監(jiān)牢的瞬間癞蚕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工辉哥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桦山,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓醋旦,卻偏偏與公主長得像恒水,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子饲齐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

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