Котлин addTextChangeListener лямбда?
Как вы создаете лямбда-выражение для EditText addTextChangeListener в Kotlin? Ниже дается ошибка:
passwordEditText.addTextChangedListener { charSequence ->
try {
password = charSequence.toString()
} catch (error: Throwable) {
raise(error)
}
}
6 ответов
addTextChangedListener()
принимает TextWatcher
, который является интерфейсом с 3 методами. То, что вы написали, будет работать, только если TextWatcher
только 1 способ. Я думаю, ошибку ты получаешь относится к вашему лямда не реализует 2 метода. У вас есть 2 варианта в будущем.
1) отбросьте лямбду и просто используйте анонимный внутренний класс
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
2) Создайте метод расширения, чтобы вы могли использовать лямбда-выражение:
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
})
}
и затем использовать расширение так:
editText.afterTextChanged { doSomethingWithText(it) }
немного старый, но с помощью расширений Kotlin Android вы можете сделать что-то вроде этого:
editTextRequest.textChangedListener {
afterTextChanged {
// Do something here...
}
}
дополнительный код не требуется, просто добавьте:
implementation 'androidx.core:core-ktx:1.0.0-alpha1'
надеюсь, что это 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
несколько примеров:
Rx
RxTextView
.afterTextChangeEvents(editText)
.subscribe { presenter.onTextChanged(it.editable().toString())}
это круто, чтобы сделать что-то вроде этого
RxTextView
.afterTextChangeEvents(editText)
.skipInitialValue()
.debounce(500L, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { presenter.onTextChanged(it.editable().toString())}
.autoDispose()
у меня есть пыльный класс, но вы можете легко изменить его (или нет)
public class SimpleTextWatcher implements TextWatcher {
private CallBackAfterTextChanged callBackAfterTextChanged;
public interface CallBackAfterTextChanged {
void afterTextChanged(Editable s);
}
public SimpleTextWatcher(CallBackAfterTextChanged callBackAfterTextChanged) {
this.callBackAfterTextChanged = callBackAfterTextChanged;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
callBackAfterTextChanged.afterTextChanged(s);
}
}
на Котлин
editSearch.addTextChangedListener(SimpleTextWatcher{ presenter.onTextChanged(it.toString())})
или расширение, но я не буду повторяться
Другой альтернативой является KAndroid
библиотека
implementation 'com.pawegio.kandroid:kandroid:0.8.7@aar'
тогда вы могли бы сделать что-то вроде этого...
editText.textWatcher { afterTextChanged { doSomething() } }
очевидно, что чрезмерно использовать всю библиотеку для решения вашей проблемы, но она также поставляется с рядом других полезных расширений, которые устраняют шаблонный код в Android SDK.
Это выглядит аккуратно:
passwordEditText.setOnEditorActionListener {
textView, keyCode, keyEvent ->
val DONE = 6
if (keyCode == DONE) {
// your code here
}
false
}