In this case, I have two fragments in BottomNavigationView: Home and Dictionary.
Inside of DictionaryFragment I show BottomSheetFragment with EditText and Button. When the user clicks to the button, the following code executing:
if (name.isNotEmpty()) {
sharedViewModel.setNewPackName(name)
}
where name is text from EditText and SharedViewModel:
val currentPackName = MutableLiveData<String>()
fun setNewPackName(packName: String) {
currentPackName.postValue(packName)
}
Inside of DictionaryFragment I have this code:
override fun setObservers() {
sharedViewModel.currentPackName.observe { newPackName ->
Timber.tag("newName").d("setObservers(): $newPackName")
pack_name.text = newPackName
}
}
But when I moving DictionaryFragment -> HomeFragment -> DictionaryFragment, I see duplicate of "setObservers(): $newPackName" string in my Logcat. Repeating these steps (D-> H-> D) I see the same situation: the next line is printed
BaseViewModel
open class BaseViewModel : ViewModel() {
val compositeDisposable by lazy { CompositeDisposable() }
protected fun <T : Any> Observable<T>.compositeSubscribe(
onNext: (T) -> Unit = {},
onError: (Throwable) -> Unit = {},
onComplete: () -> Unit = {}
) = composite(
subscribe(onNext, onError, incomplete)
)
private fun composite(disposable: Disposable) {
compositeDisposable.add(disposable)
}
override fun onCleared() {
compositeDisposable.dispose()
super.onCleared()
}
}
To be honest, I don’t know what could be the problem. I also use Navigation architecture Component where the visual state of the fragments is preserved, but the life cycle methods are called again.
EDIT: This problem occurs if I have viewModel.smth.observe()
and when I switch between fragments (for example, D -> H -> D)
EDIT_2: In my BaseFragment I have the following extension function:
protected inline fun <T> LiveData<T>.observe(crossinline codeBlock: (T) -> Unit) {
observe(this@BaseFragment, Observer { it -> it?.let { codeBlock(it) } })
}
I've tried to change it to:
protected inline fun <T> LiveData<T>.observe(crossinline codeBlock: (T) -> Unit) {
val observer = Observer<T> { it -> it?.let { codeBlock(it) } }
removeObserver(observer)
observe(this@BaseFragment, observer)
}
but the problem is still here.
Please, help me to solve this problem.