场景:在搜索框中输入内容,实时进行搜索,结果以列表形式展现。
搜索时,为了避免产生无意义的搜索请求,通常会进行限流处理。熟悉 RxJava
的同学,一定会知道怎么做,各种天花乱坠的操作符让你眼花缭乱。
这里采用 flow
的方式,不多说,直接上代码:
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.onFailure
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
@ExperimentalCoroutinesApi
fun EditText.onTextChangedFlow() = callbackFlow {
val watcher = 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?) {
s?.let { value -> trySend(value).onFailure { e -> e?.printStackTrace() } }
}
}
addTextChangedListener(watcher)
awaitClose { removeTextChangedListener(watcher) }
}
使用姿势:
lifecycleScope.launch {
mBinding.edit.onTextChangedFlow()
.debounce(200)
.filter { it.isNotEmpty() }
.distinctUntilChanged()
.catch { print(it.message) }
.flowOn(Dispatchers.IO)
.collect {
// 网络请求获取搜索结果
}
}
这时候 AndroidStudio
会有警告:
不用太在意,强迫症可以在 build.gradle
中添加如下代码消除警告:
kotlinOptions {
jvmTarget = '1.8'
// 移除试验性和预览的 Api 警告
freeCompilerArgs += "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
freeCompilerArgs += "-Xopt-in=kotlinx.coroutines.FlowPreview"
}
网友评论