如何将spinner选中的值绑定到arraylist中的值

dzi*_*kan 11 android android-databinding

我设法结合微调器ArrayListobjects,现在我需要使它的是,当您选择微调的某些项目,它反映了ViewModel(setter方法被调用,并设置一个变量来选择什么指数是在转的值)

我设法让它以相反的方式工作,将值viewmodel反映到view(像这样如何使用带有Android微调器的DataBindingUtil?).

相关的xml

<data>
<variable
            name="spinnerList"
            type="com.example.root.proj.viewmodels.MonumentTypeVMList"/>
</data>


<Spinner
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            bind:spinnerbind="@{spinnerList.list}"
            bind:selection="@{spinnerList.selection}"
            ></Spinner>
Run Code Online (Sandbox Code Playgroud)

自定义绑定

@BindingAdapter("bind:selection")
public static void bindSelection(Spinner spinner, int position) {
    spinner.setSelection(position);
}
Run Code Online (Sandbox Code Playgroud)

Mak*_*aks 8

这个问题中提出了一个更简单(我认为)的解决方案,关键是使用SpinnerselectedItemPostion属性,该属性不在问题中包含的代码中,而是在它链接到的repo中: android:selectedItemPosition="@={model.position}"

我成功地使用了上述方法.这确实需要从位置到实际的微调器列表项进行映射,但无论如何我需要为我的用例执行此操作.

  • 为什么会给出未知属性警告 (3认同)
  • 因为AS还没有很好的数据绑定集成。这一点是一个相当困难的问题,因为AS需要验证布局文件后注释处理器,这当然很困难。 (2认同)

luc*_*992 7

与Ajit的答案几乎相同,但使用android:entries而不是绑定适配器.

                    <android.support.v7.widget.AppCompatSpinner
                    android:id="@+id/typeSpinner"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:entries="@{vehicle.types}"
                    android:selectedItemPosition="@={vehicle.selectedTypePosition}">
Run Code Online (Sandbox Code Playgroud)

然后是我的可观察课程

    @InverseBindingMethods({
        @InverseBindingMethod(type = AppCompatSpinner.class, attribute = "android:selectedItemPosition"),
    })
    class Vehicle extends BaseObservable {

    String[] types = getResources().getStringArray(R.array.service_types);

    String type = null;

    @Bindable
    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
        notifyPropertyChanged(BR.type);
    }

    Integer selectedTypePosition = 0;

    @Bindable
    public Integer getSelectedTypePosition() {
        return selectedTypePosition;
    }

    public void setSelectedTypePosition(Integer selectedTypePosition) {
        this.selectedTypePosition = selectedTypePosition;
        type = types[selectedTypePosition];

    }

    @BindingAdapter("selectedItemPositionAttrChanged")
    void setSelectedItemPositionListener(AppCompatSpinner view, final InverseBindingListener selectedItemPositionChange) {
        if (selectedItemPositionChange == null) {
            view.setOnItemSelectedListener(null);
        } else {
            view.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    selectedItemPositionChange.onChange();
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {

                }
            });
        }
    }

    @InverseBindingAdapter(attribute = "selectedItemPosition")
    Integer getSelectedItemPosition(AppCompatSpinner spinner) {
        return spinner.getSelectedItemPosition();
    }

}
Run Code Online (Sandbox Code Playgroud)

从我的实现简化了这一点,并没有测试它.应该工作......

  • 我收到错误:错误:(43,10)错误:无效元素上的@BindingAdapter:setSelectedItemPositionListener(android.support.v7.widget.AppCompatSpinner,android.databinding.InverseBindingListener) (2认同)

Aji*_*ngh 3

您可以使用反向绑定来实现此目的。您将需要定义两个自定义绑定。

  1. 从微调器获取最新值并在模型中设置。
  2. 在微调器中选择新值时触发事件。

要从微调器中获取选定的值,请将此方法添加到您的自定义绑定中。

@InverseBindingAdapter(attribute = "selection", event = "selectionAttrChanged")
  public static String getSelectedValue(AdapterView view) {
    return (String) view.getSelectedItem();
  }
Run Code Online (Sandbox Code Playgroud)

要在微调器中选择新值时触发事件,请使用

@BindingAdapter(value = {"selection", "selectionAttrChanged", "adapter"}, requireAll = false)
  public static void setAdapter(AdapterView view, String newSelection, final InverseBindingListener bindingListener, ArrayAdapter adapter) {
    view.setAdapter(adapter);
    view.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
      @Override
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        bindingListener.onChange();
      }

      @Override
      public void onNothingSelected(AdapterView<?> parent) {
        //Nothing
      }
    });
    if (newSelection != null) {
      int pos = ((ArrayAdapter) view.getAdapter()).getPosition(newSelection);
      view.setSelection(pos);
    }
  }
Run Code Online (Sandbox Code Playgroud)

现在在您的布局文件中只需使用上面的绑定即可:

<Spinner
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:adapter="@{AdapterFactory.getAdapter(context)}"
      app:selection="@={model.selectedValue}"/>
Run Code Online (Sandbox Code Playgroud)