記一次寫點選事件的擴充套件
寫一個介面的各種點選事件的時候難免會寫很多id.setOnClickListener(this)
這樣的程式碼,寫的時間多了,難免會煩惱,老子為什麼要寫那麼多重複的程式碼啊!!
既然不想寫那麼多重複程式碼,那麼就自己來寫個擴充套件吧。
開始
在寫點選事件的時候,會讓類實現View.OnClickListener
介面,然後在寫控制元件setOnClickListener()
方法,既然每個控制元件都要寫,不如寫個擴充套件方法,引數是一個可變引數,型別為View
,然後在裡面實現每個控制元件的setOnClickListener()
方法。
fun View.OnClickListener.setOnClickListener(vararg ids: View?) { ids.filterNotNull().forEach { it.setOnClickListener(this) } }
使用的時候是這樣的:
class TestActivity:AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState:Bundle?) { setOnClickListener(one, two) } override fun onClick(v:View) { when (v.id) { R.id.one -> { } R.id.two -> { } else -> { } } } }
是不是省掉了很多重複的程式碼。。
延伸
在寫點選事件的時候,往往要判斷重複點選,那麼就會用到RxView
(RxBinding第三方庫,由於公司專案用的版本還是0.4.0
版本,如果用最新的可以按照思路自己實現)來控制,那麼就寫個擴充套件來對應判斷重複點選事件,其中裡面會用到RxJava
的CompositeSubscription
來取消所有訂閱。
基類
首先要在Activity
或者Fragment
的基類裡面寫CompositeSubscription
的取消訂閱。
class BaseTestActivity:AppCompatActivity() { protected val compositeSubscription = CompositeSubscription() override fun onDestroy() { compositeSubscription.clear() super.onDestroy() } }
compositeSubscription
在子類用到,所以設定為protected
。
擴充套件
在寫這個擴充套件的時候,分兩個情況,在RecyclerView的ViewHolder裡面的時候,是不需要用到CompositeSubscription
來取消訂閱事件的,在Activity
或者Fragment
上面才用到的。
ViewHolder
由於不同人的封裝的ViewHolder的程式碼不一樣,這裡就直接用自己專案上的程式碼列舉出來,大家可以根據自己專案的程式碼自己調整,最終實現的程式碼是這樣的:
class TestBinder:ItemBinder<TestEntity>(R.layout.item_test){ override fun onBindViewHolder(holder:ViewHolder, item:TestEntity) { holder.run { setOnClickThrottleFirst(one, two, three) { when (it.id) { R.id.one -> {} R.id.two -> {} else -> {} } } } } }
由於會用到資料類的物件,所以不能用View.OnClickListener
那樣的擴充套件方法。
實現
fun setOnClickThrottleFirst( vararg ids: View?, block: (View) -> Unit ) { ids.filterNotNull().forEach { view -> RxView.clicks(view) .throttleFirst(1, TimeUnit.SECONDS) .subscribe { block(view) } } }
Activity或者Fragment
在Activity或者Fragment上面使用,我們期望的實現是這樣的:
fun test() { setOnClickThrottleFirst( compositeSubscription, one, two, three, four ) } override fun onClick(v:View) { when (v.id) { R.id.one -> {} R.id.two -> {} R.id.three -> {} R.id.four -> {} else -> {} } }
實現
看了上面的ViewHolder的時候就會發現,這裡很簡單,只需要加個CompositeSubscription引數,同時將呼叫函式引數的那裡改成,onClick(View)
響應點選事件:
fun View.OnClickListener.setOnClickThrottleFirst( compositeSubscription:CompositeSubscription, vararg ids: View? ) { ids.filterNotNull().forEach { view -> compositeSubscription.add(RxView.clicks(view) .throttleFirst(1, TimeUnit.SECONDS) .subscribe { onClick(view) }) } }
結尾
每天寫那麼多重複的程式碼,總會有不想寫的時候,這也就是這篇部落格產生的原因,如果大家有更好的實現方案也可以分享出來。