Вот код, который я использовал для привязки Spinner в XML с BindingAdapter. XML:
<data>
<import type="java.util.List" />
<variable
name="stateData"
type="List<com.xyz.model.remote.result.State>" />
</data>
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/spState"
android:layout_width="0dp"
android:layout_height="@dimen/_30sdp"
android:layout_marginTop="@dimen/_5sdp"
android:backgroundTint="@color/textColor"
android:minWidth="0dp"
android:minHeight="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/ivState"
app:layout_constraintTop_toTopOf="parent"
bind:listitem="@layout/item_view"
bind:onStateSelected="@{viewModel.onStateSelectedListener}"
bind:selectedStateId="@={viewModel.signUpFormFields.stateId}"
bind:states="@{stateData}" />
BindingAdapter.kt
@BindingAdapter(
value = ["states", "defaultSelectedId", "onStateSelected", "selectedStateId", "selectedStateIdAttrChanged"],
requireAll = false
)
@JvmStatic
fun bindStateSpinnerEntries(
spinner: AppCompatSpinner,
stateList: List<State>? = arrayListOf(),
selectedId: Int? = -1,
itemSelectedListener: AdapterView.OnItemSelectedListener,
newId: Int?,
idAttrChanged: InverseBindingListener
) {
if (stateList == null) {
val tempList = arrayListOf<State>()
tempList.add(0, State(-1, -1, spinner.context.getString(R.string.login_state_hint)))
spinner.adapter = StateSpAdapter(
spinner.context,
R.layout.item_dropdown,
R.layout.item_view,
tempList
)
spinner.setSelection(0)
return
}
(stateList as ArrayList).add(
0,
State(-1, -1, spinner.context.getString(R.string.login_state_hint))
)
spinner.adapter = StateSpAdapter(
spinner.context,
R.layout.item_dropdown,
R.layout.item_view,
stateList
)
var selectedPos = 0
if (selectedId != null) {
for (state in stateList) {
if (state.id == selectedId) {
break
}
selectedPos++
}
}
if (selectedPos < stateList.size) spinner.setSelection(selectedPos) else spinner.setSelection(
0
)
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>,
view: View,
position: Int,
id: Long
) {
idAttrChanged.onChange()
itemSelectedListener.onItemSelected(parent, view, position, id)
}
override fun onNothingSelected(parent: AdapterView<*>) {}
}
}
@InverseBindingAdapter(
attribute = "selectedStateId",
event = "selectedStateIdAttrChanged"
)
@JvmStatic
fun captureSelectedStateId(powerSpinnerView: AppCompatSpinner): Int {
return (powerSpinnerView.selectedItem as State).id
}
ViewModel
Наблюдать за слушателем изменения состояния.
val onStateSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
stateReceived.postValue(true)
errState.postValue(false)
}
}
Во фрагменте наблюдать и связывать список состояний.
mFragmentBinding.stateData = stateList