Kotlin addTextChangeListener lambda?
comment construire une expression lambda pour L'EditText addTextChangeListener dans Kotlin? Ci-dessous donne une erreur:
passwordEditText.addTextChangedListener { charSequence ->
try {
password = charSequence.toString()
} catch (error: Throwable) {
raise(error)
}
}
6 réponses
addTextChangedListener()
prend un TextWatcher
qui est une interface avec 3 méthodes. Ce que vous avez écrit ne fonctionne que si TextWatcher
n'avait qu'une méthode. Je suppose que l'erreur que vous faites est liée au fait que votre lambda n'a pas implémenté les 2 autres méthodes. Vous avez 2 options.
1) laissez tomber la lambda et utilisez simplement une classe interne anonyme
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) Créer une méthode d'extension pour que vous puissiez utiliser une expression lambda:
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())
}
})
}
Et ensuite utiliser l'extension de la sorte:
editText.afterTextChanged { doSomethingWithText(it) }
un peu vieux, mais en utilisant les extensions Android de Kotlin vous pouvez faire quelque chose comme ça:
editTextRequest.textChangedListener {
afterTextChanged {
// Do something here...
}
}
Pas de code supplémentaire est nécessaire, il suffit d'ajouter:
implementation 'androidx.core:core-ktx:1.0.0-alpha1'
espérons que ce Kotlin
exemple d'aide explicitant:
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
}
}
avec ceci XML
mise en page:
<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>
Et 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
quelques exemples:
Rx
RxTextView
.afterTextChangeEvents(editText)
.subscribe { presenter.onTextChanged(it.editable().toString())}
C'est cool de faire quelque chose comme ceci
RxTextView
.afterTextChangeEvents(editText)
.skipInitialValue()
.debounce(500L, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { presenter.onTextChanged(it.editable().toString())}
.autoDispose()
j'ai un poussiéreux de la classe, mais vous pouvez le changer facilement (ou pas)
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);
}
}
Kotlin
editSearch.addTextChangedListener(SimpleTextWatcher{ presenter.onTextChanged(it.toString())})
ou Extension, mais je ne vais pas me répéter
une Autre alternative est le KAndroid
bibliothèque
implementation 'com.pawegio.kandroid:kandroid:0.8.7@aar'
alors vous pourriez faire quelque chose comme ça...
editText.textWatcher { afterTextChanged { doSomething() } }
évidemment, il est excessif d'utiliser une bibliothèque entière pour résoudre votre problème, mais il est également livré avec une gamme d'autres extensions utiles qui éliminent le code boilerplate dans le SDK Android.
Cette air soigné:
passwordEditText.setOnEditorActionListener {
textView, keyCode, keyEvent ->
val DONE = 6
if (keyCode == DONE) {
// your code here
}
false
}