Firebase数据库在检索数据后通知适配器?

时间:2018-10-31 15:38:18

标签: android android-studio firebase-realtime-database kotlin recycler-adapter

从数据库中完全检索到数据后,我是否正在尝试访问数据?最初,我将适配器应用于片段。在Adapter中,我尝试从Firebase数据库检索数据。所以在这里给问题发送空数组列表。检索完整数据时,它应该发回arraylist吗?

适配器代码:

class FirebaseAdapter(context: Context): RecyclerView.Adapter<FirebaseAdapter.Holder>() {

var dataList: ArrayList<DatabaseOperations.ImageInfo> = arrayListOf()
var context: Context? = null

init {
    if (context == null)
        this.context = context

    dataList= DatabaseOperations().retriveInfo(context!!)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
    var itemView: View = LayoutInflater.from(parent.context).inflate(R.layout.imagelist_row,parent)
    var viewHolder: FirebaseAdapter.Holder = FirebaseAdapter.Holder(itemView)


    return viewHolder
}

override fun getItemCount(): Int {
    Log.e("itemCoutn",dataList.size.toString()) // it give output 0
    return dataList.size
}

override fun onBindViewHolder(holder: Holder, position: Int) {

   try {
       //----------------get bitmap from image url-----------------
       var downloadUri: String = dataList.get(position).downloadUri
       Log.e("fire adapter",downloadUri.toString())

       //------------------Assign Data to item here-----------------
       holder.image_name.text = dataList.get(position).imageName

       Glide.with(this!!.context!!)
               .load(downloadUri)
               .into(holder.row_image)

   }
   catch(e: Exception){
       Log.e("Firebase Adapter","Error "+e.toString())
   }
}


class Holder(itemView: View?) : RecyclerView.ViewHolder(itemView) {

    val row_image: ImageView
    val image_name: TextView
    init {

        row_image  = itemView!!.findViewById<ImageView>(R.id.row_image)
        image_name = itemView!!.findViewById<TextView>(R.id.image_name)


    }

}
}

信息检索代码:

fun retriveInfo( context: Context): ArrayList<ImageInfo>{

    var data = ArrayList<ImageInfo>()

    if (mDatabaseRefrence == null)
        mDatabaseRefrence = FirebaseDatabase.getInstance().getReference(getUid())

    val menuListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {

            var dataSnap: DataSnapshot? = null


            var it: Iterable<DataSnapshot> = dataSnapshot.children
            it.forEach { dataSnapshot ->
                data.add(ImageInfo(
                        dataSnapshot!!.child("imageName").toString(),
                        dataSnapshot!!.child("imageInfo").toString(),
                        dataSnapshot!!.child("downloadUri").toString()
                ))
            }

            FirebaseAdapter(context).notifyDataSetChanged()
            Log.e("db size 0",data.size.toString())

        }

        override fun onCancelled(databaseError: DatabaseError) {
            println("loadPost:onCancelled ${databaseError.toException()}")
        }
    }

    mDatabaseRefrence!!.addValueEventListener(menuListener)



    Log.e("db size",data.size.toString())

    return data
}

1 个答案:

答案 0 :(得分:0)

您现在无法返回尚未加载的内容。换句话说,由于函数的异步行为,您不能简单地返回data列表作为函数的结果,因为该列表将始终为empty。这意味着,当您尝试返回该结果时,数据尚未从数据库中完成加载,因此无法访问。

基本上,您正在尝试从异步的API同步返回值。那不是一个好主意。您应该按预期异步处理API。

对此问题的快速解决方案是仅在回调内部(在data方法内部)使用onDataChange()列表。如果您想在外部使用它,建议您从此 post 中查看anwser的最后一部分,其中我已经解释了如何使用自定义回调来完成。您也可以查看此 video 以获得更好的理解。