在 android:text 的 EditText 上为 Short 和 Integer 值创建不同的 InverseBindingAdapter

create different InverseBindingAdapter for Short and Integer values on android:text of EditText

我为自定义数据绑定创建了这些方法

@BindingAdapter("android:text")
public static void setShortText(TextView view, short value) {
    view.setText(String.valueOf(value));
}

@InverseBindingAdapter(attribute = "android:text")
public static Short getShortText(TextView view) {
    try {
        return Short.parseShort(view.getText().toString());
    } catch (NumberFormatException e) {
        return null;
    }
}

@BindingAdapter("android:text")
public static void setIntText(TextView view, int value) {
    view.setText(String.valueOf(value));
}

@InverseBindingAdapter(attribute = "android:text")
public static Integer getIntText(TextView view) {
    try {
        return Integer.parseInt(view.getText().toString());
    } catch (NumberFormatException e) {
        return null;
    }
}

并将我的 Short 和 Integer 变量绑定到视图。当我构建我的项目时,自动生成的 java 使用前三种方法,而第四种方法 (getIntText) 没有使用,问题就在这里。它对整数字段使用 getShortText 并导致编译时 casting 错误。

我很惊讶,数据绑定器正确检测到它应该使用 setIntText 将整数值设置为视图,但它无法识别 inverseBinding。

我该如何解决这个问题?

请注意,我不喜欢使用以下技术,因为我想在数据为空时控制绑定

android:text="@={`` + obj.field}

我找到了解决办法,但实在不满意自己。 我将 getIntText return 值从 Integer 更改为 int,问题就解决了。 如果有人找到其他更好的解决方案,请告诉我。

@InverseBindingAdapter(attribute = "android:text")
public static int getIntText(TextView view) {
    try {
        return Integer.parseInt(view.getText().toString());
    } catch (NumberFormatException e) {
        return -1;
    }
}

为了使此解决方案正常工作,有必要使其能够接收空值,并检查 TextView 的新值是否与先前的值不同。 如果我契约,绑定方法将永远执行。

这是我的解决方案:

@BindingAdapter("android:text")
fun setBindShortText(view: TextView, value: Short?) {
    value?.let {
        if (!it.toString().contentEquals(view.text))
            view.text = it.toString()
    }
}
@InverseBindingAdapter(attribute = "android:text")
fun getBindShortText(view: TextView): Short? {
    return try {
        view.text.toString().toShort()
    } catch (e: java.lang.NumberFormatException) {
        null
    }
}


@BindingAdapter("android:text")
fun setBindIntText(view: TextView, value: Int?) {
    value?.let {
        if (!it.toString().contentEquals(view.text))
            view.text = it.toString()
    }
}
@InverseBindingAdapter(attribute = "android:text")
fun getBindIntText(view: TextView): Int? {
    return try {
        view.text.toString().toInt()
    } catch (e: NumberFormatException) {
        null
    }
}