我可以通过功能参数发送扩展功能吗?
下面我有一些扩展函数的功能。
fun EditText.setEmailValidationListener(): TextWatcher { val textWatcher = object : TextWatcher { override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(text: Editable?) { validateEmail() } private fun validateEmail(): Boolean { if (validateEmailFormat(showError = false)) { getParentInputLayout()?.isErrorEnabled = false return true } return false } } addTextChangedListener(textWatcher) return textWatcher } fun EditText.setPasswordValidationListener(): TextWatcher { val textWatcher = object : TextWatcher { override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(text: Editable?) { validateEmpty() } private fun validatePasswordText(): Boolean { if (validateEmptyText(showError = false)) { getParentInputLayout()?.isErrorEnabled = false return true } return false } } addTextChangedListener(textWatcher) return textWatcher } fun EditText.validateEmailFormat(showError: Boolean = true): Boolean { // Do something checking the Email return false } fun EditText.validatePasswordText(showError: Boolean = true): Boolean { // Do something checking the Password return false } private fun EditText.getParentInputLayout(): TextInputLayout? { if (parent is TextInputLayout) { return parent as TextInputLayout } return null }
setEmailValidationListener
和setPasswordValidationListener
都是相同的,除了它们分别使用的验证函数,即validateEmailFormat
和validatePasswordFormat
。
所以我打算把这两个函数的通用代码重构成一个通用函数,如下所示
fun EditText.setupTextChangeListener(validatorFunc : (showError: Boolean) -> Boolean): TextWatcher { val textWatcher = object : TextWatcher { override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(text: Editable?) { validateEmpty() } private fun validateEmpty(): Boolean { if (validatorFunc(false)) { getParentInputLayout()?.isErrorEnabled = false return true } return false } } addTextChangedListener(textWatcher) return textWatcher }
…基本上只是将validationFunc
作为参数发送给它。
但是,我找不到任何将EditText.validateEmailFormat
和EditText.validatePasswordFormat
发送到validationFunc
函数参数的方法。
我怎么能做到这一点?
一些理论
扩展功能的签名比起先看可能要复杂一点。 这个扩展需要对这个类的对象有一定的参考才能对它做出反应。
实际上是扩展方法
fun EditText.validateEmailFormat(showError: Boolean = true): Boolean
在反编译成普通的老java后,看起来像这样:
public static final boolean validateEmailFormat(@NotNull EditText $receiver, boolean showError)
因为(几乎)不可能改变已编译的Java类。 所以Kotlin(很可能有其他扩展方法概念的语言)使用静态方法,第一个参数是扩展类的接收器,以使其工作。
回到业务
您的validateEmailFormat
实际上是EditText.(Boolean) -> Boolean
类型EditText.(Boolean) -> Boolean
,同时是类型(EditText, Boolean) -> Boolean
。 所以你需要做两件事情之一:
首先,你可以使EditText.setupTextChangeListener
接受validatorFunc
为EditText.(Boolean) -> Boolean
或(EditText, Boolean) -> Boolean
而不是(Boolean) -> Boolean
。
或者,你不要在fun EditText.validateEmailFormat(Boolean)
扩展EditText
,并使其成为Kotlin函数,例如像这样的fun validateEmailFormat(String, Boolean)
。
正如你广泛使用扩展功能,我假设第一个选项是正确的解决方案。
- Android 4.4中的自定义视图构造函数在Kotlin上崩溃,如何修复?
- Kotlinx不能解决符号“合成”
- 为Kotlin / Anko DSL定义的ImageView设置图像时遇到问题
- 急于在kotlin中初始化对象?
- 安装kotlin后无法打开Android studio项目
- 过时的Kotlin运行时警告(Kotlin插件1.1.2-release-Studio2.3-3)
- 为什么我的应用程序有两个快捷方式,每个都有不同的行为?
- Haskell中的HasSupportFragmentInjector问题 – DispatchingAndroidInjector为null
- Kotlin – 与SomeClass.class对象的等价性?