Problem:
I have activity which have shared button , shared title,shared process bar and container in the middle of the screen where fragments replaced.
so i have viewmodel of the acitivty - ActivityViewModel and inside of it there is observables of:
val mNavigationToMainActivity = CompletableSubject.create()
val mNavigationToUsername = PublishSubject.create<Any>()
val mNavigationToPassword = PublishSubject.create<Any>()
val mNavigationToChangePassword = PublishSubject.create<LoginItem>()
val mProcessBar = PublishSubject.create<Int>()
val mContinueButtonEnabled = BehaviorSubject.createDefault(false)
val mContinueClick = PublishSubject.create<Any>()
val mChangeTitleSubject = BehaviorSubject.createDefault(false)
val mLoadingIndicatorSubject = BehaviorSubject.createDefault(false)
and there is shared viewmodel between the fragment which call FragmentViewModel. all of the fragment uses the same viewmodel
now the problem is how the viewmodel of the fragment can access the viewmodel of the activity? for example when user click login button so i want the fragmentviewmodel have the access to the loader of the activity and then to navigatetonext screen.
or for example to enabled the button when the input is valied
so this is what i did to communicate between these:
fun <T> PublishSubject<T>.bind(subject: PublishSubject<T>): Disposable {
return subscribe({ subject.onNext(it) }, { throwable -> subject.onError(throwable) })
}
fun <T> BehaviorSubject<T>.bind(subject: BehaviorSubject<T>): Disposable {
return subscribe({ subject.onNext(it) }, { throwable -> subject.onError(throwable) })
}
fun CompletableSubject.bind(subject: CompletableSubject): Disposable {
return subscribe({ subject.onComplete() }, { throwable -> subject.onError(throwable) })
}
i let to viewmodel of the fragment to extend the viewmodel of the acitvity kinda of base viewmodel
so this is the viewmodel of acitvity
open class IntroViewModel : BaseViewModel() {
val mNavigationToMainActivity = CompletableSubject.create()
val mNavigationToUsername = PublishSubject.create<Any>()
val mNavigationToPassword = PublishSubject.create<Any>()
val mNavigationToChangePassword = PublishSubject.create<LoginItem>()
val mProcessBar = PublishSubject.create<Int>()
val mContinueButtonEnabled = BehaviorSubject.createDefault(false)
val mContinueClick = PublishSubject.create<Any>()
val mChangeTitleSubject = BehaviorSubject.createDefault(false)
fun bind(introViewModel: IntroViewModel){
mNavigationToUsername.bind(introViewModel.mNavigationToUsername).addDisposable()
mNavigationToPassword.bind(introViewModel.mNavigationToPassword).addDisposable()
mNavigationToChangePassword.bind(introViewModel.mNavigationToChangePassword).addDisposable()
mNavigationToMainActivity.bind(introViewModel.mNavigationToMainActivity).addDisposable()
mProcessBar.bind(introViewModel.mProcessBar).addDisposable()
mContinueButtonEnabled.bind(introViewModel.mContinueButtonEnabled).addDisposable()
}
fun continueClicked() {
mContinueClick.onNext(Any())
}
} and this is of the fragment
class ChangePasswordViewModel(private val userRepository: UserRepository)
: IntroViewModel() {
and inside of each fragment i binded the viewmodel of the activity to viewmodel of the fragment
viewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(ChangePasswordViewModel::class.java)
viewModel.start(2,arguments?.getParcelable(LoginItem::class.simpleName))
ViewModelProviders.of(activity!!, viewModelFactory).get(IntroViewModel::class.java).apply {
viewModel.bind(this)
}
its nasty and i dont really like it. can u please help me with it??