Android 使用@InverseBindingAdapter / AttrChanged 的​​微调器双向绑定不起作用

Android Spinner two-way binding with @InverseBindingAdapter / AttrChanged doesn't work

我一直在尝试在 Spinner 上设置双向绑定。

网络上和堆栈溢出上有很多这样的例子,但 none 对我有用。

它只是一个国家微调器,我用这个方法为它定义了一个国家适配器:

@InverseBindingAdapter(attribute = "selectedCountry", event = "selectedCountryAttrChanged")
public static String bindCountryInverseAdapter(AppCompatSpinner pAppCompatSpinner) {
    Object selectedItem = pAppCompatSpinner.getSelectedItem();
    SpinnerAdapter adapter = pAppCompatSpinner.getAdapter();
    if (adapter instanceof CountrySpinnerAdapter) {
        return (String) selectedItem;
    }
    throw new UnsupportedOperationException("The adapter must be a CountrySpinnerAdapter");
}

@BindingAdapter(value = "selectedCountryAttrChanged", requireAll = false)
public static void bindCountryChanged(AppCompatSpinner pAppCompatSpinner, final InverseBindingListener newTextAttrChanged) {
    AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            newTextAttrChanged.onChange();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            newTextAttrChanged.onChange();
        }
    };
    pAppCompatSpinner.setOnItemSelectedListener(listener);

}

@BindingAdapter("selectedCountry")
public static void bindCountryValue(AppCompatSpinner pAppCompatSpinner, String newSelectedValue) {
    SpinnerAdapter adapter = pAppCompatSpinner.getAdapter();
    if (adapter instanceof CountrySpinnerAdapter) {
        ((CountrySpinnerAdapter) adapter).bindSelectedValue(pAppCompatSpinner, newSelectedValue);
        return;
    }
    throw new UnsupportedOperationException("The adapter must be a CountrySpinnerAdapter");
}

从未调用 bindCountryChanged 方法。

我也试过这个变体(在其他例子之后):

@BindingAdapter(value = {"selectedCountry", "selectedCountryAttrChanged"}, requireAll = false)
public static void bindCountryValueChanged(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InverseBindingListener newTextAttrChanged) {
    AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            newTextAttrChanged.onChange();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            newTextAttrChanged.onChange();
        }
    };
    pAppCompatSpinner.setOnItemSelectedListener(listener);

}

已调用,但 newTextAttrChanged 始终为空。

排版、装订部分:

<data>
    <variable
        name="customer"
        type="my.package.CustomerBinding" />
</data>

和小部件:

<android.support.v7.widget.AppCompatSpinner
    android:id="@+id/editCountry"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:spinnerMode="dropdown"
    app:adapter="@{customer.countrySpinnerAdapter}"
    app:selectedCountry="@{customer.country}" />

country id 只是一个 ObservableField<String>countrySpinnerAdapter 是一个 BaseAdapter 国家列表。

Android gradle 插件:

classpath 'com.android.tools.build:gradle:2.2.1'

工具版本:

buildToolsVersion "24.0.2"

当然数据绑定已启用:

dataBinding {
    enabled = true
}

为什么 newTextAttrChanged 总是 null / BindingAdapter 从未被调用?我做错了什么?

您在绑定表达式中缺少 = 以通知系统您希望将此绑定用作双向绑定。

app:selectedCountry="@{customer.country}"

应该是

app:selectedCountry="@={customer.country}"