Skip to content

Instantly share code, notes, and snippets.

@terrakok

terrakok/SmartField.kt

Last active Sep 18, 2017
Embed
What would you like to do?
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.EditText
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 18.09.17.
*/
class SmartField<T: Any>(
private val editText: EditText,
defaultValue: T,
private val formatter: (T) -> String,
private val extractor: (String) -> T,
private val changeListener: (T) -> Unit,
private val isLiveUpdate: Boolean = false
) {
val currentValue get() = extractor(editText.text.toString())
private val watcher = object : TextWatcher {
private var v = ""
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
v = editText.text.toString()
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { }
override fun afterTextChanged(p0: Editable?) {
val newVal = extractor(editText.text.toString())
if (isLiveUpdate && extractor(v) != newVal) {
changeListener(newVal)
}
}
}
init {
editText.setText(formatter(defaultValue))
if (!isLiveUpdate) {
editText.onFocusChangeListener = View.OnFocusChangeListener { view, focus ->
if (!focus) changeListener(extractor(editText.text.toString()))
}
}
enableWatcher()
}
fun setValue(value: T) {
disableWatcher()
with(formatter(value)) {
editText.setText(this)
editText.setSelection(this.length)
}
enableWatcher()
}
private fun enableWatcher() = editText.addTextChangedListener(watcher)
private fun disableWatcher() = editText.removeTextChangedListener(watcher)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment