In Android we can use 2-way data-binding with @=
in front of variable. But, that variable is a double
. So for displaying it in EditText
, I need to convert it to String
using String.valueOf(pojo.value)
.
If I attach =
in front for two-way data binding it simply just not compile.
If I attach a onTextChanged
and set the value there, I looses the cursor. Is there any workaround?
Edit:
It worked with InverseBindingAdapter
but doesn't allow .
(period) to be typed.
Here's how I did it.
//-------------------------------------------------------------------------------------------------//
@BindingAdapter("app:text")
fun setDoubleInTextView(tv: TextView, dbl: Double?) {
try {
//This will occur when view is first created or when the leading zero is omitted
if (dbl == null && (tv.text.toString() == "" || tv.text.toString() == ".")) return
//Check to see what's already there
val tvDbl = tv.text.toString().toDouble()
//If it's the same as what we've just entered then return
// This is when then the double was typed rather than binded
if (tvDbl == dbl)
return
//If it's a new number then set it in the tv
tv.text = dbl?.toString()
} catch (nfe: java.lang.NumberFormatException) {
//This is usually caused when tv.text is blank and we've entered the first digit
tv.text = dbl?.toString() ?: ""
}//catch
}//setDoubleInTextView
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -//
@InverseBindingAdapter(attribute = "app:text")
fun getDoubleFromTextView(editText: TextView): Double? {
return try {
editText.text.toString().toDouble()
} catch (e: NumberFormatException) {
null
}//catch
}//getDoubleFromTextView
//-------------------------------------------------------------------------------------------------//
@BindingAdapter("textAttrChanged")
fun setTextChangeListener(editText: TextView, listener: InverseBindingListener) {
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) = listener.onChange()
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
Log.d(TAG, "beforeTextChanged $p0")
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
Log.d(TAG, "onTextChanged $p0")
}
})
}
//-------------------------------------------------------------------------------------------------//
<EditText
style="@style/TextAppearance.MaterialComponents.Body1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/price"
android:inputType="numberDecimal"
app:text="@={viewModel.tempProductPrice}"/>
The EditText has the following setting to force the correct input
android:inputType="numberDecimal"
This works for me (2020):
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="@={`` + viewModel.currentStudent.age}" //key point!! Not single/double quote
android:inputType="number" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With