在 Android 数据绑定中使用长值

Using Long Value In Android Databinding

我正在尝试使用 Android Databinding 中的 Long 值,但是无法正常工作。这就是我尝试过的一切

1:这很好用。直到我开始测试 pre-lollipop 之前,我开始遇到崩溃。我不得不从 XML

中删除这个 android:addTextChangedListener="@{outlet.onCapacityChange}"
    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: 在使用 = Equal Operator 将所有 android:addTextChangedListener="@{outlet.onCapacityChange}" 更改为 android:text="@={String.valueOf(outlet.capacity)}" 之后,因为现在默认提供双向绑定。

    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"/>

第一个在 Post Lollipop 上运行良好,但在 Pre-Lollipop 上运行不佳。这是我的 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);
}

我的项目因此无法构建。我不知道为什么?我检查了 null,初始化了它和所有的东西。但是,它不会因此而构建

试试这个 android:text="@={outlet.capacityAsString}",其中 capacityAsString 是 String (ObservableField<String>) 我不认为,您可以使用 String.valueOf(outlet.capacity) 之类的东西进行双向绑定。

已编辑:确实,有一种方法可以使用类似 android:text="@={outlet.capacityAsLong}" 的方法,但您必须编写自定义 @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;
    }
}

它完美运行,但您需要为您的 EditText 设置 android:inputType="number"

并不是说你不能用长值执行双向绑定,但这里的问题是 android:text 将接受 String 值,尽管你正在将 long 转换为 String 但如果是双向绑定,直接取值应该是 String.

最简单的解决方案是,在您的模型 class 中使用 ObservableField<String>,而不是 long。