Android spinner Связывание данных с использованием XML и отображение выбранных значений

Я использую новое привязку данных для Android и отлично работает. Я могу выполнить привязку данных с помощью EditText, TextView, Radio и checkbox. Теперь я не могу выполнить привязку данных в spinner.

Найдена некоторая подсказка в следующей ссылке: привязка данных spinner для Android с XML-макетом

Но, все еще не в состоянии найти решение. Также необходимо выполнить двухстороннюю привязку данных. Должно отражать выбранное значение данных счетчика.

Может ли кто-нибудь показать мне пример?

Вот мой xml код:

 <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/tools" xmlns:card_view="http://schemas.android.com/apk/res-auto"> <data> <import type="android.view.View" /> <variable name="viewModel" type="com.ViewModels.model" /> </data> <Spinner android:id="@+id/assessmemt_spinner" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_margin="@dimen/carview_margin" android:layout_toRightOf="@+id/text_bp" android:drawSelectorOnTop="true" android:spinnerMode="dropdown" android:visibility="@{viewModel.type.equals(@string/spinner_type)? View.VISIBLE : View.GONE}" /> </layout> 

Модель:

  public class AssessmentGetViewModel { private String valueWidth; private ArrayList<String> values; private String type; public String getValueWidth() { return this.valueWidth; } public void setValueWidth(String valueWidth) { this.valueWidth = valueWidth; } public ArrayList<String> getvalues() { return this.values; } public void setvalues(ArrayList<String> values) { this.values = values; } public String gettype() { return this.type; } public void settype(String type) { this.type = type; } } 

Solutions Collecting From Web of "Android spinner Связывание данных с использованием XML и отображение выбранных значений"

Я нашел что-то полезное, но оно не находится в официальной документации для двусторонней привязки данных.

1. '@ =' использование для двусторонней передачи данных

2. Для достижения двухсторонней привязки данных требуется «BindingAdapter» и «InverseBindingAdapter» для аннотации.

Для первого элемента многие блогеры показали использование «@ =» для двусторонней привязки данных. https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/

Для второго пункта, как @George Mound ответил здесь ( Редактировать текстовый курсор сбрасывается налево, когда текст по умолчанию edittext является значением float ), EditText может быть привязан в двух направлениях, используя аннотацию BindingAdapter и InverseBindingAdapter.

Следуя инструкциям, вы можете создать свой метод двусторонней привязки для spinner.

Во-первых, создайте ViewModel

 public class ViewModel { private ObservableField<String> text; public ViewModel() { text = new ObservableField<>(); } public ObservableField<String> getText() { return text; } } 

Во-вторых, добавьте его в свой xml.

  <android.support.v7.widget.AppCompatSpinner android:layout_width="wrap_content" android:layout_height="wrap_content" android:entries="@array/days" bind:selectedValue="@={viewModel.text}"/> 

В-третьих, добавьте ваш bindingUtil

 public class SpinnerBindingUtil { @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, String newSelectedValue, final InverseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { newTextAttrChanged.onChange(); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } } @InverseBindingAdapter(attribute = "bind:selectedValue", event = "bind:selectedValueAttrChanged") public static String captureSelectedValue(AppCompatSpinner pAppCompatSpinner) { return (String) pAppCompatSpinner.getSelectedItem(); } } 

Как ваша пила, она использовала «selectedValue» как переменную для выбранного по умолчанию значения, но что такое «selectedValueAttrChanged» ?? Я думал, что это сложно (я не знаю, почему он не является нулевым, когда он вызывается), его не нужно добавлять в xml, поскольку это только обратный вызов для прослушивания элемента, измененного в счетчике. Затем вы устанавливаете onItemSelectedListener и устанавливаете его для вызова функции InverseBindingListener onchange () (Документация и пример здесь: https://developer.android.com/reference/android/databinding/InverseBindingAdapter.html ) . Событием по умолчанию будет «android: TextAttrChanged ", и если вы хотите иметь собственный двусторонний bind inversebind, вам нужно использовать атрибут с суффиксом" AttrChanged "

Значением по умолчанию для события является имя атрибута, сшитое с помощью «AttrChanged». В приведенном выше примере значением по умолчанию было бы android: textAttrChanged, даже если оно не было предоставлено.

Наконец, в вашей деятельности и вашем файле string.xml

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding lBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false); mViewModel = new ViewModel(); mViewModel.getText().set("Wednesday"); lBinding.setViewModel(mViewModel); lBinding.setHandler(new Handler()); setContentView(lBinding.getRoot()); } 

string.xml

 <array name="days"> <item name="Mon">Monday</item> <item name="Tue">Tuesday</item> <item name="Wed">Wednesday</item> </array> 

Когда вы запустите код, он покажет «Среда» как значение по умолчанию для счетчика. Надеюсь, это поможет многим людям

@ Long Ranger Мне очень нравится ваш ответ, но я думаю, что нам нужно что-то сделать, чтобы сломать цикл. Например:

 @BindingAdapter(value = {"bind:selectedValue", "bind:selectedValueAttrChanged"}, requireAll = false) public static void bindSpinnerData(AppCompatSpinner pAppCompatSpinner, final String newSelectedValue, final InverseBindingListener newTextAttrChanged) { pAppCompatSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if(newSelectedValue != null && newSelectedValue.equlas(parent.getSelectedItem()){ return; } newTextAttrChanged.onChange(); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); if (newSelectedValue != null) { int pos = ((ArrayAdapter<String>) pAppCompatSpinner.getAdapter()).getPosition(newSelectedValue); pAppCompatSpinner.setSelection(pos, true); } }