BindingAdapter потерял связь с неизвестной причиной - PullRequest
0 голосов
/ 22 января 2019

Адаптер привязки потерял привязку к модели представления. Однако я понятия не имею, в чем причина. SpinnerTextView в коде - это текстовое представление, отображающее диалоговое окно с предупреждением для выбора значения из списка. При установке заголовка текст Textview будет установлен в качестве значения String. Привязка потеряна, так как текстовое представление не показывает новое значение, есть какое-либо решение?

Я установил несколько точек останова и обнаружил, что pickQuantity = "0" сработал, а также pickQuantity.value = values.value !! [index] также был запущен. Однако в BindingAdapter.kt только selectedQuantity = "0" запустил функцию setTitle. Поэтому мой 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" />

1 Ответ

0 голосов
/ 22 января 2019

Вы пропускаете вызов binding.setLifecycleOwner(this)

Устанавливает LifecycleOwner, который должен использоваться для наблюдения за изменениями LiveData в этой привязке.Если LiveData находится в одном из выражений привязки и не установлено LifecycleOwner, то LiveData не будет наблюдаться и обновления к нему не будут распространяться в пользовательский интерфейс.

Таклибо установите владельца жизненного цикла, либо используйте ObservableField, что лучше подходит.

Поскольку адаптеры работают по-разному в отношении обновлений данных, вы можете вместо этого распространять изменения в наборе данных адаптера и вызывать notifyDataSetChanged()или аналогичный для обновления привязок.

...