在Kotlin中如何构建一个lambda表达式用于EditText的addTextChangeListener?以下代码会报错:
passwordEditText.addTextChangedListener { charSequence ->
try {
password = charSequence.toString()
} catch (error: Throwable) {
raise(error)
}
}
在Kotlin中如何构建一个lambda表达式用于EditText的addTextChangeListener?以下代码会报错:
passwordEditText.addTextChangedListener { charSequence ->
try {
password = charSequence.toString()
} catch (error: Throwable) {
raise(error)
}
}
addTextChangedListener()
接受一个 TextWatcher
,这是一个带有3个方法的接口。如果 TextWatcher
只有1个方法,则您编写的内容将无效。我猜测您收到的错误与您的lambda未实现其他2个方法有关。您有两个选择。
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
})
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
})
}
然后像这样使用扩展:
editText.afterTextChanged { doSomethingWithText(it) }
fun foo() = ...
)。 - F. GeorgeafterTextChanged.invoke(...)
而不是 afterTextChanged(...)
? - Felix D.添加此核心ktx依赖项
implementation 'androidx.core:core-ktx:1.0.0'
你只需执行:
passwordEditText.doAfterTextChanged{ }
虽然有些老了,但使用 Kotlin Android 扩展,你可以这样做:
editTextRequest.textChangedListener {
afterTextChanged {
// Do something here...
}
}
无需额外代码,只需添加:
implementation 'androidx.core:core-ktx:1.0.0'
KAndroid
解决方案完美地解决了问题。 - Igorimplementation "androidx.core:core-ktx:1.2.0"
-> edt.addTextChangedListener(afterTextChanged = { /*dosomething*/ })
- Dr.jackyimplementation 'androidx.core:core-ktx:1.1.0'
,那么您就可以使用。etPlayer1.doOnTextChanged { text, start, count, after -> // Do stuff }
测试一下:
passwordEditText.addTextChangedListener(object:TextWatcher{
override fun afterTextChanged(s: Editable?) { }
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { }
})
希望这个Kotlin
示例可以帮助理解:
class MainFragment : Fragment() {
private lateinit var viewModel: MainViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.main_fragment, container, false)
view.user.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable) {
userLayout.error =
if (s.length > userLayout.counterMaxLength) {
"Max character length is: ${userLayout.counterMaxLength}"
} else null
}
})
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
// TODO: Use the ViewModel
}
}
使用此XML
布局:
<android.support.design.widget.TextInputLayout
android:id="@+id/userLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterMaxLength="5"
app:counterEnabled="true"
android:hint="user_name">
<android.support.design.widget.TextInputEditText
android:id="@+id/user"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
还有这个Gradle
:
android {
compileSdkVersion 'android-P'
...
}
api 'com.android.support:design:28.0.0-alpha1'
implementation 'com.android.support:appcompat-v7:28.0.0-alpha1' // appcompat library
如果您使用implementation 'androidx.core:core-ktx:1.1.0-alpha05'
,则可以使用
For android.widget.TextView
TextWatcher
TextView.doBeforeTextChanged(crossinline action: (text: CharSequence?, start: Int, count: Int, after: Int) -> Unit)
Add an action which will be invoked before the text changed.
TextWatcher
TextView.doOnTextChanged(crossinline action: (text: CharSequence?, start: Int, count: Int, after: Int) -> Unit)
Add an action which will be invoked when the text is changing.
TextWatcher
TextView.doAfterTextChanged(crossinline action: (text: Editable?) -> Unit)
添加核心ktx依赖项
implementation 'androidx.core:core-ktx:1.3.0'
然后您可以像这样简单实现
edit_text.addTextChangedListener { it: Editable? ->
// Do your stuff here
}
另一个选择是使用 KAndroid
库:
implementation 'com.pawegio.kandroid:kandroid:0.8.7@aar'
然后您可以像这样进行操作...
editText.textWatcher { afterTextChanged { doSomething() } }
显然,使用整个库来解决问题是过度的,但它还带有一系列其他有用的扩展,可以消除Android SDK中的样板代码。