观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

前言

  扩展函数的意思是在一些已经被实现的类里,添加你自己需要的自定义方法。这样我们不需要写静态方法的工具类来实现需要的函数方法,而是直接在原有类的基础上去扩展。扩展函数在很多现代高级语言里都是支持的,但是Java很遗憾不支持这个功能。但是kotlin支持此功能。下面我们就来讲解在Android上可能能使用扩展函数的一些例子。

 

 

例子1:点击间隔实现

  在实际Android开发中,其实很多按钮都是需要一些点击间隔的,保证这个按键不会被连续点击导致创建多个Activity或者短时间内请求多个网络接口。我以前在 https://www.cnblogs.com/guanxinjing/p/10905850.html 这篇博客中有说明如何使用Java来实现按键的点击延迟。你可以看到不管是那种方式,在使用的时候都是极其麻烦的。需要写很多冗余模板代码。

  但是有了kotlin扩展函数的支持,我们就可以很简单是使用扩展函数帮我们直接在View上拓展一个点击间隔函数。

第一步,首先我们要创建一个与我们需要扩展函数的View同名的.kt文件。比如我们需要重写setOnClickListener这个点击方法,这个方法是在View这个类里的。所以我们需要创建一个View.kt文件

 

第二步,实现扩展方法

import android.os.SystemClock
import android.view.MotionEvent
import android.view.View

private var clickInterval = 400L
private var lastTime = 0L
fun View.setOnIntervalClickListener(onIntervalClickListener: (View) -> Unit) {
    this.setOnClickListener {
        //这里使用SystemClock.elapsedRealtime() 系统启动时间,会有更高的安全性,如果使用系统时间,用户可能修改系统时间导致无法点击
        if (SystemClock.elapsedRealtime() - lastTime > clickInterval) {
            lastTime = SystemClock.elapsedRealtime()
            onIntervalClickListener.invoke(it)
        }
    }
}

 

另外,如果你需要控制这个扩展函数的作用域,只需要在函数方法fun前面添加可见性修饰符即可。这样你就可以在限定范围内调用这个扩展函数,从而不影响到其他模块。

  • public        全局可见
  • internal        当前模块Model中可见
  • protected       当前包可见
  • private            当前类可见

第三步,使用它

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        textView.setOnIntervalClickListener {
            Toast.makeText(this, System.currentTimeMillis().toString(), Toast.LENGTH_LONG).show()
        }
    }

例子2:监听EditText的文本变化

  在Java里监听EditText的文本变化是特别啰嗦的,因为需要实现TextWatcher的3个方法。如果你其实只想监听字数或者文字内容变化,google在模板代码里提供了一个例子,来让这个方法简单化。代码如下:

/**
 * Extension function to simplify setting an afterTextChanged action to EditText components.
 */
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
    this.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(editable: Editable?) {
            afterTextChanged.invoke(editable.toString())
        }

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}

        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
    })
}

例子3 String字符串判断

 

/**
 * 判断是否含有特殊字符与表情字符
 *
 * @param str
 * @return true为包含,false为不包含
 */
public fun String?.isSpecialChar(): Boolean {
    if (this.isNullOrEmpty()) {
        return false
    }
    val pattern = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]|[ _`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]", Pattern.UNICODE_CASE or Pattern.CASE_INSENSITIVE)
    val m = pattern.matcher(this)
    return m.find()
}

/**
 * 判断是否是全中文汉字
 *
 * @param str
 * @return
 */
fun String?.isChinese(): Boolean {
    if (this.isNullOrEmpty()) {
        return false
    }
    val pattern = "[\u4e00-\u9fa5]*"
    return Pattern.matches(pattern, this)
}

 

 

 

End

posted on 2020-09-22 17:13  观心静  阅读(621)  评论(0编辑  收藏  举报