我的控件的 2 向数据绑定
2-way data binding for my control
假设我有自定义视图,定义如下以支持数据绑定:
@InverseBindingMethods({@InverseBindingMethod(type = com.jaredrummler.materialspinner.MaterialSpinner.class,
attribute = "app:selectedIndex", event = "app:selectedIndexAttrChanged", method = "getSelectedIndex")})
public class MaterialSpinner extends TextView
{
//...............
public Integer getSelectedIndex()
{
return selectedIndex;
}
@InverseBindingAdapter(attribute = "app:selectedIndex")
public static Integer getSelectedIndex(MaterialSpinner spinner)
{
return spinner.getSelectedIndex();
}
//**************
接下来我需要创建事件selectedIndexArttrChanged
:
@BindingAdapter({"app:selectedIndexAttrChanged"})
public static void setSelectedIndexListener(MaterialSpinner view, final InverseBindingListener selectedIndexChange)
{
}
但我不确定如何设置事件。因为它是静态的,所以我不能把 notifyPropertyChanged
放在那里。你有什么建议吗?
如果我将 BindingAdapter 设为非静态,我的应用程序会崩溃并显示错误消息:
java.lang.IllegalStateException: Required DataBindingComponent is null
in class ActivityMainBinding. A BindingAdapter in MaterialSpinner is
not static and requires an object to use, retrieved from the
DataBindingComponent. If you don't use an inflation method taking a
DataBindingComponent, use DataBindingUtil.setDefaultComponent or make
all BindingAdapter methods static.
我假设你的 MaterialSpinner
没有扩展 AdapterView
。如果是这样,您应该已经为 android:selectedItemPosition
启用了双向数据绑定。
一件事是您不需要 InverseBindingAdapter
和 InverseBindingMethod
。你只需要一个或另一个。在你的情况下,因为你的 InverseBindingAdapter
实际上只是调用 getter,你应该保留 InverseBindingMethod(更少的代码)。
要连接绑定侦听器,请执行以下操作:
@BindingAdapter({"app:selectedIndexAttrChanged"})
public static void setSelectedIndexListener(MaterialSpinner view,
final InverseBindingListener selectedIndexChange)
{
if (selectedIndexChange == null) {
view.setOnItemSelectedListener(null);
return;
}
view.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
selectedIndexChange.onChange();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
mAttrChanged.onChange();
}
});
}
我建议您查看数据绑定附带的 BindingAdapter 的源代码。例如,如果您使用 Android Studio 查找 AdapterViewBindingAdapter
,您将看到一个可用于模板的实现。
假设我有自定义视图,定义如下以支持数据绑定:
@InverseBindingMethods({@InverseBindingMethod(type = com.jaredrummler.materialspinner.MaterialSpinner.class,
attribute = "app:selectedIndex", event = "app:selectedIndexAttrChanged", method = "getSelectedIndex")})
public class MaterialSpinner extends TextView
{
//...............
public Integer getSelectedIndex()
{
return selectedIndex;
}
@InverseBindingAdapter(attribute = "app:selectedIndex")
public static Integer getSelectedIndex(MaterialSpinner spinner)
{
return spinner.getSelectedIndex();
}
//**************
接下来我需要创建事件selectedIndexArttrChanged
:
@BindingAdapter({"app:selectedIndexAttrChanged"})
public static void setSelectedIndexListener(MaterialSpinner view, final InverseBindingListener selectedIndexChange)
{
}
但我不确定如何设置事件。因为它是静态的,所以我不能把 notifyPropertyChanged
放在那里。你有什么建议吗?
如果我将 BindingAdapter 设为非静态,我的应用程序会崩溃并显示错误消息:
java.lang.IllegalStateException: Required DataBindingComponent is null in class ActivityMainBinding. A BindingAdapter in MaterialSpinner is not static and requires an object to use, retrieved from the DataBindingComponent. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
我假设你的 MaterialSpinner
没有扩展 AdapterView
。如果是这样,您应该已经为 android:selectedItemPosition
启用了双向数据绑定。
一件事是您不需要 InverseBindingAdapter
和 InverseBindingMethod
。你只需要一个或另一个。在你的情况下,因为你的 InverseBindingAdapter
实际上只是调用 getter,你应该保留 InverseBindingMethod(更少的代码)。
要连接绑定侦听器,请执行以下操作:
@BindingAdapter({"app:selectedIndexAttrChanged"})
public static void setSelectedIndexListener(MaterialSpinner view,
final InverseBindingListener selectedIndexChange)
{
if (selectedIndexChange == null) {
view.setOnItemSelectedListener(null);
return;
}
view.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
selectedIndexChange.onChange();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
mAttrChanged.onChange();
}
});
}
我建议您查看数据绑定附带的 BindingAdapter 的源代码。例如,如果您使用 Android Studio 查找 AdapterViewBindingAdapter
,您将看到一个可用于模板的实现。