私はSpinnerで双方向バインディングを設定しようとしばらくしてきました。@InverseBindingAdapter/AttrChangedを使用したAndroid Spinnerの双方向バインディングは機能しません
ウェブ上やここではスタックオーバーフローに関する多くの例がありますが、どれも私のためには機能しません。
それはちょうど国のスピナーですが、私はこの方法でそれのための国のアダプタを定義しました:
@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
メソッドが呼び出されることはありません。
私も(他の例以下)このバリアントを試してみた:これはと呼ばれるが、newTextAttrChanged
は常にnullです
@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);
}
。
レイアウト、部品結合:
<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
です。
アンドロイドのGradleプラグイン:
classpath 'com.android.tools.build:gradle:2.2.1'
ツールのバージョン:
buildToolsVersion "24.0.2"
そしてもちろん、データバインディングが有効になっている:
dataBinding {
enabled = true
}
newTextAttrChanged
は常にnullである理由/ BindingAdapterは決してありませんコールド?私は間違って何をしていますか?
'アプリでなければなりません:それは'でなければなりませんのでselectedCountryは= "@ {customer.countryは}" 'あなたは、' = '双方向のバインディングを欠落していませんapp:selectedCountry = "@ = {customer.country}" '...? – yennsarah
イエスは正しいです!私は何とかそれを見落としました... '@ = {'と '@ {'?私は '= '形式を使用するはずですが、後者はいつも使っていますか? –
私は答えを投稿します。 ;) – yennsarah