美文网首页我的Kotlin之旅
记一次写点击事件的扩展

记一次写点击事件的扩展

作者: 叫我旺仔 | 来源:发表于2019-03-28 16:04 被阅读4次

    前言

    写一个界面的各种点击事件的时候难免会写很多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版本,如果用最新的可以按照思路自己实现)来控制,那么就写个扩展来对应判断重复点击事件,其中里面会用到RxJavaCompositeSubscription来取消所有订阅。

    基类

    首先要在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) })
        }
    }
    

    结尾

    每天写那么多重复的代码,总会有不想写的时候,这也就是这篇博客产生的原因,如果大家有更好的实现方案也可以分享出来。

    相关文章

      网友评论

        本文标题:记一次写点击事件的扩展

        本文链接:https://www.haomeiwen.com/subject/matcbqtx.html