gpt4 book ai didi

android - 实时数据中的 Observables 更新在 fragment 中不起作用

转载 作者:行者123 更新时间:2023-12-05 00:03:15 25 4
gpt4 key购买 nike

我有一个实例化 koin 注入(inject)的 View 模型实例的 fragment ,问题是,观察到的属性之一在 View 模型的 postValue () 操作之后没有在 fragment 中被激发,它根本没有进入方法在 fragment 中,即使它已经更新。

fragment :

class ListFragment : Fragment() {

private lateinit var adapter: PostAdapter
private val viewModel: PostsViewModel by viewModel()
private var _binding: ListFragmentBinding? = null
private var defaultTopic = "news"
private var afterPage: String = ""

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.list_fragment, container, false)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = ListFragmentBinding.bind(view)

adapter = PostAdapter(mutableListOf(), requireContext()) {
val action = ListFragmentDirections.openDetailsFragment(it)
findNavController().navigate(action)
}

_binding?.let{
val llm = LinearLayoutManager(requireContext())
it.recyclerviewPosts.layoutManager = llm
it.recyclerviewPosts.adapter = adapter

recyclerViewListenerSetup(it, llm)
}
setupObservers()

}

private fun recyclerViewListenerSetup(it: ListFragmentBinding, llm: LinearLayoutManager) {
it.recyclerviewPosts.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val visibleItemCount: Int = llm.childCount
val totalItemCount: Int = llm.itemCount
val firstVisibleItemPosition: Int = llm.findFirstVisibleItemPosition()

if((visibleItemCount + firstVisibleItemPosition) >= totalItemCount
&& firstVisibleItemPosition >= 0) {
viewModel.getNextPage(defaultTopic, afterPage)
}
}
})
}

private fun setupObservers(){
viewModel.getPostList(defaultTopic)
viewModel.posts.observe(this as LifecycleOwner, { posts ->
if (posts.isSuccess && posts.getOrNull() != null) {
adapter.updateList(posts.getOrNull()!! as MutableList<PostsDTO>)
afterPage = posts.getOrNull()!![0].after
showList()
} else {
showError()
}
})
viewModel.loading.observe(this as LifecycleOwner, {
if (it) {
showLoading()
} else {
hideLoading()
}
})
viewModel.next.observe(this as LifecycleOwner, {
if (it.isSuccess && it.getOrNull() != null) {
adapter.addList(it.getOrNull() as MutableList<PostsDTO>)
afterPage = it.getOrNull()!![0].after
}
})
}

private fun showList(){
_binding?.let {
it.recyclerviewPosts.visibility = VISIBLE
}
}

private fun showLoading(){
_binding?.let {
it.loading.visibility = VISIBLE
it.containerError.root.visibility = GONE
it.recyclerviewPosts.visibility = GONE
}
}

private fun hideLoading(){
_binding?.let {
it.loading.visibility = GONE
}
}

private fun showError() {
_binding?.let {
it.containerError.root.visibility = VISIBLE
it.recyclerviewPosts.visibility = GONE
}
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_main, menu)
val searchItem = menu.findItem(R.id.action_search)
val searchManager =
requireActivity().getSystemService(Context.SEARCH_SERVICE) as SearchManager
val searchView = searchItem.actionView as SearchView
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity?.componentName))

searchView.apply {
queryHint = "Search SubReddit"
setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
defaultTopic = query!!
viewModel.getPostList(defaultTopic)
return false
}

override fun onQueryTextChange(newText: String?): Boolean {
return true
}
})
}
super.onCreateOptionsMenu(menu, inflater)
}

}

我尝试在recyclerView滚动时调用viewmodel方法来更新显示的列表。

View 模型:

class PostsViewModel(private val repository: PostsRepository) : ViewModel(){

private val _posts = MutableLiveData<Result<List<PostsDTO>>>()
val posts: LiveData<Result<List<PostsDTO>>>
get() =_posts

private val _loading = MutableLiveData<Boolean>()
val loading: LiveData<Boolean>
get() = _loading

private val _next = MutableLiveData<Result<List<PostsDTO>>>()
val next: LiveData<Result<List<PostsDTO>>>
get() =_posts

fun getPostList(q: String){
viewModelScope.launch {
_loading.postValue(true)
repository.fetchPosts(q)
.collect {
_posts.value = it
}
_loading.postValue(false)
}
}

fun getNextPage(topic: String, afterPage: String) {
viewModelScope.launch {
repository.fetchNextPage(topic, afterPage)
.collect{
_next.postValue(it)
}
}
}

}

这种情况下next方法的请求结果已经更新viewmodel后,fragment在viewmodel.next.observer()中不被激发

最佳答案

哎呀!经过单元测试后,我能够找出问题所在,问题出在 ctrl + v,下一个属性,它返回的是 _post 属性而不是 _next 属性,因此未通知 View 更新。修正修正在viewmoldel中,改变下一个变量的get方法:

private val _next = MutableLiveData<Result<List<PostsDTO>>>()
val next: LiveData<Result<List<PostsDTO>>>
get() =_next

关于android - 实时数据中的 Observables 更新在 fragment 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66851035/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com