我正在使用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
初始化后才启动代码
答案 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..
})