hasActiveObservers и hasObservers false в общем ViewModel - PullRequest
1 голос
/ 15 января 2020

Я пытаюсь установить связь между двумя фрагментами и ViewPager2 с помощью общего ViewModel следующим образом:

SharedViewModel

val viewPagerFragment = MutableLiveData<Int>()

init {
    viewPagerFragment.value = -1
}

fun displayedFragment(fragmentIndex: Int){
    viewPagerFragment.value = fragmentIndex
}

fun doSomethingForFragmentA(){
    //
}

fun doSomethingForFragmentB(){
    //
}

Фрагмент A

override fun onResume() {
    super.onResume()
    sharedViewModel.displayedFragment(0)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
}

Фрагмент B

override fun onResume() {
    super.onResume()
    sharedViewModel.displayedFragment(1)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
}

ViewPager2

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    sharedViewModel.viewPagerFragment.observe(this, Observer {
        when (it) {
            0 -> sharedViewModel.doSomethingForFragmentA(it)
            1 -> sharedViewModel.doSomethingForFragmentB(it)
        }
    })

}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
}

Во время первого вызова onActivityCreated в ViewPager2 LiveData Observer реагирует правильно. Тем не менее, оба hasActiveObservers и hasObservers показывают false в общей ViewModel. Когда я переключаюсь с FragmentA на FragmentB, FragmentB корректно обновляет LiveData в onResume (). На этот раз Observer в ViewPager2 не реагирует на изменение, а hasActiveObservers и hasObservers по-прежнему ложны.

Стоит отметить, что если я переместу наблюдателей из ViewPager в FragmentA и FragmentB, все будет работать нормально.

Единственное, что приходит на ум, - это то, что ViewPager имеет другую хост-активность.

1 Ответ

0 голосов
/ 16 января 2020

Мне удалось решить проблему с помощью каналов. Не совсем то, что я хотел, но это работает. Я все еще надеюсь, что есть решение оригинального вопроса.

AppContainer

class AppContainer {
    val currentViewPagerFragmentChannel = Channel<Int>()
}

BaseApplication

class BaseApplication : Application(){

    val appContainer = AppContainer()
}

FragmentA

override fun onResume() {
    super.onResume()
    val app = activity?.application as BaseApplication


    GlobalScope.launch {
        app.appContainer.currentViewPagerFragmentChannel.send(0)
    }
}

FragmentB

override fun onResume() {
    super.onResume()
    val app = activity?.application as BaseApplication

    // Send an Integer
    GlobalScope.launch {
        app.appContainer.currentViewPagerFragmentChannel.send(1)
    }
}

ViewPager

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    launch {
        val app = activity?.application as BaseApplication
        val ch = app.appContainer.currentViewPagerFragmentChannel

        if (!ch.isClosedForSend){
            for (value in ch){
                when (value) {
                    // FragmentA is displayed
                    0 -> sharedViewModel.doSomethingForFragmentA(value)
                    // FragmentB is displayed
                    1 -> sharedViewModel.doSomethingForFragmentB(value)
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...