观察者被触发两次,即使观察到的变量被改变一次

问题描述 投票:0回答:1

我的ViewModel类应异步加载User数据和图像,完成后应将变量userLoaded设置为true并触发宿主片段内的观察者以使选项菜单膨胀。 ViewModel内部的初始化是通过

完成的
init {
        viewModelScope.launch {
            userLoaded.value = false
            try {
                loadUser(id)
                loadImg(id)
            } catch (e: Exception){
                Log.e(TAG, "${e.message}")
            } finally {
                userLoaded.value = true
            }
        }
    }

loadUser()loadImg()是两个suspend fun,它们从Firebase加载一些数据。主要问题在于,即使userLoaded.value仅更改一次,菜单也会被放大两次。以下是片段内的观察者]

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        // menu.clear()
        viewModel.userLoaded.observe(this, Observer {
            if (it == true) {
                inflater.inflate(R.menu.show_profile_menu, menu)
            }
        })
    }

Update1:这个解决方案怎么样?

override fun onPrepareOptionsMenu(menu: Menu) {
        viewModel.userLoaded.observe(this, Observer {
            menu.findItem(R.id.edit_icon).isVisible = it
            menu.findItem(R.id.edit_icon).isEnabled = it
        })
        super.onPrepareOptionsMenu(menu)
    }
android android-fragments mvvm viewmodel observer-pattern
1个回答
0
投票

您不应该在onCreateOptionsMenu中订阅观察者,因为可能多次调用此方法。您应该订阅onViewCreated

fun onViewCreated(view: View, savedInstanceState: Bundle?) {
   /* other stuff */
   viewModel.userLoaded.observe(this, Observer {
        if (it == true) {
            // toggle a global flag and recreate the menu
            hasLoaded = true
            activity?.invalidateOptionsMenu()
        }
    })
}

然后

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    // menu.clear()
    if (hasLoaded) {
        inflater.inflate(R.menu.show_profile_menu, menu)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.