關(guān)于Graywater的系列文章
- RecyclerView的超強(qiáng)輔助Graywater——理論篇
- RecyclerView的超強(qiáng)輔助Graywater——基礎(chǔ)實操篇
- RecyclerView的超強(qiáng)輔助Graywater——點(diǎn)擊事件
- RecyclerView的超強(qiáng)輔助Graywater——綜合實操篇
上一篇寫了Graywater的基礎(chǔ)使用湿蛔,但是沒講點(diǎn)擊事件,這一篇文章就把點(diǎn)擊事件給補(bǔ)充上。還是使用的基礎(chǔ)實操篇中的GraywaterPrimaryDemo繼續(xù)寫析苫。
先展示點(diǎn)擊效果圖:
在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)系蚊伞,來快速查找所需要的類席赂。
到這里,基本上點(diǎn)擊事件就講完了时迫,有什么錯誤或說的不清楚的地方歡迎大家指正颅停。
P.S.
Graywater 官方Demo Github地址
GraywaterPrimaryDemo Github地址 如果對大家有幫助的話,star就是對我的鼓勵掠拳。
如果對你有幫助的話癞揉,點(diǎn)贊、評論溺欧、贊賞都是對我的鼓勵喊熟,也是支持我寫下去的動力,謝謝姐刁!