TootsieRockNRoll
TootsieRockNRoll

Reputation: 3288

Android - DataBinding with LiveData hold old values

I have DataBinding set and I use a ViewPager BindingAdapter to switch between screens:

BindingAdapter

@BindingAdapter("app:nextPageListener") fun nextPageListener(viewPager: ViewPager, next: Boolean?) {
  next ?: return
  if (next) viewPager.nextPage()
  else viewPager.previousPage()
} 

View Pager

<ViewPager
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:nextPageListener="@{viewModel.nextPageListener}"
    />

viewModel.nextPageListener

  private val _nextPageListener = MutableLiveData<Boolean>()
  val nextPageListener: LiveData<Boolean> get() = _nextPageListener

My issue is if I call _nextPageListener.postValue(true) and go to the next page and at some point leave the screen, when I come back the BindingAdapter is automatically called with true which makes the pager go to the next page. so basically on all the following times the pager is opened on the second screen.

Not sure if it has anything to do with lifecycle, but if it helps this is what I have

binding.lifecycleOwner = viewLifecycleOwner

Any idea how to fix this without some ugly workarounds?

Upvotes: 1

Views: 261

Answers (1)

Parth
Parth

Reputation: 791

Yes. you can use Event class.

open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

Now you can wrap your LiveData like this.

   private val _nextPageListener = MutableLiveData<Event<Boolean>>()
val nextPageListener: LiveData<Event<Boolean>> get() = _nextPageListener

and final step in your activity.

yourVm.nextPageListener.observe(this, Observer {
            it.getContentIfNotHandled()?.let {
                when (it) {

                  //get Your value here.
                }
            }
        })

Upvotes: 1

Related Questions