Reputation: 653
I want to know the best practice/way to fill any Spinner with data from room db.
I also want to use ViewModel and LiveData (then I'll move to StateFlow!), but I'm confused with the correct order defining variables.
first I have this in the view model:
val aniosLiveData = anioRepository.anios.asLiveData() // return LiveData<List<Anio>>
then on the fragment, first the viewmodel declaration:
private val ensayosViewModel: EnsayosViewModel by viewModels()
then, in onViewCreated() I have a block with the binding elements:
binding.apply {
recyclerViewEnsayos.apply {
adapter = ensayosAdapter
layoutManager = LinearLayoutManager( requireContext())
setHasFixedSize(true)
}
spinnerAnio.apply {
adapter = aniosAdapter // <- Spinner adapter
}
}
I override onCreate() to define an observer, and then I put this lines:
ensayosViewModel.aniosLiveData.observe(viewLifecycleOwner, {spinnerData ->
aniosAdapter = ArrayAdapter<Anio>(requireContext(), R.layout.spinner_text_item, spinnerData)
})
Where/When do I need to declare "aniosAdapter" ? like this: ?
//At class level
private lateinit var aniosAdapter : ArrayAdapter<Anio>
Is this the correct way ? There is another ?? more simpler ?
Thanks in advance! Best Regards
Upvotes: 0
Views: 443
Reputation: 418
If you need reference to the aniosAdapter
outside of the lifecycle hook, I would recommend using a private lateinit var
as you alluded. While you are initializing the spinnerAnio
's adapter correctly at first, it's not going retroactively recognize any mutations you make to aniosAdapter
after the execution of the lifecycle hook. Instead, you're going to need to adjust your aniosLiveData
observer to appear as such:
ensayosViewModel.aniosLiveData.observe(viewLifecycleOwner, {
binding.spinnerAnio.adapter = ArrayAdapter<Anio>(
requireContext(),
R.layout.spinner_text_item,
it
)
})
In the scenario where you do need to reference the aniosAdapter
outside of the lifecycle hook's scope, your observer would likely look as such in conjunction with the private lateinit var
you referenced:
ensayosViewModel.aniosLiveData.observe(viewLifecycleOwner, {
aniosAdapter = ArrayAdapter(
requireContext(),
R.layout.spinner_text_item,
it
)
binding.spinnerAnio.adapter = aniosAdapter
})
If you can guarantee that your observer will trigger immidately, aniosAdapter
would be safe to declare as a private lateinit var
. If you are unsure, it would be much safer to consider it as an optional field as depicted below. Nice work!
private var aniosAdapter: ArrayAdapter<Anio>? = null
Upvotes: 1