3

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??

AbraKdabra
  • 31
  • 1
  • One View (Fragment/Activity) can bind to different ViewModel, it's not a one-to-one relationship. So you could refactor to have a ViewModel for the navigation (or Coordinator). The activity would observe the changes to swap fragments, and each fragment would "tell the ViewModel" that the button 'navigate to XYZ' was clicked – NSimon Jun 27 '18 at 15:12
  • its kinda what i did.. – AbraKdabra Jun 27 '18 at 17:21

0 Answers0