【问题标题】:Firebase Database notify adapter after retriving data?Firebase数据库在检索数据后通知适配器?
【发布时间】:2019-04-04 20:15:09
【问题描述】:

从数据库中完全检索到数据后,我是否正在尝试访问数据?最初我将适配器应用于片段。在适配器中,我尝试从 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
}

【问题讨论】:

  • 代码的哪一部分,哪一行是你的ArrayList null
  • 在检索信息码中有一个叫data的arraylist。在 onDataChange 方法中,我正在填充数据数组列表,但在 firebase 适配器中接收到的数组列表 init 部分为空

标签: android android-studio firebase-realtime-database kotlin android-recyclerview


【解决方案1】:

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

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

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

【讨论】:

  • 嗨阿布舍克!你有没有试过我上面的解决方案,它有效吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 2019-01-08
相关资源
最近更新 更多