MutableList 仍然为空(?),即使我正在填充它

MutableList remaining empty (?) even though i'm populating it

我正在尝试填充一个可变列表,以便我可以将它用于回收站视图。不幸的是,虽然(我认为)我正在填充列表,但它仍然是空的并且回收器视图不起作用(我想这是因为列表问题)。代码见下方:

        private val newList: MutableList<NewListModel> = mutableListOf()
        private val oldList = retrieveOldList()

        private fun retrieveAndPopulate() {
                
                for (i in 0 until oldList.size){
        
                    val oldItem = oldList[i]
                    
                    val itemOne = oldItem.itemOne
                    val itemTwo = oldItem.itemTwo
                    val itemThree = oldItem.itemThree
                    val itemFour = oldItem.itemFour
    
                    val newItemData =
                        NewListModel(
                            itemOne, itemTwo, itemThree, itemFour
                        )
    
                newList.add(newItemData)
                Log.d(
                    "RetrieveData",
                    "${newItemData.itemOne} has been added to the list."
                )
            }
        }

下面的 class 适用于“NewListModel”

@Keep
@IgnoreExtraProperties
data class NewListModel (
    var itemOne: String ?= null,
    var itemTwo: String ?= null,
    var itemThree: String ?= null,
    var itemFour: String ?= null,
)

下面是我如何尝试填充“oldList”

fun retrieveData(): MutableList<OldListModel> {

        val list: MutableList<OldListModel> = mutableListOf()
        val ref = FirebaseDatabase.getInstance().getReference("/storage")

        ref.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                if (snapshot.exists()) {
                    ref.get()
                        .addOnSuccessListener {

                            for (listItem in snapshot.children) {
                                val listItem = snapshot.getValue(OldListModel::class.java)

                                if (listItem != null) {
                                    list.add(listItem)
                                }
                            }
                        }
                } else {
                    Log.d(
                        "Data",
                        "Retrieving data was unsuccessful."
                    )
                }
            }

            override fun onCancelled(error: DatabaseError) {
            }
        })
        return list
}

可能值得一提的是,我从一个可变列表中获取数据并将其添加到另一个可变列表中。非常感谢任何帮助

(以下是我尝试填充回收站视图的方式)

val newList = retrieveAndPopulate()

val recyclerView = findViewById<View>(R.id.recyclerView) as RecyclerView
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
val adapterAdapter = AdapterAdapter(newList)
recyclerView.adapter = adapterAdapter

您的问题是您认为自己是 运行 顺序编码,而实际上是 运行 异步编码。查看函数中带编号的注释以跟踪执行顺序:

fun retrieveData(): MutableList<OldListModel> {

    // 1. Here you create a list
    val list: MutableList<OldListModel> = mutableListOf()
    val ref = FirebaseDatabase.getInstance().getReference("/storage")

    // 2. Here a listener is added that will let you know LATER when the data is ready
    ref.addValueEventListener(object : ValueEventListener {
        // 4. LATER the data changed will get called
        override fun onDataChange(snapshot: DataSnapshot) {
            if (snapshot.exists()) {
                ref.get()
                    .addOnSuccessListener {
                        // 5. EVEN LATER this listener is called with data
                        for (listItem in snapshot.children) {
                            val listItem = snapshot.getValue(OldListModel::class.java)

                            // 6. FINALLY - you add to a list that has long since stopped being relevant
                            if (listItem != null) {
                                list.add(listItem)
                            }
                        }
                    }
            } else {
                Log.d(
                    "Data",
                    "Retrieving data was unsuccessful."
                )
            }
        }

        override fun onCancelled(error: DatabaseError) {
        }
    })
    return list // 3. Here you return the EMPTY list that was created
}

一个解决方案——虽然可能不是最好的解决方案是在回调完成后更新您的列表:

private val theList = mutableListOf<YourDataModelType>

fun retrieveData(): { // No longer returning anything

    // Remove this, no longer returning anything
    // val list: MutableList<OldListModel> = mutableListOf()

    val ref = FirebaseDatabase.getInstance().getReference("/storage")
    ref.addValueEventListener(object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            if (snapshot.exists()) {
                ref.get()
                    .addOnSuccessListener {
                        theList.clear() // Clear out existing data

                        for (listItem in snapshot.children) {
                            val listItem = snapshot.getValue(OldListModel::class.java)

                            if (listItem != null) {
                                theList.add(listItem)
                            }
                        }
                        
                        // Since you're using Kotlin, you could use a map,
                        // but that's unrelated to this issue
                        // val list = snapshot.children.map { getValue(...) }.filterNotNull()
                        
                        // Now that we have a full list here, update:
                        updateAdapterWithNewData(theList)
                    }
            } else {
                Log.d(
                    "Data",
                    "Retrieving data was unsuccessful."
                )
            }
        }

        override fun onCancelled(error: DatabaseError) {
        }
    })
}

其中 updateAdapterWithNewData 是您按照说明编写的函数。

请阅读有关异步编程的内容,并确保您了解在 Firebase 等框架中使用回调/侦听器时代码是如何流动的。

我遇到的问题是在尝试访问 onSuccessListener 中的数据时不使用 callbacks。这导致列表根本没有更新。

在网上翻了一天,终于找到了这些解决方案:

  1. 解法:

  2. 解决方案的扩展:link

这解决了我的问题,我希望它也能解决你的问题!