Home > Enterprise >  ListAdapter is not being notified whenever data is updated and emitted by StateFlow
ListAdapter is not being notified whenever data is updated and emitted by StateFlow

Time:03-09

StateFlow is emitting new data after change, but ListAdapter is not being updated/notified, but when configuration is changed(i.e device is rotated from Portrait to Landscape mode) update is occurred:

class TutorialListFragment : Fragment() {
    
        private lateinit var binding: FragmentTutorialListBinding
    
        private val viewModel: ITutorialViewModel by viewModels<TutorialViewModelImpl>()
        private lateinit var adapter: TutorialAdapter
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
    
            binding = FragmentTutorialListBinding.inflate(inflater, container, false)
            return binding.root
    
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            val recyclerView = binding.recyclerView
    
            adapter = TutorialAdapter()
            recyclerView.adapter = adapter    
     
            loadData()   
    
        }
    
        private fun loadData() {
            viewModel
                .getTutorialList()
    
            val tutorialList: MutableList<TutorialResponse> = mutableListOf()

            viewModel
                .tutorialListStateFlow
                .onEach { list ->
                    list.forEach {tutorialResponse->
                        tutorialList.add(tutorialResponse)                       
                        Log.e("TUTORIAL_LIST_FRAG", "$tutorialResponse")
                    }
                    adapter.submitList(tutorialList)
                }.launchIn(viewLifecycleOwner.lifecycleScope)
        }
}

View model is:

class TutorialViewModelImpl: ViewModel(), ITutorialViewModel {

    private val mTutorialRepository: ITutorialRepository = TutorialRepositoryImpl()

    private val _tutorialListStateFlow = MutableStateFlow<List<TutorialResponse>>(mutableListOf())
    override val tutorialListStateFlow: StateFlow<List<TutorialResponse>>
        get() = _tutorialListStateFlow.asStateFlow()

    init {
        mTutorialRepository
            .getTutorialListSuccessListener {
                viewModelScope
                    .launch {
                        _tutorialListStateFlow.emit(it)
                        Log.e("TUTORIAL_GL_VM", "$it")
                    }
            }    
       
    }

    override fun getTutorialList() {
        // Get list
        mTutorialRepository.getTutorialList()
    }
}

When I look into Logcat I see this line:

Log.e("TUTORIAL_GL_VM", "$it")

prints all the changes, but no update in ListAdapter.

CodePudding user response:

I assume your data from mTutorialRepository is not a flow ,so you must add .toList() if you want to emit list in stateFlow to get notified


mTutorialRepository.getTutorialListSuccessListener {
   viewModelScope.launch {
      // here add .toList()
      _tutorialListStateFlow.emit(it.toList())             
   }
} 

or if it still does not works, try to change your loadData() like this


private fun loadData() {
// idk what are doing with this ??
viewModel.getTutorialList()

lifecycleScope.launch {
     viewModel.tutorialListStateFlow.collect { list ->
       adapter.submitList(list)
    }
  }
}
  • Related