使用Kotlin创建动态Android TextWatcher
Today there’s 1 Pull Request that attract my attention. This code is part of a simple calculator activity. It listen to a field to calculate the total nominal and shows it in a TextView.
今天有1個請求請求吸引了我的注意。 此代碼是簡單的計算器活動的一部分。 它偵聽一個字段以計算總標稱并將其顯示在TextView中。
seratus_ribu.addTextChangedListener(object : TextWatcher {override fun afterTextChanged(s: Editable) {}override fun beforeTextChanged(s: CharSequence,start: Int,count: Int,after: Int) {}override fun onTextChanged(s: CharSequence,start: Int,before: Int,count: Int) {val sumPaidInstallment = sumPaidInstallment()val txtNominal ="${DisplayHelper.formatCurrency(sumPaidInstallment)} / ${DisplayHelper.formatCurrency(totalPaidInstallment)}"angsuran.text = txtNominal}})Repeat this code for 11 field and you got a large code with lot of empty space and empty implementation. With java, there’s nothing you can do. You just accept it. But with kotlin, code like this become more and more unacceptable.
對11個字段重復此代碼,您將獲得一個大型代碼,其中包含大量空白空間和空的實現。 使用Java,您無能為力。 您只接受它。 但是使用kotlin,這樣的代碼變得越來越難以接受。
To fix it we can leverage lambda in kotlin. So I created a DynamicTextWatcher class that extend TextWatcher and implemented all the method. This class constructor accepted 3 lambda that each correlate with a TextWatcher function. This way you can just pass your function without having to implement the other empty function.
要解決此問題,我們可以利用Kotlin中的lambda。 因此,我創建了一個DynamicTextWatcher類,該類擴展了TextWatcher并實現了所有方法。 此類的構造函數接受3個lambda,每個lambda與一個TextWatcher函數相關。 這樣,您就可以傳遞函數而不必實現其他空函數。
class DynamicTextWatcher(private val afterChanged: (Editable?) -> Unit,private val beforeChanged: (CharSequence?, Int, Int, Int) -> Unit,private val onChanged: (CharSequence?, Int, Int, Int) -> Unit ) : TextWatcher {override fun afterTextChanged(s: Editable?) {afterChanged(s)}override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {beforeChanged(s, start, count, after)}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {onChanged(s, start, before, count)} }But this implementation still requires you to pass empty lambda for the function that you didn’t use. We can again leverage kotlin feature by making the parameter as optional parameter. The only thing we need to do is giving the parameters default value.
但是此實現仍然需要您為未使用的函數傳遞空的lambda。 通過將參數設為可選參數,我們可以再次利用kotlin功能。 我們唯一需要做的就是給參數提供默認值。
class DynamicTextWatcher(private val afterChanged: ((Editable?) -> Unit) = {},private val beforeChanged: ((CharSequence?, Int, Int, Int) -> Unit) = { _, _, _, _ -> },private val onChanged: ((CharSequence?, Int, Int, Int) -> Unit) = { _, _, _, _ -> } ) : TextWatcher {override fun afterTextChanged(s: Editable?) {afterChanged(s)}override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {beforeChanged(s, start, count, after)}override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {onChanged(s, start, before, count)} }Thus now the code can be called like this
因此,現在可以像這樣調用代碼
seratus_ribu.addTextChangedListener(DynamicTextWatcher(onChanged = { _, _, _, _ ->val sumPaidInstallment = sumPaidInstallment()val txtNominal ="${DisplayHelper.formatCurrency(sumPaidInstallment)} / ${DisplayHelper.formatCurrency(totalPaidInstallment)}"angsuran.text = txtNominal}))A whole lot of line has gone. Code that doesn’t matter, boiler plate. Now we an focus directly to the code that matters.
很多行已經走了。 沒關系的代碼,樣板。 現在,我們直接將重點放在重要的代碼上。
Turn out the original coder has done a good job of centralizing the calculation. So we can extract the onChanged into a single val resulting the final code to become like this
原來的編碼器在集中計算方面做得很好。 因此,我們可以將onChanged提取到單個val中,從而使最終代碼變得像這樣
....val nominalWatcher = DynamicTextWatcher(onChanged = { _, _, _, _ ->updateNominal(totalPaidInstallment)})seratus_ribu.addTextChangedListener(nominalWatcher)lima_puluh_ribu.addTextChangedListener(nominalWatcher)dua_puluh_ribu.addTextChangedListener(nominalWatcher)sepuluh_ribu.addTextChangedListener(nominalWatcher)lima_ribu.addTextChangedListener(nominalWatcher)dua_ribu.addTextChangedListener(nominalWatcher)seribu.addTextChangedListener(nominalWatcher)seribu_logam.addTextChangedListener(nominalWatcher)lima_ratus.addTextChangedListener(nominalWatcher)dua_ratus.addTextChangedListener(nominalWatcher)seratus.addTextChangedListener(nominalWatcher)}private fun updateNominal(totalPaidInstallment: Int) {val sumPaidInstallment = sumPaidInstallment()val txtNominal ="${DisplayHelper.formatCurrency(sumPaidInstallment)} / ${DisplayHelper.formatCurrency(totalPaidInstallment)}"angsuran.text = txtNominal}138 line of code reduced to 24 line in minutes.
138行代碼在幾分鐘內減少到24行。
They say programming language is only a tool. But choosing the right tool can save you a lot of work.
他們說編程語言只是一種工具。 但是選擇正確的工具可以節省大量工作。
Turn out this already exist as Android-ktx implementation. The implementation is quite similar. So it’s interesting to see the difference.
原來這已經作為Android-ktx實現存在。 實現非常相似。 因此,看到差異很有趣。
See the ktx implementation here. To use the ktx implementation the code needs to be modified to be like this:
在此處查看ktx實現。 要使用ktx實現,需要修改代碼,如下所示:
val nominalWatcher = { _:CharSequence?, _: Int, _: Int, _: Int -> updateNominal(totalPaidInstallment) }seratus_ribu.addTextChangedListener(onTextChanged = nominalWatcher)seratus_ribu.addTextChangedListener(onTextChanged = nominalWatcher)lima_puluh_ribu.addTextChangedListener(onTextChanged = nominalWatcher)dua_puluh_ribu.addTextChangedListener(onTextChanged = nominalWatcher)sepuluh_ribu.addTextChangedListener(onTextChanged = nominalWatcher)lima_ribu.addTextChangedListener(onTextChanged = nominalWatcher)dua_ribu.addTextChangedListener(onTextChanged = nominalWatcher)seribu.addTextChangedListener(onTextChanged = nominalWatcher)seribu_logam.addTextChangedListener(onTextChanged = nominalWatcher)lima_ratus.addTextChangedListener(onTextChanged = nominalWatcher)dua_ratus.addTextChangedListener(onTextChanged = nominalWatcher)seratus.addTextChangedListener(onTextChanged = nominalWatcher)翻譯自: https://medium.com/@abangkis/creating-dynamic-android-textwatcher-using-kotlin-fb5a4bc24996
總結
以上是生活随笔為你收集整理的使用Kotlin创建动态Android TextWatcher的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [css] 如何解决html设置hei
- 下一篇: 前端学习(2841):UI开发思路--搭