I wanted to get a list of data from the realtime database using coroutines and MVVM and put them to recyclerview. It runs but the data from the realtime database are added after the recyclerview.adapter initialization, thus returning list.size to 0
ViewModel.kt
class DasarhukumdetailsViewModel : ViewModel() {
val database = FirebaseDatabase.getInstance().reference
var dasarHukumList = ArrayList<DasarHukum>()
fun getDHData(KEYVALUE: String?) = liveData(Dispatchers.Main.immediate) {
val postListener = object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
for (snapshot in snapshot.children) {
val res = snapshot.getValue(DasarHukum::class.java)
Log.d("dataAdd", "Adding: ${res?.filename}")
dasarHukumList.add(res!!)
}
}
override fun onCancelled(databaseError: DatabaseError) {
// Getting Post failed, log a message
Log.w("readDHList", "loadPost:onCancelled", databaseError.toException())
throw databaseError.toException()
}
}
try {
if (KEYVALUE != null) {
database.child("dasarhukum").child(KEYVALUE).addValueEventListener(postListener)
}
emit(Resource.success(dasarHukumList))
} catch (e: Exception) {
emit(Resource.error(
null,
e.message ?: "Unknown Error"
))
}
}
Fragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
[...]
observerSetup(KEYVALUE)
rvSetup()
return binding.root
}
fun observerSetup(keyvalue: String?) {
viewModel.getDHData(keyvalue).observe(viewLifecycleOwner, {
when (it.status) {
Status.SUCCESS -> {
it?.data.let { dhList ->
dasarHukumAdapter.dasarhukumList = dhList
dasarHukumAdapter.notifyDataSetChanged()
}
}
Status.ERROR -> {
Toast.makeText(context, "Error getting documents: ${it.message}", Toast.LENGTH_LONG)
Log.e("realDB", it.message!!)
}
}
})
}
fun rvSetup() {
with(binding.rvDasarHukum) {
layoutManager = LinearLayoutManager(context)
setHasFixedSize(true)
adapter = dasarHukumAdapter
}
}
RVAdapter.kt
class DasarHukumAdapter : RecyclerView.Adapter<DasarHukumAdapter.DasarHukumViewHolder>() {
var dasarhukumList: List<DasarHukum>? = null
set(value) {
notifyDataSetChanged()
field = value
}
class DasarHukumViewHolder(private val binding: ItemDasarhukumBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(dasarHukum: DasarHukum?) {
binding.dasarhukum = dasarHukum
binding.executePendingBindings()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DasarHukumViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ItemDasarhukumBinding.inflate(layoutInflater, parent, false)
return DasarHukumViewHolder(binding)
}
override fun onBindViewHolder(holder: DasarHukumViewHolder, position: Int) {
val dasarHukum = dasarhukumList?.get(position)
Log.d("dhVH", "Adding: ${dasarHukum?.name}")
holder.bind(dasarHukum)
}
override fun getItemCount(): Int {
Log.d("dhCount", "List size: ${dasarhukumList?.size}")
return dasarhukumList?.size ?: 0
}
How can the recyclerview waits for the viewmodel.getDHData() to returns the arraylist first then initialize so it can be displayed to the recyclerview?