【发布时间】:2023-02-21 19:17:46
【问题描述】:
我只需要获取一次数据并避免在屏幕旋转时获取数据。
我的片段:
private var _binding: FragmentTopArticlesBinding? = null
private val binding get() = _binding!!
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentTopArticlesBinding.inflate(inflater, container, false)
getTopArticles()
return binding.root
}
观察状态的功能:
private fun getTopArticles() {
var sortedList = emptyList<Article>()
val adapter = ArticleAdapter(
onArticleClicked = { title ->
Toast.makeText(context, title, Toast.LENGTH_SHORT).show()
}
)
binding.recyclerViewTop.layoutManager = LinearLayoutManager(context)
binding.recyclerViewTop.adapter = adapter
lifecycleScope.launch {
viewModel.stateUI.collect { it ->
when (it) {
is StateUI.Success -> {
it.articles.collect { articles ->
if (articles.isNotEmpty()) {
observeArticles(sharedViewModel, articles, adapter)
获取数据的函数:
private suspend fun observeArticles(
sharedViewModel: SharedViewModel,
articles: List<Article>,
adapter: ArticleAdapter
) {
binding.progressBar.visibility = View.GONE
sharedViewModel.sortState.collect { sortState ->
val sortedList = when (sortState) {
SortOrderState.Ascending -> {
sharedViewModel.sortArticles(articles)
}
SortOrderState.Descening -> {
sharedViewModel.sortArticles(articles)
}
}
adapter.submitList(sortedList)
binding.recyclerViewTop.postDelayed({
binding.recyclerViewTop.scrollToPosition(0)
}, 1000)
}
}
我的任务是在用户单击菜单项排序(asc 或 desc)时获取和排序 2 个片段的数据。问题是当我旋转屏幕时,这些函数获取数据但我只想在我第一次进入 Fragment 时执行一次。
我删除了这行代码:
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
因为我将无法使用 scrollToPosition。
编辑:
视图模型:
private val _cacheArticle = MutableStateFlow(emptyList<Article>())
val cacheArticle = _cacheArticle.asStateFlow()
init {
viewModelScope.launch {
if(cacheArticle.value.isEmpty()){
val observeTopArticles = articleRepository.getTopArticles()
_cacheArticle.value = observeTopArticles
_stateUI.value = StateUI.Success(articles = observeTopArticles)
Log.d(TAG, ": PULL")
} else
{
Log.d(TAG, ": CACHE1")
_stateUI.value = StateUI.Success(articles = _cacheArticle.value)
}
}
【问题讨论】:
-
视图模型的发布代码/您如何获取数据。如果您只想获取一次数据,则不应使用流。 Small hack 可能会在收到第一个数据后调用取消。
-
我删除了所有流但仍然从 api 获取数据,尝试使用一些本地 stateFlow 但它仍然不会存储数据并在我从 api 获取数据时使用它一次
-
我刚刚重新阅读了您的问题。您不希望轮换获取数据。您正在使用 ViewModel。它不会。 ViewModel 在配置更改后仍然存在。
-
那么可以在没有 cacheArticle 的情况下使用 viewModel 吗? observeTopArticles 从 api 获取数据,所以我认为当我旋转屏幕时它仍然获取数据。
-
这不完全是我的意思。你在那里的代码,它不会在旋转时重新获取它。 ViewModels
init只会被调用一次——也就是说,如果您正确地创建了viewModel。
标签: android kotlin mvvm fragment viewmodel