如何使用 Coroutines Flow 根据另一个视图中的更改修改一个视图?
How to use Coroutines Flow to modify one view based on the change in another view?
我有两个编辑文本每当我输入一个编辑文本时,我都想发出数据并填充另一个编辑文本。在下面找到我试过的代码
class MainActivity : AppCompatActivity() {
private var editText : EditText? = null
private var editText1 : EditText? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val linearLayout = LinearLayout(baseContext)
linearLayout.orientation = LinearLayout.VERTICAL
editText = EditText(baseContext)
editText1 = EditText(baseContext)
linearLayout.addView(editText)
linearLayout.addView(editText1)
setContentView(linearLayout)
CoroutineScope(Dispatchers.Main).launch {
sendData().collect{
editText!!.setText(it)
}
}
}
private fun sendData() = flow {
editText1?.addTextChangedListener {
emit(it.toString())
}
}.flowOn(Dispatchers.Default)
}
你真的需要为此使用 Flow
吗?
editText?.addTextChangedListener{ editable ->
editText1.setText(editable.toString())
}
编辑:
由于这只是为了学习目的,所以有机会使用callbackFlow
。但是你必须小心在发射后关闭回调:
fun listenTextChange(): Flow<String> = callbackFlow{
editText.addTextChangeListener{
offer(it.toString())
}
awaitClose{ editText.removeListener() //if there is one or just make the callback null }
}
然后,您可以:
listenTextChange().collect{text ->
editText1.setText(text)
}
Kotlin 扩展函数版本:
@ExperimentalCoroutinesApi
val EditText.textFlow: Flow<String>
get() = callbackFlow {
val textWatcher = doAfterTextChanged { offer(it.toString()) }
awaitClose { removeTextChangedListener(textWatcher) }
}
另一种解决方案如下;
每当您输入 editText 时,TextView 都会更新。
class MainActivity : AppCompatActivity() {
private lateinit var editText: EditText
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
editText = findViewById(R.id.edit_query)
textView = findViewById(R.id.text_view)
lifecycleScope.launch {
listenTextChange().collect { str ->
textView.text = str
}
}
}
@ExperimentalCoroutinesApi
fun listenTextChange(): Flow<String> = callbackFlow {
val watcher = 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?) {
trySend(editable.toString())
}
}
editText.addTextChangedListener(watcher)
awaitClose {
editText.removeTextChangedListener(watcher)
}
}
}
我有两个编辑文本每当我输入一个编辑文本时,我都想发出数据并填充另一个编辑文本。在下面找到我试过的代码
class MainActivity : AppCompatActivity() {
private var editText : EditText? = null
private var editText1 : EditText? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val linearLayout = LinearLayout(baseContext)
linearLayout.orientation = LinearLayout.VERTICAL
editText = EditText(baseContext)
editText1 = EditText(baseContext)
linearLayout.addView(editText)
linearLayout.addView(editText1)
setContentView(linearLayout)
CoroutineScope(Dispatchers.Main).launch {
sendData().collect{
editText!!.setText(it)
}
}
}
private fun sendData() = flow {
editText1?.addTextChangedListener {
emit(it.toString())
}
}.flowOn(Dispatchers.Default)
}
你真的需要为此使用 Flow
吗?
editText?.addTextChangedListener{ editable ->
editText1.setText(editable.toString())
}
编辑:
由于这只是为了学习目的,所以有机会使用callbackFlow
。但是你必须小心在发射后关闭回调:
fun listenTextChange(): Flow<String> = callbackFlow{
editText.addTextChangeListener{
offer(it.toString())
}
awaitClose{ editText.removeListener() //if there is one or just make the callback null }
}
然后,您可以:
listenTextChange().collect{text ->
editText1.setText(text)
}
Kotlin 扩展函数版本:
@ExperimentalCoroutinesApi
val EditText.textFlow: Flow<String>
get() = callbackFlow {
val textWatcher = doAfterTextChanged { offer(it.toString()) }
awaitClose { removeTextChangedListener(textWatcher) }
}
另一种解决方案如下; 每当您输入 editText 时,TextView 都会更新。
class MainActivity : AppCompatActivity() {
private lateinit var editText: EditText
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
editText = findViewById(R.id.edit_query)
textView = findViewById(R.id.text_view)
lifecycleScope.launch {
listenTextChange().collect { str ->
textView.text = str
}
}
}
@ExperimentalCoroutinesApi
fun listenTextChange(): Flow<String> = callbackFlow {
val watcher = 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?) {
trySend(editable.toString())
}
}
editText.addTextChangedListener(watcher)
awaitClose {
editText.removeTextChangedListener(watcher)
}
}
}