Search code examples
androidkotlinandroid-livedataswiperefreshlayout

How to apply LiveData to xxxFragment.class instead of XML


How to apply live data isRefreshing to swiperefreshLayout.isRefresh?

Code in xxxViewModel.class:

var isRefreshing = MutableLiveData<Boolean>()

fun refresh() {
    viewModelScope.launch(Dispatchers.Main) {
        isRefreshing.value = true

        withContext(Dispatchers.IO) {
            fun doInBackground() // takes a long time
        }
   
        isRefreshing.value = false
    }
}

Code in xxxFragment.class:

binding.swiperefreshLayout.setOnRefreshListener {
    xxxViewModel.refresh()
}

// error here, require Boolean, found MutableLiveData<Boolean>
binding.swiperefreshLayout.isRefreshing = xxxViewModel.isRefreshing 

Usually I apply the live data to XML like below, but I cannot find swiperefreshlayout.isRefreshing in XML.

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swiperefresh_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        isFreshing = "@{xxxViewModel.isRefreshing}">

Solution

  • What you did is to get the current value of the liveData "isRefreshing". (also you need to add .value to get the underlying value associated with the liveData)

    binding.swiperefreshLayout.isRefreshing = xxxViewModel.isRefreshing.value?:false
    

    Instead, you should observe the Live Data for changes after initializing your view model.

     xxxViewModel.apply {
    
        
        isRefreshing.observe(viewLifecycleOwner){
             binding.swiperefreshLayout.isRefreshing = it
        }
    
        //... observe the rest of your LiveData
    } 
    

    EDIT:

    you can create a function like the following

    private inline fun <T> doObserve(ld: LiveData<T>, crossinline callback: (T) -> Unit) {
        ld.observe(viewLifecycleOwner, { callback.invoke(it) })
    }
    

    then just call that instead

     xxxViewModel.apply {
    
       doObserve( isRefreshing){
             binding.swiperefreshLayout.isRefreshing = it
        }
    
        //... observe the rest of your LiveData
    }