Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Long Value In Android Databinding

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

like image 490
Tonespy Avatar asked Aug 16 '16 14:08

Tonespy


People also ask

Which is better ViewBinding and DataBinding?

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.

Can I use both DataBinding and ViewBinding?

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.

When should I use DataBinding?

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.


2 Answers

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.

like image 147
Roman_D Avatar answered Oct 13 '22 09:10

Roman_D


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.

like image 36
Ravi Avatar answered Oct 13 '22 11:10

Ravi