Android-等待变量在ViewModel中初始化以在Fragment中进行

时间:2019-07-15 11:39:40

标签: android kotlin

我正在使用Kotlin协程从Room数据库中获取数据,并且我需要等待在ViewModel中初始化变量才能在Fragment中使用它们,主要是为了初始化GoogleMap等其他内容目的(例如检查导航条件等)。 另外,我实际上需要等待Navigation中的Args,因此第一个调用是从Fragment到ViewModel,然后才触发协同程序

我已经看到了多种实现方法,但是我对Android来说还很陌生,而且与我已经使用的方式不匹配,而且大多数情况下它太复杂了,我听不懂。 / p>

实际上我在Fragment中使用它:

Handler().postDelayed(
{My code...}, 50)

但是我知道这根本不是一个干净的方法,有时变量甚至在50ms之后都没有初始化。我还尝试了一个简单的

While (var == null){}
My code...

但是它也很野蛮,只会冻结应用程序。

这是我的片段的一个例子

var currentSession: Session? = null

val args = SessionDetailsFragmentArgs.fromBundle(arguments!!)
viewModel.initializeSession(args.sessionID)

viewModel.session.observe(this, Observer{
    currentSession = it
})
//I need to wait for currentSession to continue
..Doing stuff with currentSession..

这是我的ViewModel:

private var _session = MutableLiveData<Session?>()
val session: LiveData<Session?>
    get() = _session

fun initializeSession(key: Long) {
    uiScope.launch {
        _session.value = withContext(Dispatchers.IO) {
            val session = dataSessionSource.getSession(key)
            session
        }
    }

}

我将其缩短了一点,但更多地了解我的工作方式。一切都可以根据需要进行编译和工作

我需要的就像一个函数MyVariable.OnInitialized() { ... },仅在MyVariable初始化后才启动代码

2 个答案:

答案 0 :(得分:0)

我不知道这是否是您所需要的,但是也许可以使用加载程序在ui中显示,直到满足您的需求为止。

在您的视图模型中,您可以这样做:

private val _loading = MutableLiveData<Boolean>().apply(value = false)
val loading: LiveData<Boolean>
  get() = _loading

然后在启动会话时将loading的值更改为true,在会话结束时将其的值更改为false。您只需要观察片段中的负载并将其显示给用户即可。

答案 1 :(得分:0)

实际上很简单:

  

,我需要等待在ViewModel中初始化变量才能在Fragment中使用它们,主要是为了初始化其他事物(例如GoogleMap),也可以出于其他目的(例如,检查导航条件等)。另外,我实际上需要等待导航中的Args

您无需等待变量。

您公开了LiveData<T>而不是变量,以便您观察更改。

这种更改包括初始化,因为该值是异步检索的。

因此,仅当LiveData包含所需数据时,才需要继续执行逻辑。

viewModel.session.observe(viewLifecycleOwner, Observer {
    currentSession = it
    ..Doing stuff with currentSession..
})