title: How to get a RecyclerView Item to update itself from a LiveData value in it's binding object using BindingAdapter?
body: <p>I have a recyclerview.widget.ListAdapter to display some cards in a grid. When I click on a card, it comes to the front of the grid, flips, and when you see the front, you are supposed to be able to like it. I have an ImageView on the corner of the front of the card, that is supposed to toggle between liking or not, displaying a different drawable that I have already defined.</p>
  
  <p>My ViewHolder looks like this:</p>
  
  <pre><code>class GameCardViewHolder(private val binding : ItemGameCardBinding) :
          RecyclerView.ViewHolder(binding.root){
  
      companion object {
          fun from(parent: ViewGroup): GameCardViewHolder {
              val layoutInflater = LayoutInflater.from(parent.context)
              val binding = ItemGameCardBinding.inflate(layoutInflater, parent, false)
              return GameCardViewHolder(binding)
          }
          ...
      }
  
      fun bind(productCard: ProductCard, listener: OnClickListener){
          binding.productCard = productCard
          binding.executePendingBindings()
          ...  
      }
  }
  </code></pre>
  
  <p>My item_game_card.xml looks like this:</p>
  
  <pre><code>&lt;layout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"&gt;
  
      &lt;data&gt;
          &lt;variable
              name="productCard"
              type="company.app.model.ProductCard" /&gt;
      &lt;/data&gt;
      &lt;androidx.constraintlayout.widget.ConstraintLayout&gt;
      ...
          &lt;ImageView
              android:id="@+id/gameItemLikeImageView"
              android:layout_width="0dp"
              android:layout_height="0dp"
              ...
              app:imageDrawable="@{productCard.liked}"
              android:onClick="@{() -&gt; productCard.toggleLike()}"
          /&gt;
      &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;
  &lt;/layout&gt;
  </code></pre>
  
  <p>My BindingAdapters.kt:</p>
  
  <pre><code>@BindingAdapter("imageDrawable")
  fun bindImageDrawable(imgView: ImageView, boolean: LiveData&lt;Boolean&gt;?) {
      Timber.d("Binding liked: $boolean")
      when(boolean?.value){
          true -&gt; imgView.setImageResource(R.drawable.ic_card_like)
          false -&gt;  imgView.setImageResource(R.drawable.ic_card_dislike)
      }
  }
  </code></pre>
  
  <p>And my ProductCard.kt:</p>
  
  <pre><code>data class ProductCard(
      val position: Int,
      val product: Product
  ){
      ...
      private val _liked = MutableLiveData(false)
      val liked : LiveData&lt;Boolean&gt;
          get() = _liked
  
      fun toggleLikeProduct(){
          Timber.d("Toggle like before: ${_liked.value}")
          val oldValue = _liked.value!!
          _liked.value = !oldValue
          Timber.d("Toggle like after: ${_liked.value}")
      }
  }
  </code></pre>
  
  <p>When I click on the ImageView, the console prints out the before and after values every time correctly, so I know the value of the <code>liked</code> LiveData is actually changing, but the View is not updating accordingly, that is because the binding adapter is only being called once (in the <code>binding.executePendingBindings()</code> I guess, when the RecyclerView binds the ViewHolder, and not every single time the LiveData changes).</p>
  
  <p><strong>I want the BindingAdapter code to be run every time the <code>liked</code> LiveData changes.</strong></p>
  
  <p>When I do this with ViewModel and Fragment layout, every time a LiveData changes in the ViewModel, the View changes because the xml is referencing that LiveData, but I don't know why, when it comes to ProductCard and recyclerview item layout, even if the xml is referencing that LiveData, the View doesn't change, the xml is not actually binding to the LiveData, which is the whole point of having LiveData.</p>
  
  <p>I have already acheived this behaviour with a very brute, unelegant sort of way, setting an onClickListener on that view, and forcing it to change it's resource drawable, on the OnBindViewHolder like this: </p>
  
  <pre><code>fun bind(productCard: ProductCard, listener: OnClickListener){
      binding.productCard = productCard
      binding.executePendingBindings()
      binding.gameItemLikeImageView.setOnClickListener {
          it?.let {
              val card = binding.productCard
              Timber.d("Tried changing liked status: ${card!!.liked}")
              val old = card.liked
              card.liked = !old
              binding.productCard = card
              val card2 = binding.productCard
              Timber.d("Tried changing liked status: ${card2!!.liked}")
              if (!old){
                  it.setBackgroundResource(R.drawable.ic_card_like)
              }
              else {
                  it.setBackgroundResource(R.drawable.ic_card_dislike)
              }
          }
      }
      ...
  }
  </code></pre>
  
  <p>But I would really like that the behaviour of each card be controlled by the state of the ProductCard object that it is bind to.</p>
  
  <p>I have also tried to force call <code>binding.executePendingBindings()</code> every time I click, but also didn't work.</p>
  
  <p>How can I make the item_game_card.xml to observe the changes in the LiveData?</p>