【问题标题】:Android: Livedata Observer gets never called, recylerview list is never submitted, navgraphviewmodelAndroid:Livedata Observer 永远不会被调用,recylerview 列表永远不会提交,navgraphviewmodel
【发布时间】:2021-04-09 00:20:39
【问题描述】:

我有一个 ShopFilterFragmentProductFilter,它位于一个 ShopFilterFragmentHolder 内,该ShopFilterFragmentHolder 本身包含一个 ViewPager2。这个 ShopFilterFragmentHolder 是一个在我的 ShopFragment 中打开的 DialogFragment。所以 ShopFragment -> ShopFilterFragmentHolder (Dialog, ViewPager2) -> ShopFilterFragmentProductFilter。所有这些 Fragment 都应该共享同一个 navgraphscoped viewmodel。

我遇到的问题是,当我在 ShopFilterFragmentProductFilter 中附加一个观察者以从 cloud-firestore 获取我的 recyclerview 列表时,这个观察者永远不会被调用,因此我收到错误消息“没有适配器附加,跳过布局”。我知道这不是我如何实例化适配器并将其分配给我的 recyclerview 的问题,因为当我设置一个静态列表(例如在我的 ShopFilterFragmentProductFilter 中创建一个列表)时,一切正常。

为什么我没有得到 livedata 值?在我看来,视图模型的创建存在问题。

这是我目前的做法:

ShopFilterFragmentProductFilter

@AndroidEntryPoint
class ShopFilterFragmentProductFilter : Fragment() {
    private var _binding: FragmentShopFilterItemBinding? = null
    private val binding: FragmentShopFilterItemBinding get() = _binding!!
    private val shopViewModel: ShopViewModel by navGraphViewModels(R.id.nav_shop) { defaultViewModelProviderFactory }
    @Inject lateinit var shopFilterItemAdapter: ShopFilterItemAdapter

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentShopFilterItemBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        bindObjects()
        submitAdapterList()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.rvShopFilter.adapter = null
        _binding = null
    }

    private fun bindObjects() {
        with(binding) {
            adapter = shopFilterItemAdapter
        }
    }

    private fun submitAdapterList() {
        shopViewModel.shopProductFilterList.observe(viewLifecycleOwner) {
            shopFilterItemAdapter.submitList(it)
            shopFilterItemAdapter.notifyDataSetChanged()
           toast("SUBMITTED LIST") // this does never get called
        }

        /* // this works
        shopFilterItemAdapter.submitList(
            listOf(
                ShopFilterItem(0, "ITEM 1"),
                ShopFilterItem(0, "ITEM 2"),
                ShopFilterItem(0, "ITEM 3"),
                ShopFilterItem(0, "ITEM 4"),
                ShopFilterItem(0, "ITEM 5"),
            )
        )
         */
    }
}

视图模型

class ShopViewModel @ViewModelInject constructor(
    private val shopRepository: ShopRepository,
    private val shopFilterRepository: ShopFilterRepository
) : ViewModel() {
    private val query = MutableLiveData(QueryHolder("", ""))

    val shopPagingData = query.switchMap { query -> shopRepository.search(query).cachedIn(viewModelScope) }

    val shopProductFilterList: LiveData<List<ShopFilterItem>> = liveData { shopFilterRepository.getProductFilterList() }

    val shopListFilterList: LiveData<List<ShopFilterItem>> = liveData { shopFilterRepository.getListFilterList() }

    fun search(newQuery: QueryHolder) {
        this.query.value = newQuery
    }
}

ShopFilterRepositoryImpl

class ShopFilterRepositoryImpl @Inject constructor(private val db: FirebaseFirestore) : ShopFilterRepository {

    override suspend fun getProductFilterList(): List<ShopFilterItem> = db.collection(FIREBASE_SERVICE_INFO_BASE_PATH)
        .document(FIREBASE_SHOP_FILTER_BASE_PATH)
        .get()
        .await()
        .toObject<ShopFilterItemHolder>()!!
        .productFilter

    override suspend fun getListFilterList(): List<ShopFilterItem> = db.collection(FIREBASE_SERVICE_INFO_BASE_PATH)
        .document(FIREBASE_SHOP_FILTER_BASE_PATH)
        .get()
        .await()
        .toObject<ShopFilterItemHolder>()!!
        .listFilter
}

Nav_graph

【问题讨论】:

  • 你检查过firestore是否返回值吗?
  • @iamanbansal 是的,我做到了。 Firestore 返回正确的值。我使用lifecycleScope.launch { val list = shopViewModel.shopFilterRepository.getProductFilterList() Timber.d("LIST IS $list") } 对其进行了测试
  • 您可以尝试制作 2 个相同的 livedata 并观察一个片段中的一个,另一个片段中的另一个。

标签: android kotlin google-cloud-firestore android-livedata android-mvvm


【解决方案1】:

或许,您应该将其定义为 MutableLiveData:

private val shopProductFilterList: MutableLiveData<List<ShopFilterItem>> = MutableLiveData()

并且在 您的 viewModel 中通过存储库获取数据的方法中,您应该发布 LiveData 值:

fun getProductFilterList() = viewModelScope.launch {
    val dataFetched = repository. getProductFilterList()
    shopProductFilterList.postValue(dataFetched)
}

【讨论】:

    猜你喜欢
    • 2020-12-21
    • 2020-11-18
    • 2012-10-27
    • 2013-10-12
    • 2012-03-27
    • 2013-08-29
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多