0

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

        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."
                )
            }
        }

下面的类用于“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
4

2 回答 2

2

您的问题是您认为在异步运行时您正在按顺序运行代码。查看函数中的编号注释以跟踪执行顺序:

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 等框架中使用回调/侦听器时代码是如何流动的。

于 2021-11-25T08:18:39.333 回答
0

我遇到的问题是callbacks在尝试访问onSuccessListener. 这导致列表根本不更新。

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

  1. 解决方法:链接

  2. 解决方案的扩展:链接

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

于 2021-11-26T01:05:05.997 回答