I am trying to use Long
value in Android Databinding
but, just can't get it to work. This is everything I've tried
1: This worked fine. Until I started testing on pre-lollipop and I started experiencing crashes. I had to remove this android:addTextChangedListener="@{outlet.onCapacityChange}"
from the XML
Java
@SerializedName("capacity")
@Expose
Long capacity
/**
*
* @return
* The capacity
*/
@Bindable
public Long getCapacity() {
return capacity;
}
/**
*
* @param capacity
* The capacity
*/
public void setCapacity(Long capacity) {
setAtomicCapacity(capacity);
Log.e(TAG+"Capacity", "" + capacity);
notifyPropertyChanged(BR.capacity);
}
public void setAtomicCapacity(Long basic) {
this.capacity = basic;
}
public TextWatcher onCapacityChange = new SimpleTextWatcher() {
@Override
public void onTextChanged(String newValue) {
Log.e(TAG+"Capacity", newValue);
setAtomicCapacity(Long.valueOf(newValue));
}
};
XML
<EditText
android:id="@+id/outletStockCapacity"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginBottom="16dp"
android:inputType="number"
android:text='@{outlet.capacity != null ? String.valueOf(outlet.capacity) : ""}'
android:addTextChangedListener="@{outlet.onCapacityChange}"
android:singleLine="true"
android:imeOptions="actionNext"/>
2: After changing all android:addTextChangedListener="@{outlet.onCapacityChange}"
to android:text="@={String.valueOf(outlet.capacity)}"
using =
Equal Operator
since two way binding is now provided by default.
Java
@SerializedName("capacity")
@Expose
Long capacity = 0L;
/**
*
* @return
* The capacity
*/
@Bindable
public Long getCapacity() {
return capacity;
}
/**
*
* @param capacity
* The capacity
*/
public void setCapacity(Long capacity) {
setAtomicCapacity(capacity);
Log.e(TAG+"Capacity", "" + capacity);
notifyPropertyChanged(BR.capacity);
}
public void setAtomicCapacity(Long basic) {
this.capacity = basic;
}
XML
<EditText
android:id="@+id/outletStockCapacity"
android:layout_width="match_parent"
android:layout_height="55dp"
android:layout_marginBottom="16dp"
android:inputType="number"
android:text="@={String.valueOf(outlet.capacity)}"
android:singleLine="true"
android:imeOptions="actionNext"/>
The first was working fine on Post Lollipop
but, not working on Pre-Lollipop
. This is my SimpleTextWatcher
public abstract class SimpleTextWatcher implements TextWatcher {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {
onTextChanged(s.toString());
}
public abstract void onTextChanged(String newValue);
}
My project wouldn't build because of this. I don't know why? I checked for null, initialized it and all. But, it wouldn't just build because of that
In short you can use ViewBinding to replace findviewbyid() effectively. If your project is however more complex and you need to add features like binding data to views, binding adapters e.t.c, use DataBinding.
View binding doesn't support layout variables or layout expressions, so it can't be used to declare dynamic UI content straight from XML layout files. View binding doesn't support two-way data binding.
Using data binding can lead to faster development times, faster execution times and more readable and maintained code. Android data binding generates binding classes at compile time for layouts.
Try this android:text="@={outlet.capacityAsString}"
, where capacityAsString is String
(ObservableField<String>
)
I dont think, you can use something like String.valueOf(outlet.capacity)
for two way binding.
EDITED: Really, there is a way to use something like android:text="@={outlet.capacityAsLong}"
, but you have to write custom @InverseBindingAdapter
:
public class MyEditTextBindingAdapters {
@BindingConversion
public static String longToStr(Long value) {
return value != null ? String.valueOf(value) : "";
}
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
public static Long captureLongValue(EditText view) {
long value = 0;
try {
value = Long.parseLong(view.getText().toString());
} catch (NumberFormatException e) {
e.printStackTrace();
}
return value;
}
}
It works perfectly, but you need to set android:inputType="number"
for your EditText.
It is not that you cannot perform two-way binding with long value, but here problem is android:text
will accept String
value, although you are converting long
to String
but if you are performing two-way binding, direct value should be String
.
Simplest solution for this would be, take ObservableField<String>
in your model class, instead of long.
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