17

データ バインディング ライブラリが BindingAdapter の実行順序を決定する方法を理解する必要があります。ビューに 2 つの BindingAdapter があり、それらの BindingAdapter に対応する両方の属性がビューにある場合、どちらのアダプターが最初に実行されるかをどのように判断しますか? 私の場合は実行順序が重要なのでお願いします。

次の 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 は、データベースに対してクエリを実行し、BindingAdapter に渡されるオブジェクトのリストを返す静的メソッドです。BindingAdapter はこのリストを受け取り、その各項目をインデックスで更新し、スピナーのアダプターとして設定します。

何らかの理由で、「setSelectedItem」BindingAdapter が常に最初に呼び出されます。最初にエントリを初期化する必要があるため、これは望ましくありません。最初に初期化されていない場合、setSelectedItem が最初に呼び出されたときに spinner.getAdapter() は null になります。つまり、以前に保存された選択は復元されません。

4

1 に答える 1