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 PMstreetsofboston
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