Reputation: 49
I am attempting to make a page in my Android app that allows the user to enter a Float value in an EditText and binds that value to my view model. Here is my code for my current binding adapter:
import android.text.SpannableStringBuilder
import android.widget.EditText
import androidx.databinding.BindingAdapter
import androidx.databinding.InverseBindingAdapter
@BindingAdapter("android:text")
fun setText(view: EditText, value: Float?) {
view.text = value?.let { SpannableStringBuilder(value.toString()) } ?: SpannableStringBuilder("")
}
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
fun getTextString(view: EditText): Float? {
val editTextString: String? = view.text?.toString()
return if(editTextString == null || editTextString == "") 0.0f else editTextString.toString().toFloat()
}
Here is the code that I have for my EditText in my layout file:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/amount_edit_text_outer"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="@dimen/edit_text_width"
android:layout_height="@dimen/edit_text_height"
android:layout_gravity="center"
android:hint="@string/edit_text_hint"
app:layout_constraintBottom_toTopOf="@+id/fab"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/amount_edit_text_inner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@={viewmodel.liveAmount$app_debug}"
android:inputType="numberDecimal" />
</com.google.android.material.textfield.TextInputLayout>
Finally, my view model live data variable looks like this:
internal val liveAmount = MutableLiveData<Float>(0.0f)
I should also add that when I run this code on my phone, it allows me to enter the first number in the EditText and nothing else. Furthermore, the keyboard does not go away unless I kill the app. Any questions or comments are welcome. Thank you all for any help!
Upvotes: 0
Views: 1629
Reputation: 3212
Try changing this:
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
to:
@InverseBindingAdapter(attribute = "android:text")
And add this other method:
// This notifies the data binding system that the attribute value has changed.
@BindingAdapter("android:textAttrChanged")
fun setTextChangedListener(editText: TextInputEditText, listener: InverseBindingListener) {
editText.addTextChangedListener(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?) {
listener.onChange()
}
})
}
This is not tested, but it should work or at least be close. See here for other similar examples:
Upvotes: 1