Android Simple Two Way Data Binging With Spinner Without BindingAdapter (Kotlin)

I have a List<Category> which loaded into Spinner using ArrayAdapter. I wanted to use Data Binding to get and set the value of the spinner.

If you are loading Enum into Spinner, you should read this guide and use @InverseMethod.

A more complete and complex solution would usually involve BindingAdapter or InverseBindingAdapter, but I wanted something simpler.

The simplest solution is to bind selectedItemPosition position.

class CategoryViewModel() : ViewModel() {  val categoryIdItemPosition = MutableLiveData<Int>()}
<Spinner
    android:id="@+id/categorySpinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:selectedItemPosition="@={viewModel.categoryIdItemPosition}"
/>
val position = viewModel.categoryIdItemPosition.valueviewModel.categoryIdItemPosition.value = position + 1

Though I can set/get position, but I can't actually get the actual selected item's ID or set selected item by ID. I can write a convenient property to do this.

class CategoryViewModel() : ViewModel() {  val categoryIdItemPosition = MutableLiveData<Int>()  var categoryIdValue      get() =          categoryIdItemPosition.value?.let {               categoryList?.get(it)?.id          }      set(value) {          val position = categoryList?.indexOfFirst {              it.id == value          } ?: -1          if (position != -1) {              categoryIdItemPosition.value = position          }      }    var categoryList List<Cateogory>? = null}

NOTE: when you assign List<Category> to spinner's adapter, update viewModel.categoryList as well.

I can also write a convenient property to get selected item.

class CategoryViewModel() : ViewModel() {  val categoryIdItemPosition = MutableLiveData<Int>()  var categoryIdValue      get() =          categoryIdItemPosition.value?.let {               categoryList?.get(it)?.id          }      set(value) {          val position = categoryList?.indexOfFirst {              it.id == value          } ?: -1          if (position != -1) {              categoryIdItemPosition.value = position + 1          }      }    val categoryIdItem    get() =        categoryIdItemPosition.value?.let {             categoryList?.get(it)        }  var categoryList List<Cateogory>? = null}

NOTE: if you are not using ViewModel, you can access List<Cateogory> using Spinner and Adapter methods.

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.