kotlin Fragemnt出现后从ViewModel获取初始数据

2w2cym1i  于 2022-12-04  发布在  Kotlin
关注(0)|答案(1)|浏览(192)

我是新的Android和它的ViewModel模式。我想实现的是每次用户进入片段,然后数据被从服务器获取。
所以我现在得到的基本上是:
检视模型

class HomeViewModel : ViewModel() {
    val data = MutableLiveData<DataModel>()

    init {
        initialize()
    }

    private suspend fun initialize() {
        //HTTP REQUEST...
        data.value = apiresult
    }
}

片段

class HomeFragment : Fragment() {
private lateinit var viewModel: HomeViewModel

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    viewModel = ViewModelProvider(this)[HomeViewModel::class.java]

    viewModel.data.observe(viewLifecycleOwner) {
        //Do some stuff on UI
    }

}

我正在阅读Android ViewModel生命周期文档,目前它符合预期。init函数块被调用一次。这导致每当用户再次进入片段时,将不会调用initialize()函数。ViewModel中的初始数据值将通知HomeFragment,无论何时启动。
我试图尽可能简单地做到这一点,所以在HomeFragment的onCreateView()方法中调用:
初始化视图模型
上述解决方案有效,但观察器回调被调用两次:第一次使用以前的值,第二次使用新的API数据。
是否有一个选项可以只注册一次LiveData,或者我应该在任何Android可覆盖的方法(如onDestroy())中从LiveData取消订阅?

xfb7svmp

xfb7svmp1#

如果您希望在用户每次输入HomeFragment时重新加载数据,则只需在Fragment的onResume生命周期回调方法中手动重新加载HomeViewModel

class HomeFragment : Fragment() {

    private lateinit var viewModel: HomeViewModel

    ...
    
    override fun onResume() {
        viewModel.reload()
    }
}

ViewModel现在看起来如下所示:

class HomeViewModel : ViewModel() {

    val data = MutableLiveData<DataModel>()

    suspend fun reload() {
        //HTTP REQUEST...
        data.value = apiresult
    }
}

请注意,您不再需要刷新HomeViewModelinit块中的ViewModel。
还有,这里有个好建议:Android文档是这样描述onCreateView的:
建议在此方法中只扩大布局,并将对返回的视图进行操作的逻辑移动到onViewCreated
因此,将ViewModel初始化逻辑移至onViewCreated

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    viewModel = ViewModelProvider(this)[HomeViewModel::class.java]

    viewModel.data.observe(viewLifecycleOwner) {
        //Do some stuff on UI
    }
}

相关问题