BindingAdapter 因未知原因丢失了绑定

BindingAdapter has lost binding with unknown reason

绑定适配器丢失了与视图模型的绑定。但是我不知道是什么原因。代码中的 SpinnerTextView 是一个文本视图,针对列表中的 selecting 值弹出一个警告对话框。设置标题会将文本视图的文本设置为字符串值。绑定丢失导致textview不显示新值,请问有什么解决办法吗?

我已经设置了一些断点,我发现 pickedQuantity = "0" 有效,而且 pickedQuantity.value = quantities.value!![index] 也是 运行。但是,在 BindingAdapter.kt 中只有 pickedQuantity="0" 触发了 setTitle 函数。 因此,当我 select value.

时,我的 TextView 将始终显示 0 但不会更改

BindingAdapter.kt

@BindingAdapter("spinnerTitle")
fun<T> SpinnerTextView<T>.setTitle(str: String) {
    title = str
}

@BindingAdapter("spinnerAlertTitle")
fun<T> SpinnerTextView<T>.setAlertTitle(str: String) {
    alertTitle = str
}

@BindingAdapter("spinnerItems")
fun<T> SpinnerTextView<T>.setItems(list: List<T>) {
    items = list
}

@BindingAdapter("spinnerItemHandler")
fun<T> SpinnerTextView<T>.setHandler(handler: (Int) -> Unit) {
    valueChanged = handler
}

TicketTypeViewModel.kt

class TicketTypeViewModel : BaseViewModel() {
    val ticketId = MutableLiveData<Int>()
    val ticketName = MutableLiveData<String>()
    val ticketPrice = MutableLiveData<String>()
    val pickedQuantity = MutableLiveData<String>()
    val quantities = MutableLiveData<List<String>>()
    val spinnerTitle = MutableLiveData<String>()
    val spinnerHandler = MutableLiveData<(Int) -> Unit>()

    fun bind(ticket: TicketType, onClick: (Int) -> Unit) {
        ticketId.value = ticket.ticketTypeId
        ticketName.value = ticket.ticketTypeName
        ticketPrice.value = "$"  + ticket.price
        pickedQuantity.value = "0"
        spinnerTitle.value = ""
        val temp = mutableListOf<String>()
        for (i in 0 until ticket.quota) {
            temp.add(i.toString())
        }
        quantities.value = temp.toList()
        spinnerHandler.value = { index ->
            pickedQuantity.value = quantities.value!![index]
            onClick(index)
        }
    }
}

TicketTypeAdapter.kt

class TicketTypeAdapter(val onClick: (Int) -> Unit): RecyclerView.Adapter<TicketTypeAdapter.ViewHolder>() {

    private var ticketList: MutableList<TicketType> = mutableListOf()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TicketTypeAdapter.ViewHolder {
        val binding: EventTicketTypeListItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.event_ticket_type_list_item, parent, false)
        return ViewHolder(binding, onClick)
    }

    override fun onBindViewHolder(holder: TicketTypeAdapter.ViewHolder, position: Int) {
        holder.bind(ticketList[position])
    }

    override fun getItemCount(): Int {
        return ticketList.size
    }

    fun refreshTicketList(ticketList: List<TicketType>){
        this.ticketList.clear()
        this.ticketList.addAll(ticketList)
        notifyDataSetChanged()
    }

    class ViewHolder(private val binding: EventTicketTypeListItemBinding, val onClick: (Int) -> Unit): RecyclerView.ViewHolder(binding.root){
        private val viewModel = TicketTypeViewModel()

        fun bind(ticket: TicketType){
            viewModel.bind(ticket, onClick)
            binding.ticketType = viewModel
        }
    }
}

在.xml

    <com.cityline.component.SpinnerTextView
        android:id="@+id/spinner_quantity"
        spinnerAlertTitle="@{ticketType.spinnerTitle}"
        spinnerItemHandler="@{ticketType.spinnerHandler}"
        spinnerItems="@{ticketType.quantities}"
        spinnerTitle="@{ticketType.pickedQuantity}"
        android:layout_width="20dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="20dp"
        android:background="@drawable/edit_text_bg_bottom_line"
        android:gravity="center"
        android:textSize="16sp" />

您未接来电 binding.setLifecycleOwner(this)

Sets the LifecycleOwner that should be used for observing changes of LiveData in this binding. If a LiveData is in one of the binding expressions and no LifecycleOwner is set, the LiveData will not be observed and updates to it will not be propagated to the UI.

因此要么设置生命周期所有者,要么使用 ObservableField,这更合适。

由于适配器在数据更新方面的工作方式不同,您可能希望将更改传播到适配器数据集并调用 notifyDataSetChanged() 或类似的方法来更新绑定。