Android 数据绑定(bind) - 找不到属性的 getter

标签 android android-layout android-databinding

this answer 中看到后,我使用了一些旋转器绑定(bind).但是在那之后我无法编译代码。

错误

Found data binding errors. ****/ data binding error ****msg:Cannot find the getter for attribute 'selectedValue' with value type java.lang.String on android.widget.Spinner. file:D:\Khemraj_AndroidStudioWorkspace_\amelioFinal\app\src\main\res\layout\activity_cart.xml loc:167:24 - 175:33 ****\ data binding error ****

波乔

public class ViewModel {
    private String text;
    public String getText() {
        return text;
    }

    public void setText(String text)
    {
       this.text = text;
    }
}

在 xml 中

  <variable
        name="viewModel"
        type="com.amelio.model.ViewModel"/>

  <android.support.v7.widget.AppCompatSpinner
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:entries="@array/days"
            bind:selectedValue="@={viewModel.text}"/>

绑定(bind)工具

public class SpinnerBindingUtil {

    @BindingAdapter(value = {"selectedValue", "selectedValueAttrChanged"}, requireAll = false)
    public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InverseBindingListener newTextAttrChanged) {
        pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                newTextAttrChanged.onChange();
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        if (newSelectedValue != null) {
            int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue);
            pAppCompatSpinner.setSelection(pos, true);
        }
    }
    @InverseBindingAdapter(attribute = "selectedValue", event = "selectedValueAttrChanged")
    public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) {
        return (String) pAppCompatSpinner.getSelectedItem();
    }

}

最佳答案

android:selectedItemPosition 属性支持开箱即用的双向数据绑定(bind)。您可以使用它或使用它的 BindingAdapter/InverseBindingAdapter 对作为模板:

@InverseBindingMethods({
    @InverseBindingMethod(type = AdapterView.class, attribute = "android:selectedItemPosition"),
    @InverseBindingMethod(type = AdapterView.class, attribute = "android:selection",
            method = "getSelectedItemPosition",
            event = "android:selectedItemPositionAttrChanged"),
})

...

@BindingAdapter("android:selectedItemPosition")
public static void setSelectedItemPosition(AdapterView view, int position) {
    if (view.getSelectedItemPosition() != position) {
        view.setSelection(position);
    }
}

@BindingAdapter(value = {"android:onItemSelected", "android:onNothingSelected",
        "android:selectedItemPositionAttrChanged" }, requireAll = false)
public static void setOnItemSelectedListener(AdapterView view, final OnItemSelected selected,
        final OnNothingSelected nothingSelected, final InverseBindingListener attrChanged) {
    if (selected == null && nothingSelected == null && attrChanged == null) {
        view.setOnItemSelectedListener(null);
    } else {
        view.setOnItemSelectedListener(
                new OnItemSelectedComponentListener(selected, nothingSelected, attrChanged));
    }
}

这会导致我做这样的事情:

@InverseBindingMethods({
    @InverseBindingMethod(type = AdapterView.class,
                          attribute = "android:selectedValue",
                          method = "getSelectedItem"
})
public class SelectedValueBindingAdapter {
    @BindingAdapter("android:selectedValueAttrChanged")
    public static void setSelectedValueListener(AdapterView view,
            final InverseBindingListener attrChanged) {
        if (attrChanged == null) {
            view.setOnItemSelectedListener(null);
        } else {
            view.setOnItemSelectedListener(new OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    attrChanged.onChange();
                }
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    attrChanged.onChange();
                }
            });
        }
    }

    @BindingAdapter("android:selectedValue")
    public static void setSelectedValue(AdapterView<?> view, Object selectedValue) {
        Adapter adapter = view.getAdapter();
        if (adapter == null) {
            return;
        }
        // I haven't tried this, but maybe setting invalid position will
        // clear the selection?
        int position = AdapterView.INVALID_POSITION;

        for (int i = 0; i < adapter.getCount(); i++) {
            if (adapter.getItem(i) == selectedValue) {
                position = i;
                break;
            }
        }
        view.setSelection(position);
    }
}

关于Android 数据绑定(bind) - 找不到属性的 getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50323830/

相关文章:

android - 使用 MPAndroidChart 库时 width and height must be > 0 错误

android - 卡片布局操作按钮

android - 如何使数据绑定(bind)与 xml 属性一起工作?

android - 数据绑定(bind) : Pass LiveData as is to BindingAdapter and observe it using a LifecycleOwner

java - LocationListener 中的 onStatusChanged(String,int,Bundle) 已被弃用

android - 跨平台 xamarin 应用程序和 native 库绑定(bind)

android - 如何在android中解析Facebook的下一页(SDK 4.0)图形响应?

Android 最小宽度布局

Android 数据绑定(bind) onLongClick 不工作

android - Ionic2/3 angular google maps TypeError : Object(. ..) 不是新 FitBoundsService 的函数