Android BindingAdapter的执行顺序?
Android BindingAdapter order of execution?
我需要了解数据绑定库如何确定其 BindingAdapter 的执行顺序。如果一个View有两个BindingAdapters,如果这个View有这两个BindingAdapters对应的属性,那么它如何确定先执行哪个adapter呢?我问是因为执行顺序对我来说很重要。
我有以下 BindingAdapter/s:
public class SpinnerBindingAdapter {
@BindingAdapter(value = {"entries"})
public static void setEntries(Spinner spinner, List<? extends SpinnerItem> spinnerItems) {
for (int i = 0; i < spinnerItems.size(); i++) {
spinnerItems.get(i).setIndex(i);
}
ArrayAdapter<? extends SpinnerItem> adapter =
new ArrayAdapter<>(spinner.getContext(), R.layout.spinner_item, spinnerItems);
spinner.setAdapter(adapter);
}
@InverseBindingAdapter(attribute = "selectedItem", event = "selectedItemAttrChanged")
public static Object getSelectedItem(Spinner spinner) {
Object selectedItem = spinner.getSelectedItem();
return selectedItem;
}
@BindingAdapter(value = {"selectedItem"})
public static void setSelectedItem(Spinner spinner, SpinnerItem spinnerItem) {
if (spinner.getAdapter() == null) {
return;
}
// Other code omitted for simplicity
}
@BindingAdapter(value = {"selectedItemAttrChanged"}, requireAll = false)
public static void setOnItemSelectedListener(Spinner spinner, final InverseBindingListener selectedItemChange) {
if (selectedItemChange == null) {
spinner.setOnItemSelectedListener(null);
} else {
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedItemChange.onChange();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}
}
下面是我如何填充微调器并设置选择:
<Spinner
android:id="@+id/spinner_system_activity_edit_tracker_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
app:entries="@{DatabaseModel.queryForAll()}"
app:selectedItem="@={object.selectedItem}"/>
DatabaseModel.queryForAll 是一个查询数据库的静态方法,returns 是一个对象列表,然后将其提供给 BindingAdapter。 BindingAdapter 获取此列表,用索引更新它的每个项目并将其设置为微调器的适配器。
无论出于何种原因,"setSelectedItem" BindingAdapter 总是首先被调用。这是不可取的,因为我需要先初始化条目。如果它没有首先初始化,那么在第一次调用 setSelectedItem 时 spinner.getAdapter() 将为 null。这意味着之前保存的选择将不会被恢复。
Android 数据绑定中没有保证的执行顺序。因此,您应该合并依赖于多个属性的绑定适配器。在您的情况下,您需要合并 selectedItem 和条目的绑定适配器。
@BindingAdapter(value = {"selectedItem", "entries"}, requireAll = false)
public static void setSelectedItem(Spinner spinner, SpinnerItem spinnerItem,
List<? extends SpinnerItem> spinnerItems) {
// Set entries attribute when provided
if (spinnerItems != null) {
for (int i = 0; i < spinnerItems.size(); i++) {
spinnerItems.get(i).setIndex(i);
}
ArrayAdapter<? extends SpinnerItem> adapter =
new ArrayAdapter<>(spinner.getContext(), R.layout.spinner_item, spinnerItems);
spinner.setAdapter(adapter);
}
// set selectedItem attribute when provided
if (spinnerItem != null) {
if (spinner.getAdapter() == null) {
return;
}
// Other code omitted for simplicity
}
}
我需要了解数据绑定库如何确定其 BindingAdapter 的执行顺序。如果一个View有两个BindingAdapters,如果这个View有这两个BindingAdapters对应的属性,那么它如何确定先执行哪个adapter呢?我问是因为执行顺序对我来说很重要。
我有以下 BindingAdapter/s:
public class SpinnerBindingAdapter {
@BindingAdapter(value = {"entries"})
public static void setEntries(Spinner spinner, List<? extends SpinnerItem> spinnerItems) {
for (int i = 0; i < spinnerItems.size(); i++) {
spinnerItems.get(i).setIndex(i);
}
ArrayAdapter<? extends SpinnerItem> adapter =
new ArrayAdapter<>(spinner.getContext(), R.layout.spinner_item, spinnerItems);
spinner.setAdapter(adapter);
}
@InverseBindingAdapter(attribute = "selectedItem", event = "selectedItemAttrChanged")
public static Object getSelectedItem(Spinner spinner) {
Object selectedItem = spinner.getSelectedItem();
return selectedItem;
}
@BindingAdapter(value = {"selectedItem"})
public static void setSelectedItem(Spinner spinner, SpinnerItem spinnerItem) {
if (spinner.getAdapter() == null) {
return;
}
// Other code omitted for simplicity
}
@BindingAdapter(value = {"selectedItemAttrChanged"}, requireAll = false)
public static void setOnItemSelectedListener(Spinner spinner, final InverseBindingListener selectedItemChange) {
if (selectedItemChange == null) {
spinner.setOnItemSelectedListener(null);
} else {
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedItemChange.onChange();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}
}
下面是我如何填充微调器并设置选择:
<Spinner
android:id="@+id/spinner_system_activity_edit_tracker_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_horizontal"
app:entries="@{DatabaseModel.queryForAll()}"
app:selectedItem="@={object.selectedItem}"/>
DatabaseModel.queryForAll 是一个查询数据库的静态方法,returns 是一个对象列表,然后将其提供给 BindingAdapter。 BindingAdapter 获取此列表,用索引更新它的每个项目并将其设置为微调器的适配器。
无论出于何种原因,"setSelectedItem" BindingAdapter 总是首先被调用。这是不可取的,因为我需要先初始化条目。如果它没有首先初始化,那么在第一次调用 setSelectedItem 时 spinner.getAdapter() 将为 null。这意味着之前保存的选择将不会被恢复。
Android 数据绑定中没有保证的执行顺序。因此,您应该合并依赖于多个属性的绑定适配器。在您的情况下,您需要合并 selectedItem 和条目的绑定适配器。
@BindingAdapter(value = {"selectedItem", "entries"}, requireAll = false)
public static void setSelectedItem(Spinner spinner, SpinnerItem spinnerItem,
List<? extends SpinnerItem> spinnerItems) {
// Set entries attribute when provided
if (spinnerItems != null) {
for (int i = 0; i < spinnerItems.size(); i++) {
spinnerItems.get(i).setIndex(i);
}
ArrayAdapter<? extends SpinnerItem> adapter =
new ArrayAdapter<>(spinner.getContext(), R.layout.spinner_item, spinnerItems);
spinner.setAdapter(adapter);
}
// set selectedItem attribute when provided
if (spinnerItem != null) {
if (spinner.getAdapter() == null) {
return;
}
// Other code omitted for simplicity
}
}