Mohamed Ibrahim
03/13/2020, 8:48 PMflow {…}
builder, So I’m creating a watcher inside it here is the code, my question is how I clear inner listeners when flow canceled ?
fun EditText.textChangesFlow(): Flow<TextViewTextChangeEvent> {
flow<TextViewTextChangeEvent> {
val watcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
emit(TextViewTextChangeEvent(s.toString()))
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
addTextChangedListener(watcher)
//how to call this when flow is canceled or finished
//removeTextChangedListener(watcher)
}
}
streetsofboston
03/13/2020, 8:51 PMawaitClose { … clear inner listeners here … }
at the end of your flow { … }
lambda:
flow<TextViewTextChangedEvent> {
...
...
awaitClose { removeTextChangedListener(watcher) }
}
kevin.cianfarini
03/13/2020, 8:57 PMchannelFlow
not flow
. Within the scope of channelFlow you can use awaitClose. You must also change emit
to send
channelFlow<TextViewTextChangedEvent> {
...
...
awaitClose { removeTextChangedListener(watcher) }
}
Mohamed Ibrahim
03/13/2020, 9:03 PMtextChangesFlow
suspend function, I have a compile error with send()
and emit()
kevin.cianfarini
03/13/2020, 9:03 PMstreetsofboston
03/13/2020, 9:08 PMafterTextChanged
is not suspend. So yes, either use offer(…)
or wrap it inside a launch: launch { send(…) }
.Mohamed Ibrahim
03/13/2020, 9:14 PMlaunch{...}
but is it safe to call?streetsofboston
03/13/2020, 9:45 PMtseisel
03/14/2020, 8:41 AMcallbackFlow
instead of channelFlow
. While both provide exactly the same behavior, callbackFlow
makes the intent clearer in this case. Also, since 1.3.4 there is a lint warning with callbackFlow
that notifies you if you forget about awaitClose
.dekans
03/14/2020, 4:47 PM