Двухсторонний прядильщик переплета в Android с Viewmodel и Livedata - PullRequest
0 голосов
/ 11 июля 2020

Я привязал, чтобы применить двухсторонний подход привязки в счетчике и получить выбранный элемент в модели просмотра. Но после выбора элемента из выпадающего списка выполняется бесконечное l oop. Возможно, что-то не так с адаптером InverseBinding. Я не знаю, что не так. Есть ли лучший способ назначить список счетчику (пользовательский адаптер) из модели просмотра и вернуть выбранную позицию элемента.

ViewModel

val projects = repo.getData()
private val _selectedProject = MediatorLiveData<Project>()
var selectedProject: LiveData<Project>
    get() = _selectedProject

счетчик в xml

<androidx.appcompat.widget.AppCompatSpinner
        android:id="@+id/spnrToCurrecncy"
        android:layout_width="wrap_content"
        app:projects="@{viewmodel.projectsnew}"
        app:selectedProject="@={viewmodel.selectedProject}"
        />

BindingAdapter и InverseBindingAdapter

@BindingAdapter(value = ["projects", "selectedProject", "selectedProjectAttrChanged"], requireAll = false)
fun setProjects(spinner: Spinner, projects: List<Project>?, selectedProject: Project?, listener: InverseBindingListener) {
   // Log.d("tag","selected proj="+selectedProject+"...projects::"+projects)
    if (projects == null) return
    spinner.adapter = CustomAapter(spinner.context, R.layout.country_custom_spinner, projects)
    setCurrentSelection(spinner, selectedProject)
    setSpinnerListener(spinner, listener)
}
private fun setSpinnerListener(spinner: Spinner, listener: InverseBindingListener) {
    spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) = listener.onChange()
        override fun onNothingSelected(adapterView: AdapterView<*>) = listener.onChange()
    }
}

private fun setCurrentSelection(spinner: Spinner, selectedItem: Project?): Boolean {
    if (selectedItem == null) {
        return false
    }
    for (index in 0 until spinner.adapter.count) {
        val currentItem = spinner.getItemAtPosition(index) as Project
        if (currentItem.name == selectedItem.name) {
            spinner.setSelection(index)
            return true
        }
    }
    return false
}

@InverseBindingAdapter(attribute = "selectedProject")
fun getSelectedProject(spinner: Spinner): Project {
    return spinner.selectedItem as Project
}
...